package com.bonus.material.materialStation.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bonus.common.biz.domain.lease.LeaseApplyInfo;
import com.bonus.common.biz.domain.lease.LeasePublishInfo;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.common.mapper.SelectMapper;
import com.bonus.material.materialStation.domain.ProAuthorizeDetails;
import com.bonus.material.materialStation.domain.ProAuthorizeInfo;
import com.bonus.material.materialStation.mapper.ProAuthorizeMapper;
import com.bonus.material.materialStation.service.ProAuthorizeService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.hibernate.validator.internal.util.StringHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @author hay
 * @description 项目部授权
 * @date 2025/6/18 21:54
 */
@Service(value = "proAuthorizeService")
@Slf4j
public class ProAuthorizeServiceImpl implements ProAuthorizeService {
    /** 应用1 */
    public static final String API_KEY = "YVXaH3odMID2QRJZFkJaL8yx";
    /** 应用1 */
    public static final String SECRET_KEY = "YWnUheHHXsqwbR1Pt0ZfaZxrh40uUW99";

    /** 应用2 */
    public static final String API_KEY_2 = "Ugm22rvfLDADxr9sT6H2muSG";
    /** 应用2 */
    public static final String SECRET_KEY_2 = "w1jfLoSLFpxdIJpQriJXWpoNF1YOWTdJ";

    static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

    @Resource
    private ProAuthorizeMapper mapper;

    @Resource(name = "SelectMapper")
    private SelectMapper selectMapper;


    @Override
    public List<LeasePublishInfo> getPublishList(LeaseApplyInfo leaseApplyInfo) {
        try {
            String username = SecurityUtils.getLoginUser().getUsername();
            // 根据用户名查询项目部信息
            List<String> departId = selectMapper.getDepartId(username);
            // 根据项目部id查询工程信息
            if (!CollectionUtils.isEmpty(departId)) {
                List<String> projectIdList = selectMapper.getAllProjectList(departId);
                if (!CollectionUtils.isEmpty(projectIdList)) {
                    leaseApplyInfo.setProjectIdList(projectIdList);
                }
            }
            List<LeasePublishInfo> list = mapper.getPublishList(leaseApplyInfo);
            if (!CollectionUtils.isEmpty(list)) {
                String keyWord = leaseApplyInfo.getKeyWord();
                // 如果关键字不为空，进行过滤
                if (!StringUtils.isBlank(keyWord)) {
                    list = list.stream()
                            .filter(item -> containsKeyWord(item, keyWord))
                            .collect(Collectors.toList());
                }
            }
            return list;
        } catch (Exception e){
            log.error("项目部授权列表查询", e.getMessage());
            return new ArrayList<>();
        }
    }

