package com.bonus.bracelet.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.bonus.bracelet.mapper.PersonMgeMapper;
import com.bonus.bracelet.mapper.ResourceFileMapper;
import com.bonus.bracelet.service.FaceInterService;
import com.bonus.bracelet.service.IPersonMgeService;
import com.bonus.common.core.constant.BusinessConstants;
import com.bonus.common.core.constant.HttpStatus;
import com.bonus.common.core.constant.SecurityConstants;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.*;
import com.bonus.common.core.utils.encryption.Sm4Utils;
import com.bonus.common.core.utils.global.SystemGlobal;
import com.bonus.common.core.utils.uuid.IdUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.common.entity.bracelet.BraceletParamsDto;
import com.bonus.common.entity.bracelet.exportVo.PersonExportVo;
import com.bonus.common.entity.bracelet.importVo.PersonImportVo;
import com.bonus.common.entity.bracelet.vo.BaseProject;
import com.bonus.common.entity.bracelet.vo.CertificateVo;
import com.bonus.common.entity.bracelet.vo.PersonVo;
import com.bonus.common.entity.file.ResourceFileVo;
import com.bonus.common.security.utils.ValidatorsUtils;
import com.bonus.system.api.RemoteFileService;
import com.bonus.system.api.domain.SysFile;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * @className:PersonMgeServiceImpl
 * @author:cwchen
 * @date:2024-07-16-11:04
 * @version:1.0
 * @description:人员-serviceImpl
 */
@Service(value = "IPersonMgeService")
@Slf4j
public class PersonMgeServiceImpl implements IPersonMgeService {

    @Resource(name = "PersonMgeMapper")
    private PersonMgeMapper mapper;

    @Resource(name = "ResourceFileMapper")
    private ResourceFileMapper resourceFileMapper;

    @Resource(name = "ValidatorsUtils")
    private ValidatorsUtils validatorsUtils;

    @Resource(name = "testTaskExecutor")
    private ThreadPoolTaskExecutor testTaskExecutor;

    @Resource
    private RemoteFileService remoteFileService;

    @Autowired
    private FaceInterUtilService faceInterService;

    @Value("${file.temp_file_path}")
    private String tempFilePath;

