package com.jeeplus.human.enrollment.enrollmentRegistration.service;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeeplus.common.SecurityUtils;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.flowable.feign.IFlowableApi;
import com.jeeplus.human.enrollment.enrollmentRegistration.domain.EnrollmentKeyCard;
import com.jeeplus.human.enrollment.enrollmentRegistration.domain.EnrollmentRegistration;
import com.jeeplus.human.enrollment.enrollmentRegistration.domain.EnrollmentSocialSecurityCard;
import com.jeeplus.human.enrollment.enrollmentRegistration.domain.EnrollmentWageCard;
import com.jeeplus.human.enrollment.enrollmentRegistration.mapper.EnrollmentRegistrationMapper;
import com.jeeplus.human.enrollment.enrollmentRegistration.mapper.EnrollmentSocialSecurityCardMapper;
import com.jeeplus.human.enrollment.enrollmentRegistration.utils.SnowFlake;
import com.jeeplus.human.practice.register.domain.Registration;
import com.jeeplus.sys.feign.IOfficeApi;
import com.jeeplus.sys.feign.IPostApi;
import com.jeeplus.sys.feign.IRoleApi;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.service.dto.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author 王强
 * @version 1.0
 * @date 2023-09-27 14:27
 */
@Service
@Transactional
public class EnrollmentRegistrationService extends ServiceImpl<EnrollmentRegistrationMapper, EnrollmentRegistration> {

    @Resource
    private EnrollmentRegistrationMapper mapper;

    @Resource
    private EnrollmentWageCardService wageCardService;

    @Resource
    private EnrollmentSocialSecurityCardService securityCardService;

    @Resource
    private EnrollmentSocialSecurityCardMapper socialSecurityCardMapper;

    @Resource
    private EnrollmentKeyCardService keyCardService;

    /**
     * 实习人员登记表信息
     * @param page
     * @param projectReportData
     * @return
     * @throws Exception
     */
    public IPage<EnrollmentRegistration> findList(Page<EnrollmentRegistration> page, EnrollmentRegistration projectReportData) throws Exception{
        QueryWrapper<EnrollmentRegistration> queryWrapper = QueryWrapperGenerator.buildQueryCondition (projectReportData,EnrollmentRegistration.class);
        queryWrapper.eq("a.del_flag","0");
        if (StringUtils.isNotBlank(projectReportData.getMobilePhone())) {
            queryWrapper.like("a.mobile_phone",projectReportData.getMobilePhone());
        }
        if (StringUtils.isNotBlank(projectReportData.getName())) {
            queryWrapper.like("a.name",projectReportData.getName());
        }
        if (StringUtils.isNotBlank(projectReportData.getDepartment())) {
            queryWrapper.eq("a.department",projectReportData.getDepartment());
        }
        IPage<EnrollmentRegistration> list = mapper.findList(page, queryWrapper);
        return list;

    }

    public EnrollmentRegistration saveRegistration(EnrollmentRegistration registration) throws Exception {
        if (StringUtils.isNotEmpty(registration.getId())){

            EnrollmentRegistration report = mapper.getById(registration.getId());
            if (report != null){
                return update(registration);
            }
        }
        return add(registration);
    }

    public EnrollmentRegistration saveRegistration2(EnrollmentRegistration registration) throws Exception {
        if (StringUtils.isNotEmpty(registration.getId())){

            EnrollmentRegistration report = mapper.getById(registration.getId());
            if (report != null){
                return update2(registration);
            }
        }
        return add(registration);
    }

    /**
     * 新增
     */
    @Transactional(rollbackFor = Exception.class)
    public EnrollmentRegistration add(EnrollmentRegistration reportData) throws Exception{

        String currentToken = TokenProvider.getCurrentToken();

        QueryWrapper<EnrollmentRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id_card", reportData.getIdCard());
        queryWrapper.eq("del_flag", 0);

        // 删除基础信息表
        Integer integer = mapper.selectCount(queryWrapper);
        Integer mobilePhoneOnly = SpringUtil.getBean(IUserApi.class).selectCountByMobile(reportData.getMobilePhone());

        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken ( ));

        EnrollmentRegistration report = new EnrollmentRegistration();