    @Override
    public AjaxResult uploadPhoto(String filePath, Long type) {
        try {
            String base64 = encodeImageFromUrlToBase64(filePath);
            String types="";
            if (type == 1){
                types="front";
            } else if (type == 2){
                types="back";
            }
            if (!StringHelper.isNullOrEmptyString(base64)) {
                String image = URLEncoder.encode(base64, "utf-8");
                MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
                RequestBody body = RequestBody.create(mediaType, "image=" + image + "&id_card_side="+types);
                Request request = new Request.Builder()
                        .url("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + getAccessToken())
                        .method("POST", body)
                        .addHeader("Content-Type", "application/x-www-form-urlencoded")
                        .addHeader("Accept", "application/json")
                        .build();
                Response response = HTTP_CLIENT.newCall(request).execute();
                String jsonString = response.body().string();
                System.err.println(jsonString);
                JSONObject jsonObject = JSONObject.parseObject(jsonString);
                JSONObject resultObject = jsonObject.getJSONObject("words_result");
                ProAuthorizeDetails bean = new ProAuthorizeDetails();
                if (type==1){
                    String name = resultObject.getJSONObject("姓名").getString("words");
                    String idNumber = resultObject.getJSONObject("公民身份号码").getString("words");
                    String sex = resultObject.getJSONObject("性别").getString("words");
                    String birth = resultObject.getJSONObject("出生").getString("words");
                    String address = resultObject.getJSONObject("住址").getString("words");
                    String nation = resultObject.getJSONObject("民族").getString("words");
                    bean.setName(name);
                    bean.setIdNumber(idNumber);
                    bean.setFrontUrl(filePath);
                } else if (type==2){
                    String time = resultObject.getJSONObject("失效日期").getString("words");
                    bean.setBackUrl(filePath);
                }
                return AjaxResult.success(bean);
            } else {
                return AjaxResult.error("图片识别失败，请重试");
            }
        } catch (Exception e) {
            log.error("图片识别失败", e.getMessage());
            return AjaxResult.error("图片识别失败，请重试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult authorizeSubmit(ProAuthorizeInfo bean) {
        try {
            String userId = SecurityUtils.getLoginUser().getUserid().toString();
            bean.setCreateBy(userId);
            if (bean != null) {
                if (bean.getAuthId() != null) {
                    //修改
                    //删除详情数据
                    int res = mapper.deleteProAuthorizeDetails(bean.getAuthId());
                    if (res <= 0) {
                        throw new RuntimeException("授权信息删除失败");
                    }
                    insertProAuthorizeDetails(bean.getDetailsList(),bean.getAuthId());
                } else {
                    for (Long lesaeId : bean.getLeaseIds()){
                        bean.setLeaseId(lesaeId);
                        //新增
                        int res = mapper.insertProAuthorizeInfo(bean);
                        if (res > 0 && bean.getId() != null) {
                            bean.setAuthId(bean.getId());
                        } else {
                            throw new RuntimeException("授权信息插入失败");
                        }
                        insertProAuthorizeDetails(bean.getDetailsList(),bean.getAuthId());
                    }
                }
                return AjaxResult.success();
            } else {
                throw new RuntimeException("授权信息插入失败");
            }
        } catch (Exception e) {
            log.error("授权提交失败", e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("授权提交失败");
        }
    }

    private void insertProAuthorizeDetails(List<ProAuthorizeDetails> detailsList,Long authId){
        String userId = SecurityUtils.getLoginUser().getUserid().toString();
        if (detailsList.size() > 0) {
            for (ProAuthorizeDetails details : detailsList) {
                details.setParentId(authId);
                details.setCreateBy(userId);
                int re = mapper.insertProAuthorizeDetails(details);
                if (re <= 0) {
                    throw new RuntimeException("授权信息插入失败");
                }
            }
        } else {
            throw new RuntimeException("没有领料人信息");
        }
    }

    @Override
    public AjaxResult authorizeView(ProAuthorizeInfo bean) {
        try {
            if (bean.getLeaseId()!= null){
                //查询授权信息
                ProAuthorizeInfo info = mapper.selectProAuthorizeInfo(bean);
                if (info != null){
                    List<ProAuthorizeDetails> detailsList = mapper.getDetailsList(info.getId());
                    info.setDetailsList(detailsList);
                }
                return AjaxResult.success(info);
            } else {
                log.error("授权查看没有id");
                return AjaxResult.error("授权信息查看失败");
            }
        } catch (Exception e) {
            log.error("授权信息查看失败", e.getMessage());
            return AjaxResult.error("授权信息查看失败");
        }
    }

    @Override
    public AjaxResult authorizeInfoView(ProAuthorizeInfo bean) {
        try {
            if (bean.getLeaseId()!= null){
                //查询授权信息
                ProAuthorizeInfo info = mapper.selectProAuthorizeInfoView(bean);
                if (info != null){
                    List<ProAuthorizeDetails> detailsList = mapper.getDetailsList(info.getId());
                    // 电子签名进行base64拼接
                    if(!detailsList.isEmpty()){
                        detailsList.forEach(details -> {
                            if (StringUtils.isNotBlank(details.getSignName())) {
                                if (!details.getSignName().startsWith("http")) {
                                    details.setSignName("data:image/png;base64," + details.getSignName());
                                }
                            }
                        });
                    }
                    info.setDetailsList(detailsList);
                }
                return AjaxResult.success(info);
            } else {
                log.error("授权查看没有id");
                return AjaxResult.error("授权信息查看失败");
            }
        } catch (Exception e) {
            log.error("授权信息查看失败", e.getMessage());
            return AjaxResult.error("授权信息查看失败");
        }
    }

    /**
     * 授权书电子签名
     *
     * @param bean
     */
    @Override
    public int updateAuthorizeInfoSign(ProAuthorizeDetails bean) {
        // 领用电子签名修改
        int count = 0;
        //修改pro_authorize_user表
        count =  mapper.updateAuthorizeInfoSign(bean);
        if(count==0){
            throw new RuntimeException("授权书电子签名失败");
        }else{
        //修改pro_authorize_info表
           return mapper.updateAuthorizeInfoSignStatus(bean);
        }


    }

    @Override
    public List<ProAuthorizeInfo> getAuthorList(ProAuthorizeInfo bean) {
        try {
            List<ProAuthorizeInfo> list = mapper.getAuthorList(bean);
            return list;
        } catch (Exception e){
            log.error("项目部授权列表查询", e.getMessage());
            return new ArrayList<>();
        }
    }

    /**
     * 判断关键字是否包含在item中
     * @param item
     * @param keyWord
     * @return
     */
    private boolean containsKeyWord(LeasePublishInfo item, String keyWord) {
        return (item.getMaTypeNames() != null && item.getMaTypeNames().contains(keyWord)) ||
                (item.getUnitName() != null && item.getUnitName().contains(keyWord)) ||
                (item.getLeaseUnit() != null && item.getLeaseUnit().contains(keyWord)) ||
                (item.getProjectName() != null && item.getProjectName().contains(keyWord)) ||
                (item.getLeaseProject() != null && item.getLeaseProject().contains(keyWord)) ||
                (item.getCode() != null && item.getCode().contains(keyWord)) ||
                (item.getCreateBy() != null && item.getCreateBy().contains(keyWord)) ||
                (item.getLeasePerson() != null && item.getLeasePerson().contains(keyWord)) ||
                (item.getPhone() != null && item.getPhone().contains(keyWord)) ||
                (item.getImpUnitName() != null && item.getImpUnitName().contains(keyWord));
    }

    /**
     * 从用户的AK，SK生成鉴权签名（Access Token）
     *
     * @return 鉴权签名（Access Token）
     * @throws IOException IO异常
     */
    static String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body=null;
        //生成随机数获取应用key
        Random random = new Random();
        int i = random.nextInt(2);
        if (i == 0){
            body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY
                    + "&client_secret=" + SECRET_KEY);
        } else {
            body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY_2
                    + "&client_secret=" + SECRET_KEY_2);
        }
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        String jsonString = response.body().string();
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        String accessToken = jsonObject.getString("access_token");
        return accessToken;
    }

    /**
     * 获取文件base64编码
     *
     * @param file MultipartFile 文件对象
     * 如果Content-Type是application/x-www-form-urlencoded时,传true
     * @return base64编码信息，不带文件头
     * @throws IOException IO异常
     */
    static String getFileContentAsBase64(MultipartFile file) throws IOException {
        return getFileContentAsBase64(file, true);
    }

    public static String encodeImageToBase64(String imagePath) throws IOException {
        // 创建一个File对象，指向图片所在的路径
        File file = new File(imagePath);
        // 检查文件是否存在
        if (!file.exists()) {
            throw new IOException("文件未找到: " + imagePath);
        }
        // 读取文件为字节数组
        byte[] fileContent = Files.readAllBytes(file.toPath());
        // 将字节数组编码为Base64字符串
        String encodedString = Base64.getEncoder().encodeToString(fileContent);
        encodedString=URLEncoder.encode(encodedString, "utf-8");

        return encodedString;
    }

    /**
     * 重载方法，可以指定是否进行URL编码
     */
    static String getFileContentAsBase64(MultipartFile file, boolean urlEncode) throws IOException {
        byte[] b = file.getBytes();
        String base64 = Base64.getEncoder().encodeToString(b);
        if (urlEncode) {
            base64 = URLEncoder.encode(base64, "utf-8");
        }
        return base64;
    }


    public static String encodeImageFromUrlToBase64(String imageUrl) throws IOException {
        System.err.println("imageUrl-=========:" + imageUrl);
        URL url = new URL(imageUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 设置请求方法为GET
        connection.setRequestMethod("GET");
        // 检查状态码是否为200 OK
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try (InputStream inputStream = connection.getInputStream();
                 ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                byte[] imageBytes = outputStream.toByteArray();
                // 将字节数组编码为Base64字符串
                String encodedString = Base64.getEncoder().encodeToString(imageBytes);
//                System.err.println("encodedString-=========:" + encodedString);
//                encodedString=URLEncoder.encode(encodedString, "utf-8");
//                System.err.println("encodedString222-=========:" + encodedString);
                return encodedString;
            }
        } else {
            throw new IOException("Failed to fetch image: HTTP status code " + responseCode);
        }
    }


}