    @Override
    public TableDataInfo getPersonLists(BraceletParamsDto dto) {
        dto.setSourceType(BusinessConstants.RESOURCE_TYPE_USER);
        List<PersonVo> list = new ArrayList<>();
        List<Future> futureList = new ArrayList<>();
        List<PersonVo> newList = new ArrayList<>();
        try {
            list = mapper.getPersonLists(dto);
            for (PersonVo vo : list) {
                Future<PersonVo> future = testTaskExecutor.submit(new Callable<PersonVo>() {
                    @Override
                    public PersonVo call() throws Exception {
                        vo.setIdCard(Sm4Utils.decode(vo.getIdCard()));
                        vo.setPhone(Sm4Utils.decode(vo.getPhone()));
                        String imageBase64 = getImageBase64(vo.getFilePath());
                        vo.setBase64Url(imageBase64);
                        int num = mapper.getCertificateNum(vo.getId());
                        vo.setCertificateNum(num);
                        return vo;
                    }
                });
                futureList.add(future);
            }
            for (Future<PersonVo> future : futureList) {
                PersonVo vo = future.get();
                newList.add(vo);
            }
        } catch (Exception e) {
            log.error("查询人员列表", e);
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(newList);
        rspData.setMsg("查询成功");
        rspData.setTotal(new PageInfo(list).getTotal());
        return rspData;
    }

    @Override
    public List<PersonVo> getExportPersonLists(BraceletParamsDto dto) {
        List<PersonVo> list = new ArrayList<>();
        try {
            list = mapper.getExportPersonLists(dto);
            for (PersonVo vo : list) {
                vo.setIdCard(Sm4Utils.decode(vo.getIdCard()));
                vo.setPhone(Sm4Utils.decode(vo.getPhone()));
            }
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addPerson(MultipartFile file, String params) {
        // 文件ID
        String delFileId = null;
        try {
            PersonVo vo = JSON.parseObject(params, PersonVo.class);
            String validResult = validatorsUtils.valid(vo, PersonVo.Query.class);
            if (StringUtils.isNotBlank(validResult)) {
                return AjaxResult.error(validResult);
            }
            // 验证身份证是否重复、手机号
            List<Map<String, String>> list = mapper.personIsExist(vo);
            if (idCardIsExist(list, vo, 1)) {
                return AjaxResult.error("身份证号码已存在");
            }
            if (idCardIsExist(list, vo, 2)) {
                return AjaxResult.error("电话已存在");
            }
            // 验证安全帽编号是否重复、马甲编号是否重复
            if (StringUtils.isNotBlank(vo.getAqmCode())) {
                int result = mapper.codeIsExist(vo, 1);
                if (result > 0) {
                    return AjaxResult.error("安全帽编号已存在");
                }
            }
            if (StringUtils.isNotBlank(vo.getMjCode())) {
                int result = mapper.codeIsExist(vo, 2);
                if (result > 0) {
                    return AjaxResult.error("马甲编号已存在");
                }
            }
            // 校验文件、上传文件
            String isVerify = UploadCheckUtils.uploadImgVerify(file);
            if (StringUtils.isNotBlank(isVerify)) {
                return AjaxResult.error(isVerify);
            }
            // 对身份证号、手机号 进行 sm4加密  保存人员数据、保存文件资源
            vo.setIdCard(Sm4Utils.encode(vo.getIdCard()));
            vo.setPhone(Sm4Utils.encode(vo.getPhone()));
            mapper.addPerson(vo);
            delFileId = uploadFile(file, vo);
            // 添加人脸照片至人脸库
            AjaxResult ajaxResult = addFaceToLibrary(BytesToMultipartFileUtil.multipartFileToBase64(file), FaceCodeUtil.ADD, "bz-" + vo.getId());
            JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult.get("data")));
            Integer code = data.getInteger("code");
            String msg = data.getString("msg");
            if (Objects.equals(code, BusinessConstants.SUCCESS_CODE)) {
                // 更新人脸库推送状态
                mapper.updatePeoplePushStatus(vo.getId(),1);
            }else{
                mapper.updatePeoplePushStatus(vo.getId(),0);
            }
        } catch (Exception e) {
            log.error("新增人员", e);
            // 添加失败-删除文件
            if (delFileId != null) {
                remoteFileService.delFile(delFileId, SecurityConstants.INNER);
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult editPerson(MultipartFile file, String params) {
        // 文件ID
        String delFileId = null;
        try {
            PersonVo vo = JSON.parseObject(params, PersonVo.class);
            String validResult = validatorsUtils.valid(vo, PersonVo.Query.class);
            if (StringUtils.isNotBlank(validResult)) {
                return AjaxResult.error(validResult);
            }
            // 人员已分配班组，岗位限制修改
            Integer canItBeModified = mapper.canItBeModified(vo);
            if (canItBeModified > 0) {
                return AjaxResult.error("人员已分配班组，岗位已限制修改");
            }
            // 验证身份证是否重复、手机号
            List<Map<String, String>> list = mapper.personIsExist(vo);
            if (idCardIsExist(list, vo, 1)) {
                return AjaxResult.error("身份证号码已存在");
            }
            if (idCardIsExist(list, vo, 2)) {
                return AjaxResult.error("电话已存在");
            }
            // 验证安全帽编号是否重复、马甲编号是否重复
            if (StringUtils.isNotBlank(vo.getAqmCode())) {
                int result = mapper.codeIsExist(vo, 1);
                if (result > 0) {
                    return AjaxResult.error("安全帽编号已存在");
                }
            }
            if (StringUtils.isNotBlank(vo.getMjCode())) {
                int result = mapper.codeIsExist(vo, 2);
                if (result > 0) {
                    return AjaxResult.error("马甲编号已存在");
                }
            }
            // 校验文件、上传文件
            if (StringUtils.isNotBlank(vo.getDelFiles())) {
                String isVerify = UploadCheckUtils.uploadImgVerify(file);
                if (StringUtils.isNotBlank(isVerify)) {
                    return AjaxResult.error(isVerify);
                }
            }
            // 对身份证号、手机号 进行 sm4加密 保存人员数据 保存文件资源 删除文件
            vo.setIdCard(Sm4Utils.encode(vo.getIdCard()));
            vo.setPhone(Sm4Utils.encode(vo.getPhone()));
            mapper.editPerson(vo);
            delFileId = uploadFile(file, vo);
            if (StringUtils.isNotEmpty(vo.getDelFiles())) {
                String personImgBase64 = getPersonImgBase64(vo.getDelFiles());
                // 删除人脸库，添加人脸照片至人脸库
                AjaxResult delAjax = delFaceToLibrary(personImgBase64, FaceCodeUtil.DEL, "bz-" + vo.getId());
                AjaxResult ajaxResult = addFaceToLibrary(BytesToMultipartFileUtil.multipartFileToBase64(file), FaceCodeUtil.ADD, "bz-" + vo.getId());
                JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult.get("data")));
                Integer code = data.getInteger("code");
                String msg = data.getString("msg");
                if (Objects.equals(code, BusinessConstants.SUCCESS_CODE)) {
                    // 更新人脸库推送状态
                    mapper.updatePeoplePushStatus(vo.getId(),1);
                }else{
                    mapper.updatePeoplePushStatus(vo.getId(),0);
                }
                String[] delFiles = vo.getDelFiles().split(",");
                for (String fileId : delFiles) {
                    resourceFileMapper.delResourceFile(vo.getFileId());
                    remoteFileService.delFile(fileId, SecurityConstants.INNER);
                }
            }
        } catch (Exception e) {
            log.error("修改人员", e);
            // 添加失败-删除文件
            if (StringUtils.isNotEmpty(delFileId)) {
                remoteFileService.delFile(delFileId, SecurityConstants.INNER);
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    /**
     * 添加人脸库
     *
     * @param base64
     * @param type
     * @param id
     * @return Integer
     * @author cwchen
     * @date 2024/8/12 13:20
     */
    public AjaxResult addFaceToLibrary(String base64, String type, String id) {
        if (StringUtils.isEmpty(base64)) {
            return null;
        }
        AjaxResult ajaxResult = faceInterService.addFace(base64, type, id);
        log.info("添加人脸库返回结果：{}", ajaxResult);
        return ajaxResult;
    }

    /**
     * 删除人脸库
     *
     * @param base64
     * @param type
     * @param id
     * @return Integer
     * @author cwchen
     * @date 2024/8/12 13:27
     */
    public AjaxResult delFaceToLibrary(String base64, String type, String id) {
        if (StringUtils.isEmpty(base64)) {
            return null;
        }
        AjaxResult ajaxResult = faceInterService.addFace(base64, type, id);
        log.info("删除人脸库返回结果：{}", ajaxResult);
        return ajaxResult;
    }

    @Override
    public AjaxResult getPersonInfo(BraceletParamsDto dto) {
        try {
            dto.setSourceType(BusinessConstants.RESOURCE_TYPE_USER);
            PersonVo vo = mapper.getPersonInfo(dto);
            PersonVo handleData = handleData(vo);
            return AjaxResult.success(handleData);
        } catch (Exception e) {
            log.error("人员详情", e);
            return AjaxResult.error();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delPerson(BraceletParamsDto dto) {
        List<CertificateVo> list = new ArrayList<>();
        try {
            PersonVo vo = mapper.getPersonInfo(dto);
            if (vo.getTeamId() != null) {
                return AjaxResult.error("该人员已分配班组，请先从班组中移除该人员");
            }
            // 判断人员是否领用设备包括手环箱、手环、安全帽等设备
            List<Integer> isLyDevices = mapper.isLyDevices(vo);
            if (isLyDevices.get(0) > 0) {
                return AjaxResult.error("该人员已绑定手环");
            }else if (isLyDevices.get(1) > 0) {
                return AjaxResult.error("该人员已绑定设备");
            }else if (isLyDevices.get(2) > 0) {
                return AjaxResult.error("该人员已领用手环箱");
            }else if (isLyDevices.get(3) > 0) {
                return AjaxResult.error("该人员已领用设备");
            }
            // 删除人员、资源文件、人脸照片
            mapper.delPerson(dto);
            list = mapper.getCertificate(dto);
            if (list != null) {
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setCertificateType(list.get(i).getCertificateType() + 1);
                    mapper.delCertificateResourceFile(list.get(i));
                }
            }
            mapper.delCertificate(dto);
            // 删除人脸库
            String base64Data = getPersonImgBase64(dto.getFilePath());
            AjaxResult delAjax = delFaceToLibrary(base64Data, FaceCodeUtil.DEL, "bz-" + dto.getId());
            resourceFileMapper.delResourceFile(dto.getFileId());
            remoteFileService.delFile(dto.getFilePath(), SecurityConstants.INNER);
            return AjaxResult.success();
        } catch (Exception e) {
            log.error("删除人员", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult pushFace(BraceletParamsDto dto) {
        try {
            String base64Data = getPersonImgBase64(dto.getFilePath());
            if (StringUtils.isEmpty(base64Data)) {
                return AjaxResult.error("未上传人脸照片");
            }
            // 删除人脸库，添加人脸照片至人脸库
            delFaceToLibrary(base64Data, FaceCodeUtil.DEL, "bz-" + dto.getId());
            AjaxResult ajaxResult = addFaceToLibrary(base64Data, FaceCodeUtil.ADD, "bz-" + dto.getId());
            JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult.get("data")));
            Integer code = data.getInteger("code");
            String msg = data.getString("msg");
            if (Objects.equals(code, BusinessConstants.SUCCESS_CODE)) {
                // 更新人脸库推送状态
                mapper.updatePeoplePushStatus(dto.getId(),1);
            }else{
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            log.error(e.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    /**
     * 根据文件ID获取图片base64
     *
     * @param filePath
     * @return String
     * @author cwchen
     * @date 2024/8/12 14:35
     */
    public String getPersonImgBase64(String filePath) {
        R<SysFile> result = remoteFileService.getImgBase64(filePath, SecurityConstants.INNER);
        if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
            String jsonString = JSON.toJSONString(result.getData());
            JSONObject item = JSON.parseObject(jsonString);
            String base64 = item.getString("url");
            return base64;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult excelUpload(MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
        String result = UploadCheckUtils.uploadExcelVerify(file);
        if (StringUtils.isNotBlank(result)) {
            return AjaxResult.error(result);
        }
        List<String> errorFileLists = new ArrayList<>();
        List<String> errorIdLists = new ArrayList<>();
        try {
            List<JSONObject> lstObj = (List<JSONObject>) ImportExcelUtils.readExcel(file, PersonImportVo.class, tempFilePath);
            List<PersonVo> list = new ArrayList<>();
            if (CollectionUtils.isEmpty(lstObj)) {
                return AjaxResult.error("请勿导入空数据");
            }
            // 获取人员岗位
            List<Map<String, String>> postTypeList = mapper.getPostType();
            // 校验数据是否合法、包含照片验证
            for (JSONObject obj : lstObj) {
                PersonImportVo vo = new PersonImportVo();
                PersonVo personVo = new PersonVo();
                vo = setPersonData(vo, obj, postTypeList);
                String isVerify = UploadCheckUtils.uploadImgVerify(vo.getFile());
                if (StringUtils.isNotBlank(isVerify)) {
                    return AjaxResult.error("第" + obj.getString("rowNo") + "行人脸照片" + isVerify);
                }
                BeanUtils.copyProperties(vo, personVo);
                String validResult = validatorsUtils.valid(personVo, PersonVo.Query.class);
                if (StringUtils.isNotBlank(validResult)) {
                    return AjaxResult.error("第" + obj.getString("rowNo") + "行" + validResult);
                }
                list.add(personVo);
            }
            // 校验身份证号、电话、安全帽编号、马甲编号 是否存在相同数据
            List<String> sameList = same(list, 1, "身份证号");
            List<String> sameList2 = same(list, 2, "电话");
            List<String> sameList3 = same(list, 3, "安全帽编号");
            List<String> sameList4 = same(list, 4, "马甲编号");
            String existData = isExistData(sameList);
            String existData2 = isExistData(sameList2);
            String existData3 = isExistData(sameList3);
            String existData4 = isExistData(sameList4);
            String errorInfo = returnErrorInfo(existData, existData2, existData3, existData4);
            if(StringUtils.isNotBlank(errorInfo)){
                return AjaxResult.error(errorInfo);
            }
            /*if (StringUtils.isNotBlank(existData)) {
                return AjaxResult.error(existData);
            }
            if (StringUtils.isNotBlank(existData2)) {
                return AjaxResult.error(existData2);
            }
            if (StringUtils.isNotBlank(existData3)) {
                return AjaxResult.error(existData3);
            }
            if (StringUtils.isNotBlank(existData4)) {
                return AjaxResult.error(existData4);
            }*/
            // 校验库中数据的身份证号、手机号、安全帽编号、马甲编号是否重复
            List<Map<String, String>> personIsExist = mapper.personIsExist(new PersonVo());
            List<Map<String, String>> aqmCodes = mapper.aqmCodeIsExist();
            List<Map<String, String>> mjCodes = mapper.mjCodeIsExist();
            for (PersonVo vo : list) {
                if (idCardIsExist(personIsExist, vo, 1)) {
                    return AjaxResult.error("第" + vo.getSerialNumber() + "行身份证号码已存在");
                }
                if (idCardIsExist(personIsExist, vo, 2)) {
                    return AjaxResult.error("第" + vo.getSerialNumber() + "行电话已存在");
                }
                if (codeIsExist(aqmCodes, vo.getAqmCode())) {
                    return AjaxResult.error("第" + vo.getSerialNumber() + "行安全帽编号已存在");
                }
                if (codeIsExist(mjCodes, vo.getMjCode())) {
                    return AjaxResult.error("第" + vo.getSerialNumber() + "行马甲编号已存在");
                }
            }
            for (PersonVo vo : list) {
                // 对身份证号、手机号 进行 sm4加密  保存人员数据、保存文件资源
                vo.setIdCard(Sm4Utils.encode(vo.getIdCard()));
                vo.setPhone(Sm4Utils.encode(vo.getPhone()));
                mapper.addPerson(vo);
                // 推送人脸照片到人脸库，并更新推送状态
                AjaxResult ajaxResult = addFaceToLibrary(BytesToMultipartFileUtil.multipartFileToBase64(vo.getFile()), FaceCodeUtil.ADD, "bz-" + vo.getId());
                JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult.get("data")));
                Integer code = data.getInteger("code");
                String msg = data.getString("msg");
                if (Objects.equals(code, BusinessConstants.SUCCESS_CODE)) {
                    // 更新人脸库推送状态
                    mapper.updatePeoplePushStatus(vo.getId(),1);
                }else{
                    mapper.updatePeoplePushStatus(vo.getId(),0);
                }
                String delFileId = uploadFile(vo.getFile(), vo);
                errorFileLists.add(delFileId);
                errorIdLists.add("bz-" + vo.getId());
            }
        } catch (RuntimeException runtimeException) {
            if (runtimeException.getMessage() == null) {
                return AjaxResult.error("模板中含有单元格数据格式不正确");
            }
            return AjaxResult.error(runtimeException.getMessage());
        } catch (Exception e) {
            log.error(e.toString(), e);
            // 添加失败-删除文件、删除人脸库照片
            if (CollectionUtils.isNotEmpty(errorFileLists)) {
                for (int i = 0; i < errorFileLists.size(); i++) {
                    remoteFileService.delFile(errorFileLists.get(i), SecurityConstants.INNER);
                    delFaceToLibrary(null, FaceCodeUtil.DEL, errorIdLists.get(i));
                }
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    public String returnErrorInfo(String existData,String existData2,String existData3,String existData4){
        if(StringUtils.isEmpty(existData) && StringUtils.isEmpty(existData2)
                && StringUtils.isEmpty(existData3)&& StringUtils.isEmpty(existData4)){
            return null;
        }else{
            StringBuffer sb = new StringBuffer();
            if(StringUtils.isNotEmpty(existData)){
                sb.append(existData + "<br>");
            }
            if(StringUtils.isNotEmpty(existData2)){
                sb.append(existData2 + "<br>");
            }
            if(StringUtils.isNotEmpty(existData3)){
                sb.append(existData3 + "<br>");
            }
            if(StringUtils.isNotEmpty(existData4)){
                sb.append(existData4 + "<br>");
            }
            return sb.toString();
        }
    }

    @Override
    public AjaxResult getPersonFace(BraceletParamsDto dto) {
        if (StringUtils.isBlank(dto.getFilePath())) {
            return AjaxResult.success("查询成功", null);
        }
        String imgBase64 = getPersonImgBase64(dto.getFilePath());
        return AjaxResult.success("查询成功", imgBase64);
    }

    /**
     * 验证身份证号是否存在
     *
     * @param list
     * @return boolean
     * @author cwchen
     * @date 2024/7/16 13:21
     */
    public boolean idCardIsExist(List<Map<String, String>> list, PersonVo vo, int type) {
        if (CollectionUtils.isEmpty(list)) {
            return false;
        } else {
            String encodeValue = Sm4Utils.encode(type == BusinessConstants.TYPE ? vo.getIdCard() : vo.getPhone());
            for (Map<String, String> map : list) {
                String value = type == BusinessConstants.TYPE ? map.get("value") : map.get("phone");
                if (Objects.equals(encodeValue, value)) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 判断安全帽编号、马甲编号 是否重复
     *
     * @param list
     * @param value
     * @return boolean
     * @author cwchen
     * @date 2024/8/19 18:09
     */
    public boolean codeIsExist(List<Map<String, String>> list, String value) {
        if (CollectionUtils.isEmpty(list) || StringUtils.isEmpty(value)) {
            return false;
        } else {
            for (Map<String, String> map : list) {
                String code = map.get("code");
                if (Objects.equals(code, value)) {
                    return true;
                }
            }
            return false;
        }
    }


    /**
     * 文件上传
     *
     * @param file
     * @param vo
     * @return void
     * @author cwchen
     * @date 2024/7/16 14:46
     */
    public String uploadFile(MultipartFile file, PersonVo vo) {
        R result = remoteFileService.singleUploadFile(file, SecurityConstants.INNER);
        if (result != null && result.getCode() == HttpStatus.ERROR) {
            log.error("人员照片上传失败");
            return null;
        } else if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
            String jsonString = JSON.toJSONString(result.getData());
            JSONObject item = JSON.parseObject(jsonString);
            if (item != null) {
                ResourceFileVo fileVo = setResourceFileData(item, vo);
                resourceFileMapper.addFile(fileVo);
            }
            return item.getString("fileId");
        }
        return null;
    }

    public PersonVo handleData(PersonVo vo) {
        vo.setIdCard(Sm4Utils.decode(vo.getIdCard()));
        vo.setPhone(Sm4Utils.decode(vo.getPhone()));
        R<SysFile> result = remoteFileService.getImgBase64(vo.getFilePath(), SecurityConstants.INNER);
        if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
            String jsonString = JSON.toJSONString(result.getData());
            JSONObject item = JSON.parseObject(jsonString);
            String base64 = item.getString("url");
            vo.setBase64Url(base64);
        }
        return vo;
    }

    /**
     * 获取图片的base64
     *
     * @param filePath
     * @return String
     * @author cwchen
     * @date 2024/8/20 9:18
     */
    public String getImageBase64(String filePath) {
        R<SysFile> result = remoteFileService.getImgBase64(filePath, SecurityConstants.INNER);
        if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
            String jsonString = JSON.toJSONString(result.getData());
            JSONObject item = JSON.parseObject(jsonString);
            String base64 = item.getString("url");
            return base64;
        }
        return null;
    }


    /**
     * 资源文件赋值
     *
     * @param item
     * @return ResourceFileVo
     * @author cwchen
     * @date 2024/7/16 13:49
     */
    public ResourceFileVo setResourceFileData(JSONObject item, PersonVo vo) {
        ResourceFileVo fileVo = new ResourceFileVo();
        String resourceId = IdUtils.simpleUUID();
        fileVo.setFileType(1);
        fileVo.setFilePath(item.getString("fileId"));
        fileVo.setFileSuffix(item.getString("suffix"));
        fileVo.setFileName(item.getString("fileName"));
        fileVo.setSourceId(vo.getId() + "");
        fileVo.setSourceType("1");
        return fileVo;
    }

    /**
     * 证书资源文件赋值
     *
     * @param item
     * @param vo
     * @return
     */
    public ResourceFileVo setCertificateResourceFileData(JSONObject item, CertificateVo vo) {
        ResourceFileVo fileVo = new ResourceFileVo();
        String fileType = null;
        if (item.get("suffix").equals(".pdf") || item.get("suffix").equals(".doc") || item.get("suffix").equals(".docx")) {
            fileType = "0";
        } else {
            fileType = String.valueOf(vo.getCertificateType() + 1);
        }
        String resourceId = IdUtils.simpleUUID();
        if (fileType.equals("0")) {
            fileVo.setFileType(0);
            fileVo.setSourceType(String.valueOf(vo.getCertificateType() + 1));
        } else {
            fileVo.setFileType(1);
            fileVo.setSourceType(fileType);
        }
        fileVo.setFilePath(item.getString("fileId"));
        fileVo.setFileSuffix(item.getString("suffix"));
        fileVo.setFileName(item.getString("fileName"));
        fileVo.setSourceId(vo.getId() + "");
        return fileVo;
    }

    /**
     * 人员数据赋值
     *
     * @param vo
     * @param obj
     * @return PersonVo
     * @author cwchen
     * @date 2024/7/17 10:38
     */
    public PersonImportVo setPersonData(PersonImportVo vo, JSONObject obj, List<Map<String, String>> postList) {
        vo.setSerialNumber(obj.getString("rowNum"));
        vo.setName(handleData(obj.getString("name")));
        vo.setSex(setSexData(handleData(obj.getString("sex"))));
        vo.setIdCard(handleData(obj.getString("idCard")));
        vo.setPhone(handleData(obj.getString("phone")));
        vo.setFile(obj.get("file") != null ? (MultipartFile) obj.get("file") : null);
        vo.setPost(setPost(postList, handleData(obj.getString("post"))));
        vo.setAqmCode(handleData(obj.getString("aqmCode")));
        vo.setMjCode(handleData(obj.getString("mjCode")));
        return vo;
    }

    /**
     * 设置人员岗位
     *
     * @param postList
     * @param value
     * @return String
     * @author cwchen
     * @date 2024/8/12 10:07
     */
    public String setPost(List<Map<String, String>> postList, String value) {
        if (CollectionUtils.isEmpty(postList)) {
            return null;
        }
        for (Map<String, String> map : postList) {
            if (Objects.equals(map.get("name"), value)) {
                return map.get("value");
            }
        }
        return null;
    }

    /**
     * 处理性别
     *
     * @param value
     * @return Integer
     * @author cwchen
     * @date 2024/7/17 10:39
     */
    public Integer setSexData(String value) {
        if(StringUtils.isEmpty(value)){
            return null;
        }
        switch (value) {
            case BusinessConstants.MAN:
                return 0;
            case BusinessConstants.FEMALE:
                return 1;
            case BusinessConstants.OTHER:
                return 2;
            default:
                return 3;
        }
    }

    public static List<String> same(List<PersonVo> list, int type, String name) {
        // 1 身份证号 2.手机号 3.安全安全帽编号 4.马甲编号
        List<String> errList = new ArrayList<String>();
        Map<String, String> map = new HashMap<String, String>();
        for (int i = 0; i < list.size(); i++) {
            String key = null;
            if (type == BusinessConstants.SAME_TYPE) {
                key = list.get(i).getIdCard();
            } else if (type == BusinessConstants.SAME_TYPE2) {
                key = list.get(i).getPhone();
            } else if (type == BusinessConstants.SAME_TYPE3) {
                key = list.get(i).getAqmCode();
            } else if (type == BusinessConstants.SAME_TYPE4) {
                key = list.get(i).getMjCode();
            }
            if (key == null || Objects.equals("", key)) {
                continue;
            }
            String old = map.get(key);
            if (old != null) {
                map.put(key, old + "," + (i + 3));
            } else {
                map.put(key, "" + (i + 3));
            }
        }
        Iterator<String> it = map.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            String value = map.get(key);
            if (value.indexOf(",") != -1) {
                System.out.println(key + " 重复,行： " + value);
                errList.add(name + " 重复,重复行： " + value);
            }
        }
        return errList;
    }

    /**
     * excel表格是否存在相同数据
     *
     * @return String
     * @author cwchen
     * @date 2024/7/17 12:07
     */
    public String isExistData(List<String> sameList) {
        if (CollectionUtils.isNotEmpty(sameList)) {
            StringBuffer errStr = new StringBuffer();
            for (int j = 0; j < sameList.size(); j++) {
                errStr.append(sameList.get(j) + "\n");
            }
            return errStr.toString();
        }
        return null;
    }

    public String handleData(String value) {
        if (StringUtils.isNotBlank(value)) {
            return value.trim();
        }
        return null;
    }

    @Override
    public AjaxResult selectCertificateById(Integer memberId) {
        List<ResourceFileVo> highImgList = new ArrayList<>();
        List<ResourceFileVo> electricianImgList = new ArrayList<>();
        List<ResourceFileVo> elseImgList = new ArrayList<>();
        try {
            PersonVo vo = mapper.selectCertificateById(memberId);
            if (ObjectUtil.isNotEmpty(vo)) {
                List<ResourceFileVo> list = mapper.selectCertificateFile(memberId);
                getImageFileTwo(list);
                for (int i = 0; i < list.size(); i++) {
                    if(list.get(i).getFileType()==0){
                        list.get(i).setBast64Image(null);
                    }
                }
                highImgList = list.stream().filter(bracelet -> (bracelet.getSourceImagType() == 2)).collect(Collectors.toList());
                electricianImgList = list.stream().filter(bracelet -> (bracelet.getSourceImagType() == 3)).collect(Collectors.toList());
                elseImgList = list.stream().filter(bracelet -> (bracelet.getSourceImagType() == 4)).collect(Collectors.toList());
                vo.setHighImgList(highImgList);
                vo.setElectricianImgList(electricianImgList);
                vo.setElseImgList(elseImgList);
            }
            return AjaxResult.success(vo);
        } catch (Exception e) {
            log.error("人员详情", e);
            return AjaxResult.error();
        }
    }

    @Override
    public AjaxResult getFileUrl(ResourceFileVo dto) {
        try {
            R<SysFile> result = remoteFileService.getImgBase64(dto.getFilePath(), SecurityConstants.INNER);
            if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
                String jsonString = JSON.toJSONString(result.getData());
                JSONObject item = JSON.parseObject(jsonString);
                String base64 = item.getString("url");
                dto.setBast64Image(base64);
            }
            return AjaxResult.success(dto);
        } catch (Exception e) {
            log.error("文件下载错误", e);
            return AjaxResult.error();
        }
    }


    /**
     * 图片查询
     *
     * @param list
     * @return
     */
    public void getImageFile(List<ResourceFileVo> list) {
        if (com.bonus.common.core.utils.StringUtils.isNotEmpty(list)) {
            list.forEach(file -> {
                R<SysFile> result = remoteFileService.getImgBase64(file.getFilePath(), SecurityConstants.INNER);
                if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
                    String jsonString = JSON.toJSONString(result.getData());
                    JSONObject item = JSON.parseObject(jsonString);
                    String base64 = item.getString("url");
                    file.setBast64Image(base64);
                }
            });
        }

    }

    public void getImageFileTwo(List<ResourceFileVo> list) {
        if (com.bonus.common.core.utils.StringUtils.isNotEmpty(list)) {
            list.forEach(file -> {
            if(file.getFileType()!=0){
                R<SysFile> result = remoteFileService.getImgBase64(file.getFilePath(), SecurityConstants.INNER);
                if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
                    String jsonString = JSON.toJSONString(result.getData());
                    JSONObject item = JSON.parseObject(jsonString);
                    String base64 = item.getString("url");
                    file.setBast64Image(base64);
                }
            }
            });
        }

    }

    public AjaxResult updateCertificate(MultipartFile[] highfile, MultipartFile[] electfile, MultipartFile[] elsefile, Long id) {
        String delFileId = null;
        CertificateVo vo = new CertificateVo();
        try {
            if (highfile != null) {
                R result = remoteFileService.mostUploadFile(highfile, SecurityConstants.INNER);
                if (result != null && result.getCode() == HttpStatus.ERROR) {
                    log.error("高处作业证上传失败");
                    return null;
                } else if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
                    String jsonString = JSON.toJSONString(result.getData());
                    JSONArray json = JSON.parseArray(jsonString);
                    for (int i = 0; i < json.size(); i++) {
                        JSONObject item = json.getJSONObject(i);
                        if (item != null) {
                            vo.setPeopleId(id);
                            vo.setCertificateType(1);
                            mapper.insertCertificate(vo);
                            ResourceFileVo fileVo = setCertificateResourceFileData(item, vo);
                            resourceFileMapper.addFile(fileVo);
                            delFileId = item.getString("fileId");
                        }
                    }
                }
            }
            if (electfile != null) {
                R result2 = remoteFileService.mostUploadFile(electfile, SecurityConstants.INNER);
                if (result2 != null && result2.getCode() == HttpStatus.ERROR) {
                    log.error("电工作业证上传失败");
                    return null;
                } else if (result2 != null && result2.getCode() == HttpStatus.SUCCESS && result2.getData() != null) {
                    String jsonString = JSON.toJSONString(result2.getData());
                    JSONArray json = JSON.parseArray(jsonString);
                    for (int i = 0; i < json.size(); i++) {
                        JSONObject item = json.getJSONObject(i);
                        if (item != null) {
                            vo.setPeopleId(id);
                            vo.setCertificateType(2);
                            mapper.insertCertificate(vo);
                            ResourceFileVo fileVo = setCertificateResourceFileData(item, vo);
                            resourceFileMapper.addFile(fileVo);
                            delFileId = item.getString("fileId");
                        }
                    }
                }
            }
            if (elsefile != null) {
                R result3 = remoteFileService.mostUploadFile(elsefile, SecurityConstants.INNER);
                if (result3 != null && result3.getCode() == HttpStatus.ERROR) {
                    log.error("其他作业证上传失败");
                    return null;
                } else if (result3 != null && result3.getCode() == HttpStatus.SUCCESS && result3.getData() != null) {
                    String jsonString = JSON.toJSONString(result3.getData());
                    JSONArray json = JSON.parseArray(jsonString);
                    for (int i = 0; i < json.size(); i++) {
                        JSONObject item = json.getJSONObject(i);
                        if (item != null) {
                            vo.setPeopleId(id);
                            vo.setCertificateType(3);
                            mapper.insertCertificate(vo);
                            ResourceFileVo fileVo = setCertificateResourceFileData(item, vo);
                            resourceFileMapper.addFile(fileVo);
                            delFileId = item.getString("fileId");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("新增证书", e);
            // 添加失败-删除文件
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(delFileId)) {
                remoteFileService.delFile(delFileId, SecurityConstants.INNER);
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
        return AjaxResult.success();

    }
}
