package com.yd.api.practitioner.service.impl;

import com.yd.api.practitioner.service.PractitionerHiringContractService;
import com.yd.api.practitioner.service.PractitionerHiringService;
import com.yd.api.practitioner.vo.hiring.*;
import com.yd.api.result.CommonResult;
import com.yd.dal.entity.agms.hiring.PractitionerHiringWorkingExperience;
import com.yd.dal.entity.customer.*;
import com.yd.dal.entity.meta.MdPractitionerHiringApproveSteps;
import com.yd.dal.entity.practitioner.hiring.*;
import com.yd.dal.mapper.customer.*;
import com.yd.dal.service.customer.AclPractitionerDALService;
import com.yd.dal.service.customer.AclPractitionerHiringApproveRecordsDALService;
import com.yd.dal.service.customer.AclPractitionerSubordinateSystemDALService;
import com.yd.dal.service.practitioner.PractitionerHiringDALService;
import com.yd.rmi.ali.oss.service.OssService;
import com.yd.rmi.ali.send.service.SendService;
import com.yd.rmi.cache.SystemConfigService;
import com.yd.util.CommonUtil;
import com.yd.util.HttpUtil;
import com.yd.util.config.ZHBErrorConfig;
import org.apache.commons.beanutils.BeanPropertyValueEqualsPredicate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class PractitionerHiringServiceImpl implements PractitionerHiringService {
    @Autowired
    private OssService ossService;
    @Autowired
    private AclPractitionerHiringMembershipMapper membershipMapper;
    @Autowired
    private AclPractitionerHiringBasicInfoMapper basicInfoMapper;
    @Autowired
    private AclPractitionerHiringWorkingExperienceMapper workingExperienceMapper;
    @Autowired
    private AclPractitionerHiringPersonalStatementsMapper personalStatementsMapper;
    @Autowired
    private AclPractitionerHiringContractTermsConfirmsMapper contractTermsConfirmsMapper;
    @Autowired
    private AclPractitionerHiringApproveRecordsMapper recordsMapper;
    @Autowired
    private PractitionerHiringContractService hiringContractService;
    @Autowired
    private AclPractitionerMapper aclPractitionerMapper;
    @Autowired
    private SendService sendService;
    @Autowired
    private AclPractitionerDALService aclPractitionerDALService;
    @Autowired
    private AclPractitionerPotentialMapper aclPractitionerPotentialMapper;
    @Autowired
    private AclPractitionerSubordinateSystemDALService aclPractitionerSubordinateSystemDALService;

    private PractitionerHiringDALService practitionerHiringDalService;
    private SystemConfigService systemConfigService;
    private AclPractitionerHiringApproveRecordsDALService aclPractitionerHiringApproveRecordsDalService;

    @Autowired
    public void setPractitionerHiringDalService(PractitionerHiringDALService practitionerHiringDalService) {
        this.practitionerHiringDalService = practitionerHiringDalService;
    }

    @Autowired
    public void setSystemConfigService(SystemConfigService systemConfigService) {
        this.systemConfigService = systemConfigService;
    }

    @Autowired
    public void setAclPractitionerHiringApproveRecordsDalService(AclPractitionerHiringApproveRecordsDALService aclPractitionerHiringApproveRecordsDalService) {
        this.aclPractitionerHiringApproveRecordsDalService = aclPractitionerHiringApproveRecordsDalService;
    }

    @Override
    public SaveMembershipResponseVO saveMembership(SaveMembershipRequestVO requestVO) {
        SaveMembershipResponseVO resp = new SaveMembershipResponseVO();
        try {
            Long mdDropOptionId = requestVO.getMdDropOptionId();
            if (mdDropOptionId == null) {
                resp.setCommonResult(new CommonResult(false, "报聘职级不能为空"));
                return resp;
            }

            Long basicInfoId = requestVO.getHiringBasicInfoId();
            if (basicInfoId == null) {
                // 先保存ag_acl_practitioner_hiring_basic_info，获取hiringBasicInfoId
                AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
                basicInfo.setName(requestVO.getName());
                basicInfo.setPractitionerPotentialId(requestVO.getPractitionerPotentialId());
                basicInfoMapper.insertSelective(basicInfo);
                // 保存组织关系
                AclPractitionerHiringMembership membership = new AclPractitionerHiringMembership();
                BeanUtils.copyProperties(requestVO, membership);
                membership.setHiringBasicInfoId(basicInfo.getId());
                membership.setIsActive(1);

                Date curDate = new Date();
                membership.setCreatedAt(curDate);
                membership.setUpdatedAt(curDate);

                Long loginId = requestVO.getLoginId();
                membership.setCreatedBy(loginId);
                membership.setUpdatedBy(loginId);
                membershipMapper.insertSelective(membership);

                resp.setHiringBasicInfoId(basicInfo.getId());

            } else {
                // 仅需更新组织关系
                AclPractitionerHiringMembership membership = membershipMapper.selectByHiringBasicInfoId(basicInfoId);
                BeanUtils.copyProperties(requestVO, membership);
                membership.setHiringBasicInfoId(basicInfoId);
                membership.setIsActive(1);

                Date curDate = new Date();
                membership.setUpdatedAt(curDate);

                Long loginId = requestVO.getLoginId();
                membership.setUpdatedBy(loginId);
                membershipMapper.updateByPrimaryKeySelective(membership);

                resp.setHiringBasicInfoId(basicInfoId);
            }

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public CommonResultResponseVO saveBasicInfo(SaveBasicInfoRequestVO requestVO) {
        CommonResultResponseVO resp = new CommonResultResponseVO();
        try {
            // 数据库实体
            AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
            BeanUtils.copyProperties(requestVO, basicInfo);
            basicInfo.setIsActive(1);

            Date curDate = new Date();
            basicInfo.setCreatedAt(curDate);
            basicInfo.setUpdatedAt(curDate);

            basicInfo.setCreatedBy((long) -1);
            basicInfo.setUpdatedBy((long) -1);

            basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public QueryMembershipResponseVO queryMembership(HiringBasicInfoIdRequestVO requestVO) {
        QueryMembershipResponseVO resp = new QueryMembershipResponseVO();
        try {
            AclPractitionerHiringMembership membership = membershipMapper.queryByhiringBasicInfoId(requestVO);

            resp.setMembership(membership);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public CommonResultResponseVO saveWorkingExperience(SaveWorkingExperienceRequestVO requestVO) {
        CommonResultResponseVO resp = new CommonResultResponseVO();
        try {
            List<PractitionerHiringWorkingExperience> workingExperienceList = requestVO.getWorkingExperienceList();
            Long basicInfoId = requestVO.getHiringBasicInfoId();

            List<AclPractitionerHiringWorkingExperience> dataObjList = new ArrayList<>();
            Date curDate = new Date();

            workingExperienceList.forEach(item -> {
                AclPractitionerHiringWorkingExperience dataObj = new AclPractitionerHiringWorkingExperience();
                BeanUtils.copyProperties(item, dataObj);

                dataObj.setHiringBasicInfoId(basicInfoId);
                dataObj.setIsActive(1);

                dataObj.setCreatedAt(curDate);
                dataObj.setUpdatedAt(curDate);

                dataObj.setCreatedBy((long) -1);
                dataObj.setUpdatedBy((long) -1);

                dataObjList.add(dataObj);
            });

            List<AclPractitionerHiringWorkingExperience> resultList = workingExperienceMapper.selectByHiringBasicInfoId(basicInfoId);
            if (CollectionUtils.isNotEmpty(resultList)) {
                workingExperienceMapper.deleteBatchByIds(resultList);
            }

            if (dataObjList.size() > 0) {
                workingExperienceMapper.batchInsert(dataObjList);
            }

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public SavePersonPictureResponseVO savePersonPicture(SavePersonPictureRequestVO requestVO) {

        System.out.println("--------保存人像照片入参----------");
        System.out.println(requestVO);

        SavePersonPictureResponseVO resp = new SavePersonPictureResponseVO();
        try {
            String mediaId = requestVO.getVxUrl();
            Long basicInfoId = requestVO.getHiringBasicInfoId();
            String imgUrl = this.uploadImageToOss(mediaId, basicInfoId, 2);

            if (imgUrl == null) {
                resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830024")));
            } else {
                AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
                basicInfo.setId(basicInfoId);
                basicInfo.setPersonerPictureOssPath(imgUrl);
                basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

                resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
                resp.setImgUrl(imgUrl);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public SaveIDPictureResponseVO saveIDPicture(SaveIDPictureRequestVO requestVO) {
        SaveIDPictureResponseVO resp = new SaveIDPictureResponseVO();
        try {
            Long basicInfoId = requestVO.getHiringBasicInfoId();
            String frontVxUrl = requestVO.getFrontVxUrl();
            String backVxUrl = requestVO.getBackVxUrl();

            String frontImgUrl = this.uploadImageToOss(frontVxUrl, basicInfoId, 7);
            String backImgUrl = this.uploadImageToOss(backVxUrl, basicInfoId, 8);

            if (frontImgUrl != null && backImgUrl != null) {
                AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
                basicInfo.setId(basicInfoId);
                basicInfo.setIdFrontPageOssPath(frontImgUrl);
                basicInfo.setIdBackPageOssPath(backImgUrl);
                basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

                resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
                resp.setFrontImgUrl(frontImgUrl);
                resp.setBackImgUrl(backImgUrl);
            } else {
                resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830024")));
            }

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public SaveLastGraduateGradeResponseVO saveLastGraduateGrade(SaveLastGraduateGradeRequestVO requestVO) {
        SaveLastGraduateGradeResponseVO resp = new SaveLastGraduateGradeResponseVO();
        try {
            Long basicInfoId = requestVO.getHiringBasicInfoId();
            String code = requestVO.getLastGraduateCode();
            String grade = requestVO.getLastGraduateGrade();
            String school = requestVO.getLastGraduateSchool();
            String vxUrl = requestVO.getCertificationVxUrl();

            String imgUrl = this.uploadImageToOss(vxUrl, basicInfoId, 4);

            if (imgUrl != null) {
                AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
                basicInfo.setId(basicInfoId);
                basicInfo.setLastGraduateCode(code);
                basicInfo.setLastGraduateGrade(grade);
                basicInfo.setLastGraduateSchool(school);
                basicInfo.setLastGraduateCertificationOssPath(imgUrl);
                basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

                resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
                resp.setImgUrl(imgUrl);
            } else {
                resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830024")));
            }

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public CommonResultResponseVO savePersonalStatements(SavePersonalStatementsRequestVO requestVO) {
        CommonResultResponseVO resp = new CommonResultResponseVO();
        try {
            List<AclPractitionerHiringPersonalStatements> personalStatementList = requestVO.getPersonalStatementList();
            Long basicInfoId = requestVO.getHiringBasicInfoId();

            // 判断声明至少要勾选一个
            Boolean flag = false;
            for (AclPractitionerHiringPersonalStatements item :personalStatementList) {
                if (Long.valueOf("1").equals(item.getStatus())) {
                    flag = true;
                }
            }
            if (!flag) {
                resp.setCommonResult(new CommonResult(false, "声明至少要选一项"));
                return resp;
            }

            Date curDate = new Date();
            personalStatementList.forEach(item -> {

                item.setHiringBasicInfoId(basicInfoId);
                item.setIsActive(1);

                item.setCreatedAt(curDate);
                item.setUpdatedAt(curDate);

                item.setCreatedBy((long) -1);
                item.setUpdatedBy((long) -1);

            });

            List<AclPractitionerHiringPersonalStatements> resultList = personalStatementsMapper.selectByHiringBasicInfoId(basicInfoId);
            if (CollectionUtils.isNotEmpty(resultList)) {
                // 先删除
                personalStatementsMapper.deleteBatchByIds(resultList);
            }
            // 插入
            if (personalStatementList.size() > 0) {
                personalStatementsMapper.batchInsert(personalStatementList);
            }

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public CommonResultResponseVO saveContractTermsConfirms(SaveContractTermsConfirmsRequestVO requestVO) {
        CommonResultResponseVO resp = new CommonResultResponseVO();
        try {
            List<AclPractitionerHiringContractTermsConfirms> contractTermsConfirmsList = requestVO.getContractTermsConfirmsList();
            Long basicInfoId = requestVO.getHiringBasicInfoId();

            Date curDate = new Date();
            contractTermsConfirmsList.forEach(item -> {

                item.setHiringBasicInfoId(basicInfoId);
                item.setIsActive(1);

                item.setCreatedAt(curDate);
                item.setUpdatedAt(curDate);

                item.setCreatedBy((long) -1);
                item.setUpdatedBy((long) -1);

            });

            List<AclPractitionerHiringContractTermsConfirms> resultList = contractTermsConfirmsMapper.selectByHiringBasicInfoId(basicInfoId);
            if (CollectionUtils.isNotEmpty(resultList)) {
                contractTermsConfirmsMapper.deleteBatchByIds(resultList);
            }

            if (contractTermsConfirmsList.size() > 0) {
                contractTermsConfirmsMapper.batchInsert(contractTermsConfirmsList);
            }

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public HiringListQueryResponseVO listQuery(HiringListQueryRequestVO requestVO) {
        HiringListQueryResponseVO responseVO = new HiringListQueryResponseVO();

        Long practitionerId = requestVO.getPractitionerId();
        Long approvingStatus = requestVO.getApprovingStatus();

        //等保调整
//        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId,null);
//        if(null == findByObjSortable ){
//            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("630028")));
//            return responseVO;
//        }
        List<HiringListInfo> hiringListInfoList;
        if (Long.valueOf("0").equals(approvingStatus)) {
            // 当前经纪人的待审批记录
            hiringListInfoList = practitionerHiringDalService.queryUnhandledList(practitionerId);
        } else {
            // 当前经纪人通过或拒绝的记录
            int status = Long.valueOf("1").equals(approvingStatus) ? 1 : 0;

            hiringListInfoList = practitionerHiringDalService.queryHandledList(practitionerId, status);
        }

        // 按申请时间倒序排序
        Collections.sort(hiringListInfoList);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        responseVO.setHiringListInfoList(hiringListInfoList);

        return responseVO;
    }

    /**
     * ydLife经纪人审批详情查询接口
     * 基本信息查询同AGMS一致,代码直接copy过来的,以免后期AGMS展示数据与ydLife不一致,修改麻烦
     * 有关"查询是否可进行审批操作"说明
     * 进行到经纪人审批详情查询的经纪人都有权限审批
     * 判断相对AGMS简单,因为一个经纪人审批和辅导员/团队长是一对一,不像AGMS为一对多
     * 所以只要需要判断ag_md_practitioner_hiring_approve_steps是否有practitionerId即可判断是否审批
     * ydLife审批逻辑不可变更,辅导人审批->团队长审批
     */
    @Override
    public HiringDetailQueryResponseVO detailQuery(HiringDetailQueryRequestVO requestVO) {
        HiringDetailQueryResponseVO responseVO = new HiringDetailQueryResponseVO();

        //报聘的经纪人基本资料id
        Long hiringBasicInfoId = requestVO.getHiringBasicInfoId();

        //经纪人审批基本信息
        HiringBasicInfo hiringBasicInfo = practitionerHiringDalService.findHiringBasicInfo(hiringBasicInfoId);
        //审批经纪人关系
        HiringMemberShip hiringMemberShip = practitionerHiringDalService.findHiringMemberShip(hiringBasicInfoId);
        //审批经纪人工作经历
        List<HiringWorkingExperience> hiringWorkingExperienceList = practitionerHiringDalService.findHiringWorkingExperienceList(hiringBasicInfoId);
        //经纪人申请名目
        List<HiringPersonalStatements> hiringPersonalStatementsList = practitionerHiringDalService.findHiringPersonalStatementsList(hiringBasicInfoId);
        //经纪人合同条款是否同意
        List<HiringContractTermsConfirms> hiringContractTermsConfirmsList = practitionerHiringDalService.findHiringContractTermsConfirmsList(hiringBasicInfoId);
        //已审批结果
        List<HiringApproveRecords> hiringApproveRecordsList = practitionerHiringDalService.findHiringApproveRecordsList(hiringBasicInfoId);

        // 审批到哪一步
        Integer nextStepSeq = practitionerHiringDalService.getNextStepSeqByApproveStatus(hiringBasicInfo.getApproveStatus());
        responseVO.setHiringApproveStepsSeq(nextStepSeq);
        responseVO.setHiringBasicInfoId(hiringBasicInfoId);
        responseVO.setHiringBasicInfo(hiringBasicInfo);
        responseVO.setHiringMemberShip(hiringMemberShip);
        responseVO.setHiringWorkingExperienceList(hiringWorkingExperienceList);
        responseVO.setHiringPersonalStatementsList(hiringPersonalStatementsList);
        responseVO.setHiringContractTermsConfirmsList(hiringContractTermsConfirmsList);
        responseVO.setHiringApproveRecordsList(hiringApproveRecordsList);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    private HiringApproveSteps getHiringApproveStatus(Long practitionerId,
                                                      Long approvalIdentity,
                                                      List<HiringApproveRecords> hiringApproveRecordsList) {
        //是否可进行审批操作 0.不可审批(未到)  1.可审批  2.已审批  4.已驳回
        Long hiringApproveStatus = 0L;
        //审批到哪一步了
        Long hiringApproveStepsSeq = null;
        //查看审批流程最后一次,是否通过
        HiringApproveRecords recordsFinally = new HiringApproveRecords();
        if (!hiringApproveRecordsList.isEmpty()) {
            recordsFinally = hiringApproveRecordsList.get(hiringApproveRecordsList.size() - 1);
            Long approvingStatusId = recordsFinally.getApprovingStatusId();
            if (CommonUtil.isNullOrZero(approvingStatusId)) {
                //已驳回
                hiringApproveStatus = 4L;
                return new HiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
            }
        }
        //查看此经纪人是否已经审批
        for (HiringApproveRecords hiringApproveRecords : hiringApproveRecordsList) {
            Long approvingPractitionerId = hiringApproveRecords.getApprovingPractitionerId();
            if (approvingPractitionerId.equals(practitionerId)) {
                //已审批
                hiringApproveStatus = 2L;
                return new HiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
            }
        }
        //余下的仅有0.不可审批(未到)  1.可审批两种状态
        //approvalIdentity的参数意义0.既是辅导人又是团队长  1.辅导人  2.团队长
        //当approvalIdentity为0,1时,审批状态为可审批  当为2时判断辅导人是否审批
        if (approvalIdentity == 0 || approvalIdentity == 1) {
            hiringApproveStatus = 1L;
            hiringApproveStepsSeq = 1L;
        } else {
            //判断辅导人是否审批,仅需判断hiringApproveRecordsList.isEmpty(),因为辅导人是第一步,团队长为第二步
            if (hiringApproveRecordsList.isEmpty()) {
                hiringApproveStatus = 0L;
            } else {
                hiringApproveStatus = 1L;
                hiringApproveStepsSeq = 2L;
            }
        }
        return new HiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
    }

    @Override
    public HiringApproveResponseVO hiringApprove(HiringApproveRequestVO requestVO) {
        HiringApproveResponseVO responseVO = new HiringApproveResponseVO();
        //审批身份 0.既是辅导人又是团队长  1.辅导人  2.团队长
        Long approvalIdentity = requestVO.getApprovalIdentity();
        List<MdPractitionerHiringApproveSteps> hiringApproveStepsList = systemConfigService.findHiringApproveStepsAll();
        List<AclPractitionerHiringApproveRecords> hiringApproveRecordsList = new ArrayList<>();
        //当approvalIdentity=0时需要保存两条记录
        if (approvalIdentity == 0L || approvalIdentity == 1L) {
            boolean hasStepSeq = addStepToList(requestVO, 1, hiringApproveStepsList, hiringApproveRecordsList);
            if (!hasStepSeq) {
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830025")));
                return responseVO;
            }
        }
        if (approvalIdentity == 0L || approvalIdentity == 2L) {
            boolean hasStepSeq = addStepToList(requestVO, 2, hiringApproveStepsList, hiringApproveRecordsList);
            if (!hasStepSeq) {
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830025")));
                return responseVO;
            }
        }
        // 保存审批记录
        aclPractitionerHiringApproveRecordsDalService.save(hiringApproveRecordsList);
        // 更新basicInfo表审批状态
        // 查询审批记录
        Long basicInfoId = requestVO.getHiringBasicInfoId();
        AclPractitionerHiringApproveRecords record = recordsMapper.queryLastOneByBasicInfoId(basicInfoId);

        String approveStatus = null;
        if (Long.valueOf("0").equals(record.getApprovingStatus())) {
            approveStatus = "-1";
        } else {
            String stepSeq = record.getStepSeq();
            if (StringUtils.isEmpty(stepSeq)) {
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830025")));
                return responseVO;
            } else {
                if (stepSeq.equals(hiringApproveStepsList.size())) {
                    approveStatus = "0";
                } else {
                    approveStatus = "-1";
                }
            }
        }
        AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
        basicInfo.setId(requestVO.getHiringBasicInfoId());
        basicInfo.setApproveStatus(approveStatus);
        basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

        responseVO.setPractitionerId(requestVO.getPractitionerId());
        responseVO.setHiringBasicInfoId(requestVO.getHiringBasicInfoId());
        responseVO.setApprovalIdentity(requestVO.getApprovalIdentity());
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public CommonResultResponseVO saveBankAccount(SaveBankAccountRequestVO requestVO) {
        CommonResultResponseVO resp = new CommonResultResponseVO();
        String bankAccountOpening = requestVO.getBankAccountOpening();
        String bankAccountId = requestVO.getBankAccountId();
        if (StringUtils.isEmpty(bankAccountOpening) || StringUtils.isEmpty(bankAccountId)) {
            resp.setCommonResult(new CommonResult(false, "开户行或银行卡号不能为空"));
            return resp;
        }

        try {
            AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
            BeanUtils.copyProperties(requestVO, basicInfo);
            basicInfo.setId(requestVO.getHiringBasicInfoId());
            basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public QueryContractTermsResponseVO queryContractTerms() {
        QueryContractTermsResponseVO resp = new QueryContractTermsResponseVO();
        try {
            List<PractitionerHiringContractTerms> contractTermsList = practitionerHiringDalService.queryContractTerms();

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            resp.setContractTermsList(contractTermsList);

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public QueryWholeInfoResponseVO queryWholeInfo(HiringBasicInfoIdRequestVO requestVO) {
        QueryWholeInfoResponseVO resp = new QueryWholeInfoResponseVO();
        try {
            //报聘的经纪人基本资料id
            Long hiringBasicInfoId = requestVO.getHiringBasicInfoId();
            //基本信息
            AclPractitionerHiringBasicInfo hiringBasicInfo = basicInfoMapper.selectByPrimaryKey(hiringBasicInfoId);
            //组织关系
            AclPractitionerHiringMembership hiringMemberShip = this.queryHiringMemberShip(hiringBasicInfoId);
            //工作经历
            List<AclPractitionerHiringWorkingExperience> hiringWorkingExperienceList = workingExperienceMapper.selectByHiringBasicInfoId(hiringBasicInfoId);
            //申请名目
            List<AclPractitionerHiringPersonalStatements> hiringPersonalStatementsList = personalStatementsMapper.selectByHiringBasicInfoId(hiringBasicInfoId);
            //合同条款是否同意
            List<AclPractitionerHiringContractTermsConfirms> hiringContractTermsConfirmsList = contractTermsConfirmsMapper.selectByHiringBasicInfoId(hiringBasicInfoId);

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            if (null != hiringBasicInfo.getPractitionerPotentialId()) {
                AclPractitionerPotential aclPractitionerPotential = aclPractitionerPotentialMapper.selectByPrimaryKey(hiringBasicInfo.getPractitionerPotentialId());
                resp.setCustomerId(null != aclPractitionerPotential ? aclPractitionerPotential.getCustomerId() : null);
            }
            resp.setHiringBasicInfoId(hiringBasicInfoId);
            resp.setHiringBasicInfo(hiringBasicInfo);
            resp.setHiringMemberShip(hiringMemberShip);
            resp.setHiringWorkingExperienceList(hiringWorkingExperienceList);
            resp.setHiringPersonalStatementsList(hiringPersonalStatementsList);
            resp.setHiringContractTermsConfirmsList(hiringContractTermsConfirmsList);

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private AclPractitionerHiringMembership queryHiringMemberShip(Long hiringBasicInfoId) {
        AclPractitionerHiringMembership hiringMemberShip = membershipMapper.selectByHiringBasicInfoId(hiringBasicInfoId);
        if (hiringMemberShip.getMentorPractitionerId() == null) {
            return hiringMemberShip;
        }
        AclPractitioner mentor = aclPractitionerDALService.findPractitionerById(hiringMemberShip.getMentorPractitionerId());

        // 查询并显示“辅导人”所属的S1分部，分部负责人，S2体系，体系负责人，S3纵队，纵队负责人，没有的显示空
        List<AclPractitionerSubordinateSystem> subordinateSystemList = aclPractitionerSubordinateSystemDALService.findAll();
        Map<Long, AclPractitionerSubordinateSystem> subordinateSystemMap = new HashMap<>();
        subordinateSystemList.forEach(i -> subordinateSystemMap.put(i.getId(), i));

        Map<Long, AclPractitioner> aclPractitionerMap = aclPractitionerDALService.findAllMap();
        //所属体系
        AclPractitionerSubordinateSystem subordinateSystem = null;
        //体系团队长
        AclPractitioner systemOwner = null;

        if (mentor.getS1Id() != null) {
            subordinateSystem = subordinateSystemMap.get(mentor.getS1Id());
            if (subordinateSystem != null) {
                hiringMemberShip.setS1SubordinateSystemName(subordinateSystem.getName());

                systemOwner = aclPractitionerMap.get(subordinateSystem.getOwnerPractitionerId());
                hiringMemberShip.setS1TeamLeaderName(systemOwner != null ? systemOwner.getName() : null);
                hiringMemberShip.setS1TeamLeaderId(systemOwner != null ? systemOwner.getId() : null);
            }
        }

        if (null != mentor.getS2Id()) {
            subordinateSystem = subordinateSystemMap.get(mentor.getS2Id());
            if (subordinateSystem != null) {
                hiringMemberShip.setS2SubordinateSystemName(subordinateSystem != null ? subordinateSystem.getName() : null);

                systemOwner = aclPractitionerMap.get(subordinateSystem.getOwnerPractitionerId());
                hiringMemberShip.setS2TeamLeaderName(systemOwner != null ? systemOwner.getName() : null);
                hiringMemberShip.setS2TeamLeaderId(systemOwner != null ? systemOwner.getId() : null);
            }
        }
        if (null != mentor.getS3Id()) {
            subordinateSystem = subordinateSystemMap.get(mentor.getS3Id());
            if (subordinateSystem != null) {
                hiringMemberShip.setS3SubordinateSystemName(subordinateSystem != null ? subordinateSystem.getName() : null);

                systemOwner = aclPractitionerMap.get(subordinateSystem.getOwnerPractitionerId());
                hiringMemberShip.setS3TeamLeaderName(systemOwner != null ? systemOwner.getName() : null);
                hiringMemberShip.setS3TeamLeaderId(systemOwner != null ? systemOwner.getId() : null);
            }
        }

        return hiringMemberShip;
    }

    @Override
    public CommonResultResponseVO saveDigitalSignatures(SaveDigitalSignaturesRequestVO requestVO) {
        CommonResultResponseVO resp = new CommonResultResponseVO();
        Long basicInfoId = requestVO.getHiringBasicInfoId();
        String imgStr = requestVO.getImgStr();
        try {
            if (StringUtils.isBlank(imgStr)) {
                resp.setCommonResult(new CommonResult(false, "file不可为空"));
                return resp;
            }
            if (imgStr.indexOf("data:image/png;") != -1) {
                imgStr = imgStr.replace("data:image/png;base64,", "");
            }

            byte[] fileBytes = Base64.getDecoder().decode(imgStr);
            InputStream inputStream = new ByteArrayInputStream(fileBytes);

            // 上传图片至阿里云
            StringBuffer fileName = new StringBuffer();
            fileName.append("brokerHiring/").append(basicInfoId).append("/");
            String originalFilename = generateKey(9);
            String key = fileName.append(originalFilename).append(".png").toString();
            String putFileToOss = ossService.putFileToOss(null, key, inputStream);

            // 保存入库
            AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
            basicInfo.setId(basicInfoId);
            basicInfo.setPersonalSignOssPath(putFileToOss);
            basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, "保存失败"));
        }
        return resp;
    }

    @Override
    public SavePayrollPictureResponseVO savePayrollPicture(SavePayRollPictureRequestVO requestVO) {
        SavePayrollPictureResponseVO resp = new SavePayrollPictureResponseVO();
        try {
            String mediaId = requestVO.getVxUrl();
            if (StringUtils.isEmpty(mediaId)) {
                resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
                return resp;
            }

            Long basicInfoId = requestVO.getHiringBasicInfoId();
            String imgUrl = this.uploadImageToOss(mediaId, basicInfoId, 9);

            if (imgUrl == null) {
                resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830024")));
            } else {
                AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
                basicInfo.setId(basicInfoId);
                basicInfo.setPayrollOssPath(imgUrl);
                basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

                resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
                resp.setImgUrl(imgUrl);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public GeneratePDFResponseVO generatePDF(GeneratePDFRequestVO requestVO) {
        GeneratePDFResponseVO resp = new GeneratePDFResponseVO();
        try {
            Long hiringBasicInfoId = requestVO.getHiringBasicInfoId();
            Long practitionerId = requestVO.getPractitionerId();
            if (hiringBasicInfoId == null) {
                resp.setCommonResult(new CommonResult(false, "此经纪人无电子合同"));
                return resp;
            }

            AclPractitioner practitioner = aclPractitionerMapper.selectByPrimaryKey(practitionerId);
            String practitionerCode = practitioner == null ? null : practitioner.getPractitionerCode().trim();
            String practitionerRegNo = practitioner == null ? null : practitioner.getPractitionerRegNo();

            if (StringUtils.isBlank(practitionerRegNo)) {
                resp.setCommonResult(new CommonResult(false, "执业编号不能为空，请保存后再生成合同"));
                return resp;
            }
            if (StringUtils.isBlank(practitionerCode)) {
                resp.setCommonResult(new CommonResult(false, "内部编号不能为空，请保存后再生成合同"));
                return resp;
            }

            // 合同编号已存在就不生成新的
            String contractNo = practitioner.getContractNo();

            if (StringUtils.isEmpty(contractNo)) {
                contractNo = hiringContractService.getNextContractNo();
                practitioner.setContractNo(contractNo);
            }
            String contractOssPath = hiringContractService.generatePractitionerContract(practitioner);

            //4、经纪人表生成经纪人记录ag_acl_practitioner，ag_acl_practitioner.contract_oss_path
            //   经纪人经纪人类型级别定义表ag_acl_practitioner_setting
            AclPractitioner updateObj = new AclPractitioner();
            updateObj.setId(practitionerId);
            updateObj.setContractNo(contractNo);
            updateObj.setContractOssPath(contractOssPath);
            aclPractitionerMapper.updateByPrimaryKeySelective(updateObj);

            //合同生成后，发短信通知报聘人，辅导人，团队长
            this.sendMsgAfterPDF(hiringBasicInfoId);

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            resp.setContractOssPath(contractOssPath);

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private void sendMsgAfterPDF(Long hiringBasicInfoId) {
        AclPractitionerHiringBasicInfo basicInfo = basicInfoMapper.selectByPrimaryKey(hiringBasicInfoId);
        AclPractitionerHiringMembership memberShip = membershipMapper.selectByHiringBasicInfoId(hiringBasicInfoId);

        List<String> mobileNoList = new ArrayList<>(3);
        mobileNoList.add(basicInfo.getMobileNo());

        String name = basicInfo.getName();
        Map<String,List<String>> smsParam = new HashMap<>();
        List<String> list = new ArrayList<>();
        list.add(systemConfigService.getSingleConfigValue("ALI_SMS_CONTRACT_3"));
        list.add("{\"name\":\""+name+"\"}");
        smsParam.put(basicInfo.getMobileNo(), list);

        if (memberShip.getMentorPractitionerId() != null) {
            AclPractitioner mentor = aclPractitionerMapper.selectByPrimaryKey(memberShip.getMentorPractitionerId());
            mobileNoList.add(mentor.getMobileNo());
        }

        if (memberShip.getApprovedBy() != null) {
            AclPractitioner system = aclPractitionerMapper.selectByPrimaryKey(memberShip.getApprovedBy());
            mobileNoList.add(system.getMobileNo());
        }
        // 若辅导人和团队长为同一人，去重
        List<String> uniqueList = mobileNoList.stream().distinct().collect(Collectors.toList());

        String system = memberShip.getSubsystem();
        String mobileNo;
        String templateCode;
        String content;
        // S2的短信模板
        if (Long.valueOf("30").equals(memberShip.getMdDropOptionId())) {
            /* 短信提醒 */
            templateCode = systemConfigService.getSingleConfigValue("ALI_SMS_CONTRACT_S2");
            content = "{\"name\":\""+name+"\"}";

        } else {
            /* 短信提醒 */
            templateCode = systemConfigService.getSingleConfigValue("ALI_SMS_CONTRACT");
            content = "{\"system\":\""+system+"\",\"name\":\""+name+"\"}";
        }
        for (int i = 0; i < uniqueList.size(); i++) {

            mobileNo = uniqueList.get(i);
            if(smsParam.get(mobileNo) != null && smsParam.get(mobileNo).size() > 1){
                templateCode = smsParam.get(mobileNo).get(0);
                content = smsParam.get(mobileNo).get(1);
            }
            sendService.sendEmailOrSMS("sms", mobileNo, "0", content, templateCode, null, null, "电子报聘合同生成提醒", 99, hiringBasicInfoId);

        }
    }

    @Override
    public QueryPractitionerInfoResponseVO queryPractitionerInfo(QueryPractitionerInfoRequestVO requestVO) {
        QueryPractitionerInfoResponseVO resp = new QueryPractitionerInfoResponseVO();
        try {
            Long practitionerId = requestVO.getPractitionerId();

            if (practitionerId == null) {
                resp.setCommonResult(new CommonResult(false, "practitionerId不能为空"));
            } else {
                //等保调整
                List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId,null);
                if(null == findByObjSortable ){
                    resp.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("630028")));
                    return resp;
                }
                AclPractitioner practitioner = aclPractitionerMapper.selectByPrimaryKey(practitionerId);

                resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
                resp.setPractitioner(practitioner);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public CommonResultResponseVO hiringSubmit(HiringBasicInfoIdRequestVO requestVO) {
        CommonResultResponseVO resp = new CommonResultResponseVO();
        Long basicInfoId = requestVO.getHiringBasicInfoId();
        try {
            AclPractitionerHiringBasicInfo basicInfo = new AclPractitionerHiringBasicInfo();
            basicInfo.setId(basicInfoId);
            AclPractitionerHiringMembership hiringMemberShip = membershipMapper.selectByHiringBasicInfoId(basicInfoId);

            if (basicInfoId == null || hiringMemberShip == null) {
                resp.setCommonResult(new CommonResult(false, "保存失败"));
                return resp;
            }
            // 计算审批流程
            basicInfo.setApproveStatus(this.handleApproveStatus(hiringMemberShip));
            // 将申请人分配给体系负责人
            this.distributeToSubsystemOwner(hiringMemberShip);

            basicInfoMapper.updateByPrimaryKeySelective(basicInfo);

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, "保存失败"));
        }
        return resp;
    }

    private void distributeToSubsystemOwner(AclPractitionerHiringMembership memberShip) {
        Long hiringBasicInfoId = memberShip.getHiringBasicInfoId();
        String mdDropOptionName = memberShip.getMdDropOptionName();
        // S2,S3报聘不用团队长审批
        if (mdDropOptionName.indexOf("S2")>=0 || mdDropOptionName.indexOf("S3")>=0) {
            return;
        }
        // 查询辅导人所在S1,S2,S3
        AclPractitionerHiringMembership hiringMemberShip = this.queryHiringMemberShip(hiringBasicInfoId);

        Long s1TeamLeaderId = hiringMemberShip.getS1TeamLeaderId();
        Long s2TeamLeaderId = hiringMemberShip.getS2TeamLeaderId();
        Long s3TeamLeaderId = hiringMemberShip.getS3TeamLeaderId();

        Long approvedBy = hiringMemberShip.getSubsystemOwnerId();
        if (s2TeamLeaderId != null) {
            approvedBy = s2TeamLeaderId;
        } else {
            if (s1TeamLeaderId != null) {
                approvedBy = s1TeamLeaderId;
            } else {
                approvedBy = s3TeamLeaderId;
            }
        }
        // 保存审批的负责人
        hiringMemberShip.setApprovedBy(approvedBy);
        membershipMapper.updateByPrimaryKeySelective(hiringMemberShip);
    }

    private String handleApproveStatus(AclPractitionerHiringMembership hiringMemberShip) {
        // 经纪人报聘职级
        String mdDropOptionName = hiringMemberShip.getMdDropOptionName();
        if (mdDropOptionName.indexOf("S2")>=0 || mdDropOptionName.indexOf("S3")>=0) {
            return "2";
        }
        if (hiringMemberShip.getMentor() == null || hiringMemberShip.getMentorPractitionerId() == null) {
            return "2";
        }
        return "-2";
    }

    @SuppressWarnings("unchecked")
    private boolean addStepToList(HiringApproveRequestVO requestVO,
                                  int stepSeq,
                                  List<MdPractitionerHiringApproveSteps> hiringApproveStepsList,
                                  List<AclPractitionerHiringApproveRecords> hiringApproveRecordsList) {
        BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("stepSeq", stepSeq);
        List<MdPractitionerHiringApproveSteps> steps = (List<MdPractitionerHiringApproveSteps>) CollectionUtils.select(hiringApproveStepsList, predicate);
        if (steps.size() != 1) {
            return false;
        }
        AclPractitionerHiringApproveRecords records = new AclPractitionerHiringApproveRecords();
        MdPractitionerHiringApproveSteps step = steps.get(0);
        records.setHiringBasicInfoId(requestVO.getHiringBasicInfoId());
        records.setApproveStepId(step.getId().toString());
        records.setApproveStepName(step.getStepName());
        records.setApprovingPractitionerId(requestVO.getPractitionerId());
        records.setApprovingStatus(requestVO.getApprovingStatus());
        records.setInterviewAssessment(requestVO.getInterviewAssessment());
        records.setRejectNote(requestVO.getRejectNote());
        records.setIsActive(1);
        records.setCreatedAt(new Date());
        records.setCreatedBy(requestVO.getPractitionerId());
        records.setUpdatedAt(new Date());
        records.setUpdatedBy(requestVO.getPractitionerId());
        hiringApproveRecordsList.add(records);
        return true;
    }

    private String uploadImageToOss(String imgUrl, Long hiringBasicInfoId, Integer targetUseFor) throws Exception {
        Map<String, Object> input = HttpUtil.getInput(imgUrl);
        if (!(boolean) input.get("success")) {
            throw new Exception(ZHBErrorConfig.getErrorInfo("830024"));
        }
        //获取头像流
        InputStream inputStream = (InputStream) input.get("is");
        //判断图像尺寸
        BufferedImage img = ImageIO.read(inputStream);

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(img, "jpg", os);
        inputStream = new ByteArrayInputStream(os.toByteArray());

        //上传图片至阿里云
        String prefix = "brokerHiring/" + hiringBasicInfoId + "/";
        String originalFilename = generateKey(targetUseFor);
        String key = prefix + originalFilename + ".jpg";
        String putFileToOss = ossService.putFileToOss(null, key, inputStream);

        return putFileToOss;
    }

    private String generateKey(int targetUseFor) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        return targetUseFor + sdf.format(new Date());
    }

}