        if (integer <=0 && mobilePhoneOnly <=0 ) {

            String id = SnowFlake.getId();
            BeanUtils.copyProperties(reportData, report);
            report.setId(id);
            report.setCreateById("1");
            report.setCreateTime(new Date());
            report.setUpdateById("1");
            report.setUpdateTime(new Date());

            if (StringUtils.isNotBlank(report.getSocialSecurityNumber())){
                EnrollmentSocialSecurityCard securityCard = new EnrollmentSocialSecurityCard();
                String amountId = SnowFlake.getId();
                securityCard.setId(amountId);
                securityCard.setCreateById("1");
                securityCard.setCreateTime(new Date());
                securityCard.setUpdateById("1");
                securityCard.setUpdateTime(new Date());
                securityCard.setSocialSecurityNumber(report.getSocialSecurityNumber());
                securityCard.setSocialSecurityBankNumber(report.getSocialSecurityBankNumber());
                securityCard.setSocialSecurityPictureFront(report.getSocialSecurityPictureFront());
                securityCard.setSocialSecurityPictureOpposite(report.getSocialSecurityPictureOpposite());
                securityCard.setEnrollmentRegistrationId(id);

                socialSecurityCardMapper.insert(securityCard);
            }

            //if (null == currentToken) {
                //发起员工入职流程
                Map map = SpringUtil.getBean(IFlowableApi.class).getByNameForFen("员工入职");
                String procDefId = map.get("id")+"";

                report.setProcessDefinitionId(procDefId);
                report.setProcessType("0");
                mapper.insert(report);

                Map<String ,Map<String,String >>  allMap = new HashMap<>();

                String procDefKey = map.get("key")+"";
                String businessTable = "human_resources_enrollment_registration";

                String businessId = id;
                String title = "管理员发起了- [" + report.getName() + "员工入职]";

                //获取实习信息审核员信息
                RoleDTO roleDTO = SpringUtil.getBean(IRoleApi.class).getRoleDTOByName2("实习信息审核员");
                String assignee = getAssignee(roleDTO.getId());
                String recordType = "";

                Map<String, String> newMap = pingMap(procDefId, procDefKey, businessTable, businessId, title, assignee, recordType);
                allMap.put("入职",newMap);
                SpringUtil.getBean(IFlowableApi.class).startForFenNew(allMap);
            /*} else {
                mapper.insert(report);
            }*/
        }

