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

import com.github.pagehelper.PageInfo;
import com.yd.api.agms.service.AgmsHiringService;
import com.yd.api.agms.vo.hiring.*;
import com.yd.api.result.CommonResult;
import com.yd.dal.entity.agms.hiring.*;
import com.yd.dal.entity.customer.*;
import com.yd.dal.entity.meta.MdPractitionerHiringApproveSteps;
import com.yd.dal.entity.user.AclUser;
import com.yd.dal.service.agms.AgmsHiringDALService;
import com.yd.dal.service.customer.*;
import com.yd.dal.service.meta.MdPractitionerHiringApproveStepsDALService;
import com.yd.dal.service.user.AclUserDALService;
import com.yd.rmi.cache.SystemConfigService;
import com.yd.util.CommonUtil;
import com.yd.util.config.ZHBErrorConfig;
import org.apache.commons.beanutils.BeanPropertyValueEqualsPredicate;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author xxy
 */
@Service("agmsHiringService")
public class AgmsHiringServiceImpl implements AgmsHiringService {

    private AgmsHiringDALService agmsHiringDalService;
    private SystemConfigService systemConfigService;
    private AclUserDALService aclUserDalService;
    private MdPractitionerHiringApproveStepsDALService mdPractitionerHiringApproveStepsDalService;
    private AclPractitionerHiringApproveRecordsDALService aclPractitionerHiringApproveRecordsDalService;
    private AclPractitionerDALService aclPractitionerDalService;
    private AclPractitionerSettingDALService aclPractitionerSettingDalService;
    private AclPractitionerHiringBasicInfoDALService aclPractitionerHiringBasicInfoDalService;
    private AclPractitionerHiringMembershipDALService aclPractitionerHiringMembershipDalService;
    private AclPractitionerSubordinateSystemDALService aclPractitionerSubordinateSystemDalService;
    private AclCustomerDALService aclCustomerDalService;
    @Autowired
    public void setAgmsHiringDalService(AgmsHiringDALService agmsHiringDalService){
        this.agmsHiringDalService = agmsHiringDalService;
    }
    @Autowired
    public void setSystemConfigService(SystemConfigService systemConfigService) {
        this.systemConfigService = systemConfigService;
    }
    @Autowired
    public void setMdPractitionerHiringApproveStepsDalService(MdPractitionerHiringApproveStepsDALService mdPractitionerHiringApproveStepsDalService) {
        this.mdPractitionerHiringApproveStepsDalService = mdPractitionerHiringApproveStepsDalService;
    }

    @Autowired
    public void setAclUserDalService(AclUserDALService aclUserDalService) {
        this.aclUserDalService = aclUserDalService;
    }

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

    @Autowired
    public void setAclPractitionerDalService(AclPractitionerDALService aclPractitionerDalService) {
        this.aclPractitionerDalService = aclPractitionerDalService;
    }

    @Autowired
    public void setAclPractitionerSettingDalService(AclPractitionerSettingDALService aclPractitionerSettingDalService) {
        this.aclPractitionerSettingDalService = aclPractitionerSettingDalService;
    }

    @Autowired
    public void setAclPractitionerHiringBasicInfoDalService(AclPractitionerHiringBasicInfoDALService aclPractitionerHiringBasicInfoDalService) {
        this.aclPractitionerHiringBasicInfoDalService = aclPractitionerHiringBasicInfoDalService;
    }

    @Autowired
    public void setAclPractitionerHiringMembershipDalService(AclPractitionerHiringMembershipDALService aclPractitionerHiringMembershipDalService) {
        this.aclPractitionerHiringMembershipDalService = aclPractitionerHiringMembershipDalService;
    }

    @Autowired
    public void setAclPractitionerSubordinateSystemDalService(AclPractitionerSubordinateSystemDALService aclPractitionerSubordinateSystemDalService) {
        this.aclPractitionerSubordinateSystemDalService = aclPractitionerSubordinateSystemDalService;
    }

    @Autowired
    public void setAclCustomerDalService(AclCustomerDALService aclCustomerDalService) {
        this.aclCustomerDalService = aclCustomerDalService;
    }

    @Override
    public PractitionerHiringDetailResponseVO practitionerHiringDetail(PractitionerHiringDetailRequestVO requestVO) {
        PractitionerHiringDetailResponseVO responseVO = new PractitionerHiringDetailResponseVO();

        Long hiringBasicInfoId = requestVO.getHiringBasicInfoId();
        Long loginId = requestVO.getLoginId();
        //经纪人审批基本信息
        PractitionerHiringBasicInfo practitionerHiringBasicInfo = agmsHiringDalService.findPractitionerHiringBasicInfo(hiringBasicInfoId);
        //审批经纪人关系
        PractitionerHiringMemberShip practitionerHiringMemberShip = agmsHiringDalService.findPractitionerHiringMemberShip(hiringBasicInfoId);
        //审批经纪人工作经历
        List<PractitionerHiringWorkingExperience> practitionerHiringWorkingExperienceList = agmsHiringDalService.findPractitionerHiringWorkingExperienceList(hiringBasicInfoId);
        //经纪人申请名目
        List<PractitionerHiringPersonalStatements> practitionerHiringPersonalStatementsList = agmsHiringDalService.findPractitionerHiringPersonalStatementsList(hiringBasicInfoId);
        //经纪人合同条款是否同意
        List<PractitionerHiringContractTermsConfirms> practitionerHiringContractTermsConfirmsList = agmsHiringDalService.findPractitionerHiringContractTermsConfirmsList(hiringBasicInfoId);
        //已审批结果
        List<PractitionerHiringApproveRecords> practitionerHiringApproveRecordsList = agmsHiringDalService.findPractitionerHiringApproveRecordsList(hiringBasicInfoId);
        //查询是否可进行审批操作 0.不可审批(未到)  1.可审批  2.已审批  3.无权审批(默认)  4.已驳回
        PractitionerHiringApproveSteps practitionerHiringApproveSteps = getHiringApproveStatus(loginId,practitionerHiringMemberShip.getPractitionerLevelId(),practitionerHiringApproveRecordsList);
        responseVO.setHiringBasicInfoId(hiringBasicInfoId);
        responseVO.setPractitionerHiringApproveSteps(practitionerHiringApproveSteps);
        responseVO.setPractitionerHiringBasicInfo(practitionerHiringBasicInfo);
        responseVO.setPractitionerHiringMemberShip(practitionerHiringMemberShip);
        responseVO.setPractitionerHiringWorkingExperienceList(practitionerHiringWorkingExperienceList);
        responseVO.setPractitionerHiringPersonalStatementsList(practitionerHiringPersonalStatementsList);
        responseVO.setPractitionerHiringContractTermsConfirmsList(practitionerHiringContractTermsConfirmsList);
        responseVO.setPractitionerHiringApproveRecordsList(practitionerHiringApproveRecordsList);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public PractitionerHiringListResponseVO practitionerHiringList(PractitionerHiringListRequestVO requestVO) {
        PractitionerHiringListResponseVO responseVO = new PractitionerHiringListResponseVO();
        PageInfo<PractitionerHiringListInfo> hiringListInfoPageInfo = agmsHiringDalService.practitionerHiringList(requestVO);
        responseVO.setPractitionerHiringList(hiringListInfoPageInfo);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public PractitionerHiringApproveResponseVO practitionerHiringApprove(PractitionerHiringApproveRequestVO requestVO) {
        PractitionerHiringApproveResponseVO responseVO = new PractitionerHiringApproveResponseVO();
        Long loginId = requestVO.getLoginId();
        Long hiringBasicInfoId = requestVO.getHiringBasicInfoId();
        Integer hiringApproveStepsSeq = requestVO.getHiringApproveStepsSeq();
        //通过loginId查询此登入者的经纪人id
        Long loginPractitionerId = agmsHiringDalService.findPractitionerIdByLoginId(loginId);
        AclUser user = aclUserDalService.selectByPrimaryKey(loginId);
        //查询此人的审批流程
        PractitionerHiringMemberShip practitionerHiringMemberShip = agmsHiringDalService.findPractitionerHiringMemberShip(hiringBasicInfoId);
        List<MdPractitionerHiringApproveSteps> hiringApproveStepsList = systemConfigService.findHiringApproveStepsByPractitionerLevel(practitionerHiringMemberShip.getPractitionerLevelId());
        //保存审批结果
        saveRecords(loginPractitionerId,user.getMobileNo(), hiringApproveStepsList, requestVO, responseVO);
        if (responseVO.getCommonResult().isSuccess()){
            return responseVO;
        }
        //保存完毕,判断是否为最后一步
        MdPractitionerHiringApproveSteps listStep = hiringApproveStepsList.get(hiringApproveStepsList.size() - 1);
        Integer stepSeq = listStep.getStepSeq();
        if (stepSeq.equals(hiringApproveStepsSeq)) {
            Long approvingStatus = requestVO.getApprovingStatus();
            if (approvingStatus == 1) {
                //最后一步 并同意 更新经纪人系类表
                updatePractitionerInfo(hiringBasicInfoId,loginId);
            }
        }
        responseVO.setHiringBasicInfoId(hiringBasicInfoId);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @SuppressWarnings("unchecked")
    private void saveRecords(Long loginPractitionerId,
                             String mobileNo, List<MdPractitionerHiringApproveSteps> hiringApproveStepsList,
                             PractitionerHiringApproveRequestVO requestVO,
                             PractitionerHiringApproveResponseVO responseVO) {
        BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("stepSeq",requestVO.getHiringApproveStepsSeq());
        List<MdPractitionerHiringApproveSteps> steps = (List<MdPractitionerHiringApproveSteps>) CollectionUtils.select(hiringApproveStepsList,predicate);
        if (steps.size() != 1){
            responseVO.setHiringBasicInfoId(requestVO.getHiringBasicInfoId());
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830025")));
            return;
        }
        AclPractitionerHiringApproveRecords records = new AclPractitionerHiringApproveRecords();
        MdPractitionerHiringApproveSteps step = steps.get(0);
        records.setHiringBasicInfoId(requestVO.getHiringBasicInfoId());
        records.setApproveStepId(step.getId().toString());
        records.setApproveStepName(step.getStepName());
        records.setApprovingPractitionerId(loginPractitionerId);
        records.setApprovingStatus(requestVO.getApprovingStatus());
        records.setRejectNote(requestVO.getRejectNote());
        records.setIsActive(1);
        records.setCreatedAt(new Date());
        records.setCreatedBy(loginPractitionerId);
        records.setUpdatedAt(new Date());
        records.setUpdatedBy(loginPractitionerId);
        aclPractitionerHiringApproveRecordsDalService.save(records);
        if (CommonUtil.isNullOrZero(requestVO.getApprovingStatus())){
            responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            return;
        }
        //判断下一个步骤是不是他
        Long id = step.getId();
        MdPractitionerHiringApproveSteps lastStep = hiringApproveStepsList.get(hiringApproveStepsList.size() - 1);
        Long lastStepId = lastStep.getId();
        //这是最后一个步骤
        if (id.equals(lastStepId)){
            responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            return;
        }
        //下一个步骤
        MdPractitionerHiringApproveSteps nextStop = new MdPractitionerHiringApproveSteps();
        for (int i = 0;i< hiringApproveStepsList.size();i++){
            MdPractitionerHiringApproveSteps stop = hiringApproveStepsList.get(i);
            Long stopId = stop.getId();
            if (id.equals(stopId)){
                nextStop = hiringApproveStepsList.get(i+1);
                break;
            }
        }
        String appointedApprovePractitioners = nextStop.getAppointedApprovePractitioners();
        List<String> hiringApproveMobileNos = new ArrayList<>(Arrays.asList(appointedApprovePractitioners.split(",")));
        //不是他
        if (!hiringApproveMobileNos.contains(mobileNo)) {
            responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            return;
        }
        requestVO.setHiringApproveStepsSeq(nextStop.getStepSeq());
        saveRecords(loginPractitionerId,mobileNo,hiringApproveStepsList,requestVO,responseVO);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
    }

    private void updatePractitionerInfo(Long hiringBasicInfoId,Long loginId) {
        //更新经纪人系类表
        //ag_acl_practitioner
        //ag_acl_practitioner_setting
        //ag_acl_practitioner_subordinate_system(如果是团队长)
        AclPractitionerHiringBasicInfo basicInfo = aclPractitionerHiringBasicInfoDalService.findById(hiringBasicInfoId);
        AclPractitionerHiringMembership membership = aclPractitionerHiringMembershipDalService.findByBasicInfoId(hiringBasicInfoId);
        AclPractitionerSubordinateSystem subordinateSystem = aclPractitionerSubordinateSystemDalService.findById(membership.getSubsystemId());
        AclCustomer customer = aclCustomerDalService.findByMobileNo(basicInfo.getMobileNo());
        AclPractitioner practitioner = new AclPractitioner();
        practitioner.setInsurerId(888L);
        practitioner.setInsurerBranchId(membership.getBranchId());
        practitioner.setDeptId(subordinateSystem.getDeptId());
        practitioner.setSubordinateSystemId(membership.getSubsystemId());
        practitioner.setPractitionerCode(" ");
        practitioner.setName(basicInfo.getName());
        practitioner.setMobileNo(basicInfo.getMobileNo());
        practitioner.setIdTypeId(basicInfo.getIdTypeId());
        practitioner.setIdType(basicInfo.getIdType());
        practitioner.setIdNo(basicInfo.getIdNo());
        practitioner.setPractitionerBirthdate(basicInfo.getPractitionerBirthdate());
        practitioner.setPractitionerRegNo(" ");
        practitioner.setPractitionerRegCompany(" ");
        practitioner.setCustomerId(customer.getId());
        practitioner.setIsActive(1);
        practitioner.setCreatedAt(new Date());
        practitioner.setCreatedBy(loginId);
        practitioner.setUpdatedAt(new Date());
        practitioner.setUpdatedBy(loginId);
        practitioner.setProvinceId(basicInfo.getProvinceId());
        practitioner.setProvinceName(basicInfo.getProvinceName());
        practitioner.setCityId(basicInfo.getCityId());
        practitioner.setCityName(basicInfo.getCityName());
        practitioner.setWechatId(basicInfo.getWechatId());
        practitioner.setIsProfileShow(0);
        practitioner.setIsNameShow(0);
        practitioner.setIsMobileShow(0);
        practitioner.setEducationLevel(basicInfo.getLastGraduateGrade());
        practitioner.setMentorId(membership.getMentorPractitionerId());
        practitioner.setIntroducerId(membership.getIntroducerPractitionerId());
        practitioner.setGender(basicInfo.getGender());
        aclPractitionerDalService.save(practitioner);

        AclPractitionerSetting setting = new AclPractitionerSetting();
        setting.setPractitionerId(practitioner.getId());
        setting.setPractitionerTypeId(28L);
        setting.setPractitionerLevel(membership.getMdDropOptionId());
        setting.setIsActive(1);
        setting.setCreatedAt(new Date());
        setting.setCreatedBy(loginId);
        setting.setUpdatedAt(new Date());
        setting.setUpdatedBy(loginId);
        aclPractitionerSettingDalService.save(setting);
    }

    private PractitionerHiringApproveSteps getHiringApproveStatus(Long loginId, String practitionerLevelId, List<PractitionerHiringApproveRecords> practitionerHiringApproveRecordsList) {
        //是否可进行审批操作 0.不可审批(未到)  1.可审批  2.已审批  3.无权审批(默认) 4.已驳回
        Long hiringApproveStatus = 3L;
        //审批到哪一步了
        Long hiringApproveStepsSeq = null;
        //查看审批流程最后一次,是否通过
        PractitionerHiringApproveRecords recordsFinally = new PractitionerHiringApproveRecords();
        if (!practitionerHiringApproveRecordsList.isEmpty()) {
            recordsFinally = practitionerHiringApproveRecordsList.get(practitionerHiringApproveRecordsList.size() - 1);
            Long approvingStatusId = recordsFinally.getApprovingStatusId();
            if (CommonUtil.isNullOrZero(approvingStatusId)) {
                //已驳回
                hiringApproveStatus = 4L;
                return new PractitionerHiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
            }
        }

        //通过loginId查询对应的经纪人id
        Long loginPractitionerId = agmsHiringDalService.findPractitionerIdByLoginId(loginId);
        //AGMS登入者手机号不是经纪人手机号,无权审批
        if (!CommonUtil.isNullOrZero(loginPractitionerId)) {
            return new PractitionerHiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
        }
        //遍历已审批结果,查看此agms登入者是否已审批
        for (PractitionerHiringApproveRecords practitionerHiringApproveRecords : practitionerHiringApproveRecordsList) {
            Long approvingPractitionerId = practitionerHiringApproveRecords.getApprovingPractitionerId();
            if (approvingPractitionerId.equals(loginPractitionerId)) {
                //已审批
                hiringApproveStatus = 2L;
                return new PractitionerHiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
            }
        }
        //查询审批流程
        List<MdPractitionerHiringApproveSteps> hiringApproveSteps = systemConfigService.findHiringApproveStepsByPractitionerLevel(practitionerLevelId);
        //通过loginId查询登入者手机号码
        AclUser user = aclUserDalService.selectByPrimaryKey(loginId);
        String loginMobileNo = user.getMobileNo();
        //所有通过agms审批的手机号码
        List<String> hiringApproveMobileNo = systemConfigService.findHiringApproveMobileNo(hiringApproveSteps, practitionerLevelId);
        //agms登入者无审批权力
        if (!hiringApproveMobileNo.contains(loginMobileNo)) {
            return new PractitionerHiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
        }
        //此经纪人最后一次审批步骤id
        hiringApproveStepsSeq = recordsFinally.getApproveStepId();
        //查询此经纪人最后一次审批步骤详细信息
        Long stepId = 0L;
        for (int i = 0; i < hiringApproveSteps.size(); i++) {
            Long id = hiringApproveSteps.get(i).getId();
            if (id.equals(hiringApproveStepsSeq)) {
                stepId = id;
                break;
            }
        }
        MdPractitionerHiringApproveSteps mdPractitionerHiringApproveSteps = hiringApproveSteps.get(Integer.parseInt(stepId.toString()));
        //通过手机号码查询此agmd登入者拥有哪些审批步骤(肯定有值)
        List<MdPractitionerHiringApproveSteps> hiringApproves = mdPractitionerHiringApproveStepsDalService.findByAppointedApprovePractitioners(loginMobileNo);
        //最后一个审批步骤的seq
        Integer stepSeq = mdPractitionerHiringApproveSteps.getStepSeq() == null ? 0 : mdPractitionerHiringApproveSteps.getStepSeq();
        MdPractitionerHiringApproveSteps loginHiringApproveStep = null;
        for (MdPractitionerHiringApproveSteps hiringApprove : hiringApproves) {
            Integer loginStepSeq = hiringApprove.getStepSeq();
            if (stepSeq < loginStepSeq) {
                loginHiringApproveStep = hiringApprove;
                break;
            }
        }
        if (loginHiringApproveStep == null){
            hiringApproveStatus = 2L;
            return new PractitionerHiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
        }
        //查看下一审批步骤
        mdPractitionerHiringApproveSteps = hiringApproveSteps.get(Integer.parseInt(stepId.toString())+1);
        Long mdPractitionerHiringApproveStepsSeq = Long.valueOf(mdPractitionerHiringApproveSteps.getStepSeq());
        Long loginHiringApproveStepId = loginHiringApproveStep.getId();
        if (mdPractitionerHiringApproveStepsSeq.equals(loginHiringApproveStepId)){
            //可审批
            hiringApproveStatus = 1L;
            hiringApproveStepsSeq = mdPractitionerHiringApproveStepsSeq;
        }else {
            //0.不可审批(未到)
            hiringApproveStatus = 0L;
        }
        return new PractitionerHiringApproveSteps(hiringApproveStatus, hiringApproveStepsSeq);
    }
}