        return report;
    }

    public String getAssignee(String roleId){
        List<UserDTO> userDTOS = SpringUtil.getBean(IUserApi.class).findListByRoleId(roleId);
        StringJoiner idJoiner = new StringJoiner(",");
        for (UserDTO user : userDTOS) {
            idJoiner.add(String.valueOf(user.getId()));
        }

        return idJoiner.toString();
    }

    public String getAssignee2(String roleId){
        List<UserDTO> userDTOS = SpringUtil.getBean(IUserApi.class).findListFlowAbleByPostId(roleId);
        StringJoiner idJoiner = new StringJoiner(",");
        for (UserDTO user : userDTOS) {
            idJoiner.add(String.valueOf(user.getId()));
        }

        return idJoiner.toString();
    }
    public Map<String,String> pingMap(String procDefId,String procDefKey,String businessTable,
                                      String businessId,String title,String assignee,String recordType){
        Map<String,String> map = new HashMap();
        map.put("procDefId", procDefId);
        map.put("procDefKey", procDefKey);
        map.put("businessTable", businessTable);
        map.put("businessId", businessId);
        map.put("title", title);
        map.put("assignee", assignee);
        map.put("recordType", recordType);
        return map;
    }

    /**
     * 修改
     */
    @Transactional(rollbackFor = Exception.class)
    public EnrollmentRegistration update(EnrollmentRegistration reportData) throws Exception{
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken ( ));

        EnrollmentRegistration report = new EnrollmentRegistration();
        BeanUtils.copyProperties(reportData, report);
        report.setUpdateById(userDTO.getId());
        report.setUpdateTime(new Date());

        //生成一个系统账号
        // 生成id
        String amountId = "";
        if (StringUtils.isBlank(report.getUserId())) {
            amountId = SnowFlake.getId();
            report.setUserId(amountId);
        } else {
            amountId = report.getUserId();
        }


        if (StringUtils.isNotBlank(report.getType()) && !userDTO.isAdmin()){
            if (report.getType().equals("5")){
                //获取当前的用户，审核的人
                UserDTO dto = new UserDTO();
                //设置信息
                dto.setId(amountId);
                dto.setName(report.getName());
                dto.setPassword(SecurityUtils.encryptPassword("123456"));
                dto.setLoginName(report.getName());
                dto.setLoginFlag("1");
                dto.setMobile(report.getMobilePhone());
                dto.setTenantDTO(userDTO.getTenantDTO());
                dto.setCompanyDTO(userDTO.getCompanyDTO());
                OfficeDTO officeDTO = new OfficeDTO();
                officeDTO.setId(report.getDepartment());
                //设置角色
                OfficeDTO office = SpringUtil.getBean(IOfficeApi.class).getOfficeById(report.getDepartment());

                String name = "兴光会计员工";
                List <RoleDTO> roleIdList = new ArrayList<>();

//                roleIdList.add(roleInfo);


                String officeName = "";
                String networkAddress = "";
                if (null != office) {
                    Map<String,String> keyMap = new HashMap<>();
                    TenantDTO tenantDTO = new TenantDTO();
                    tenantDTO.setId(office.getTenantId());
                    dto.setTenantDTO(tenantDTO);
                    if (office.getTenantId().equals("10003")){
                        officeName = "会计业务管理公司";
                        networkAddress = "cpapmis.xgccpm.com";
                        keyMap.put("name", "兴光会计员工,共有权限（会计）");
                        keyMap.put("tenantId", office.getTenantId());
                        roleIdList = SpringUtil.getBean(IRoleApi.class).getRoleDTOByNameAndTenantId(keyMap);
                    }else if (office.getTenantId().equals("10004")) {
                        officeName = "中审管理公司";
                        networkAddress = "zs.xgccpm.com";
                        keyMap.put("name", "中审员工,共有权限（中审）");
                        keyMap.put("tenantId", office.getTenantId());
                        roleIdList = SpringUtil.getBean(IRoleApi.class).getRoleDTOByNameAndTenantId(keyMap);
                    }else if (office.getTenantId().equals("10001")) {
                        officeName = "评估管理公司";
                        networkAddress = "http://amc.xgccpm.com";
                        keyMap.put("name", "评估员工,共有权限（评估）");
                        keyMap.put("tenantId", office.getTenantId());
                        roleIdList = SpringUtil.getBean(IRoleApi.class).getRoleDTOByNameAndTenantId(keyMap);
                    }
                } else {
                    TenantDTO tenantDTO = new TenantDTO();
                    tenantDTO.setId("10002");
                    dto.setTenantDTO(tenantDTO);
                    officeName = "综合管理公司";
                }
                dto.setRoleDTOList(roleIdList);
                dto.setOfficeDTO(officeDTO);

                SpringUtil.getBean ( IUserApi.class ).saveOrUpdate(dto);


//                report.setOnJobStatus("正式");
                //发送短信通知 (未实现)

                PostDTO postDTO = SpringUtil.getBean(IPostApi.class).getPostDTOByName("门卡管理员");
                List<UserDTO> listByPostId = SpringUtil.getBean(IUserApi.class).findListFlowAbleByPostId(postDTO.getId());

                String randomCode = report.getName() + "你好!欢迎入职" + officeName + "，请尽快登录公司系统:" + networkAddress
                        + "完善个人信息（包括社保卡号与工资卡号）并修改初始密码，系统初始账号密码为：" + report.getName() +
                        "/123456，人事部门已在为你办理门禁卡，办理成功后将由系统告知，在收到系统通知后，请及时到办公室"+ listByPostId.get(0).getName() +"处领取门禁卡！"+
                        "注：工资卡需同时提供中信银行、招商银行卡号";
                Map<String, Object> stringObjectMap = SpringUtil.getBean(IUserApi.class).sendRandomCodes(report.getMobilePhone(), randomCode);
                String statusCode = (String) stringObjectMap.get("statusCode");
                if (("000000").equals(statusCode)) {
                    System.out.println("短信发送成功!");
                }else if(statusCode.equals("160040")){
                    System.out.println("手机号获取验证码次数已达每日上限!");
                }else{
                    System.out.println("短信发送失败，错误代码：101，请联系管理员!");
                }

                //当流程结束的时候，发起工资卡信息完善流程
                Map map = SpringUtil.getBean(IFlowableApi.class).getByNameForFen("工资卡信息完善");
                String procDefId = map.get("id")+"";

                //当流程结束的时候，发起工资卡信息完善流程
                String uid = SnowFlake.getId();
                EnrollmentWageCard wageCard = new EnrollmentWageCard();
                wageCard.setId(uid);
                wageCard.setCreateById("1");
                wageCard.setUpdateById("1");
                wageCard.setProcessDefinitionId(procDefId);
                wageCard.setEnrollmentRegistrationId(report.getId());
                wageCardService.save(wageCard);

                String procDefKey = map.get("key")+"";
                String businessTable = "human_resources_enrollment_wage_card";
                String businessId = uid;
                String title = "工资卡信息完善";
                String assignee = amountId;
                String recordType = "";
                Map<String,String> newMap = new HashMap();
                newMap.put("procDefId", procDefId);
                newMap.put("procDefKey", procDefKey);
                newMap.put("businessTable", businessTable);
                newMap.put("businessId", businessId);
                newMap.put("title", title);
                newMap.put("assignee", assignee);
                newMap.put("recordType", recordType);
                String procInsId = SpringUtil.getBean(IFlowableApi.class).startForFen(newMap);

                wageCard.setProcInsId(procInsId);
                wageCard.setType("2");
                wageCardService.saveOrUpdate(wageCard);

                //发起社保流程
                if (StringUtils.isBlank(report.getSocialSecurityNumber())){
                    Map cardMap = SpringUtil.getBean(IFlowableApi.class).getByNameForFen("社保登记");
                    String procDefId2 = cardMap.get("id")+"";

                    //当流程结束的时候，发起工资卡信息完善流程
                    String uuid = SnowFlake.getId();
                    EnrollmentSocialSecurityCard securityCard = new EnrollmentSocialSecurityCard();
                    securityCard.setId(uuid);
                    securityCard.setCreateById("1");
                    securityCard.setUpdateById("1");
                    securityCard.setProcessDefinitionId(procDefId2);
                    securityCard.setEnrollmentRegistrationId(report.getId());
                    securityCardService.save(securityCard);

                    String procDefKey2 = cardMap.get("key")+"";
                    String businessTable2 = "human_resources_enrollment_social_security_card";
                    String businessId2 = uuid;
                    String title2 = "社保卡信息完善";
                    String assignee2 = amountId;
                    String recordType2 = "";
                    Map<String,String> newMap2 = new HashMap();
                    newMap2.put("procDefId", procDefId2);
                    newMap2.put("procDefKey", procDefKey2);
                    newMap2.put("businessTable", businessTable2);
                    newMap2.put("businessId", businessId2);
                    newMap2.put("title", title2);
                    newMap2.put("assignee", assignee2);
                    newMap2.put("recordType", recordType2);
                    String procInsId2 = SpringUtil.getBean(IFlowableApi.class).startForFen(newMap2);

                    securityCard.setProcInsId(procInsId2);
                    securityCard.setType("2");
                    securityCardService.saveOrUpdate(securityCard);
                }
                //发起门卡办理通知流程
                Map keyMap = SpringUtil.getBean(IFlowableApi.class).getByNameForFen("门卡办理");
                String keyProcDefId = keyMap.get("id")+"";

                //当流程结束的时候，发起工资卡信息完善流程
                String keyUid = SnowFlake.getId();
                EnrollmentKeyCard keyCard = new EnrollmentKeyCard();
                keyCard.setId(keyUid);
                keyCard.setCreateById("1");
                keyCard.setUpdateById("1");
                keyCard.setProcessDefinitionId(keyProcDefId);
                keyCard.setEnrollmentRegistrationId(report.getId());
                keyCardService.save(keyCard);

                String keyProcDefKey = keyMap.get("key")+"";
                String keyBusinessTable = "human_resources_enrollment_key_card";
                String keyBusinessId = keyUid;
                String keyTitle = report.getName() +  "的门卡办理";

//                UserDTO userInfo = SpringUtil.getBean(IUserApi.class).getByLoginNameNotTenantId("赵俐");
//                String keyAssignee = userInfo.getId();

                PostDTO postInfo = SpringUtil.getBean(IPostApi.class).getPostDTOByName("门卡办理人");
                String keyAssignee = getAssignee2(postInfo.getId());

                String keyRecordType = "";
                Map<String,String> keyMap2 = new HashMap();
                keyMap2.put("procDefId", keyProcDefId);
                keyMap2.put("procDefKey", keyProcDefKey);
                keyMap2.put("businessTable", keyBusinessTable);
                keyMap2.put("businessId", keyBusinessId);
                keyMap2.put("title", keyTitle);
                keyMap2.put("assignee", keyAssignee);
                keyMap2.put("recordType", keyRecordType);
                String procInsId2 = SpringUtil.getBean(IFlowableApi.class).startForFen(keyMap2);
                keyCard.setProcInsId(procInsId2);
                keyCard.setType("2");
                keyCardService.saveOrUpdate(keyCard);
            }
        }

        mapper.updateById(report);
        return report;
    }

    /**
     * 修改
     */
    @Transactional(rollbackFor = Exception.class)
    public EnrollmentRegistration update2(EnrollmentRegistration reportData) throws Exception{
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken ( ));

        EnrollmentRegistration report = new EnrollmentRegistration();
        BeanUtils.copyProperties(reportData, report);
        report.setUpdateById(userDTO.getId());
        report.setUpdateTime(new Date());

        mapper.updateById(report);
        return report;
    }

    public EnrollmentRegistration findById(String id) throws Exception {
        // 查询基础信息表
        EnrollmentRegistration info = mapper.getById(id);
        return info;
    }

    public Integer findByUserId(String userId) throws Exception {
        QueryWrapper<EnrollmentRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("del_flag", 0);
        // 删除基础信息表
        Integer integer = mapper.selectCount(queryWrapper);
        return integer;
    }

    public void updateStatusById(EnrollmentRegistration dto) {
        EnrollmentRegistration registration = mapper.getById(dto.getId());
        mapper.updateStatusById(dto.getId(), dto.getType());
        //判断流程的类型  是入职登记流程 还是 个人信息完善流程
        if (StringUtils.isNotBlank(registration.getProcessType()) && registration.getProcessType().equals("0")) {
            //说明是入职登记流程  这时删除入职登记相关信息
            mapper.deleteByIdOnPhysic(dto.getId());

        }



    }

    public String remove(String id) {
        // 删除基础信息表
        mapper.removeById(id);
        return "操作成功";
    }

    public Integer findIdCardOnly(String idCard) throws Exception {
        QueryWrapper<EnrollmentRegistration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id_card", idCard);
        queryWrapper.eq("del_flag", 0);
        // 删除基础信息表
        Integer integer = mapper.selectCount(queryWrapper);
        return integer;
    }

    public Integer findMobilePhoneOnly(String mobilePhone) throws Exception {
        // 删除基础信息表
        Integer integer = SpringUtil.getBean(IUserApi.class).selectCountByMobile(mobilePhone);
        return integer;
    }

    /**
     * 获取正式工在职状态为离职的，并且user表中未删除的
     * @return
     */
    public List<EnrollmentRegistration> getFormalUserInfo() {
        return mapper.getFormalUserInfo();
    }

    public void updateRegistration(EnrollmentRegistration reportData) {
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken ( ));

        EnrollmentRegistration report = new EnrollmentRegistration();
        BeanUtils.copyProperties(reportData, report);
        report.setUpdateById(userDTO.getId());
        report.setUpdateTime(new Date());

        mapper.updateById(report);

        if (StringUtils.isNotBlank(report.getSocialSecurityNumber())){
            EnrollmentSocialSecurityCard securityCard = new EnrollmentSocialSecurityCard();
            String amountId = SnowFlake.getId();
            securityCard.setId(amountId);
            securityCard.setCreateById("1");
            securityCard.setCreateTime(new Date());
            securityCard.setUpdateById("1");
            securityCard.setUpdateTime(new Date());
            securityCard.setSocialSecurityNumber(report.getSocialSecurityNumber());
            securityCard.setSocialSecurityBankNumber(report.getSocialSecurityBankNumber());
            securityCard.setSocialSecurityPictureFront(report.getSocialSecurityPictureFront());
            securityCard.setSocialSecurityPictureOpposite(report.getSocialSecurityPictureOpposite());
            securityCard.setEnrollmentRegistrationId(report.getId());

            socialSecurityCardMapper.insert(securityCard);
        }

    }

    public void insertIntoEnrollmentRegistrationInfo(String value) {
        EnrollmentRegistration infos = JSON.parseObject(value, new TypeReference<EnrollmentRegistration>() {});
        mapper.insert(infos);
    }

    public List<String> getAllUserIdInSuccess() {
        return mapper.getAllUserIdInSuccess();
    }
}
