package com.jeeplus.human.practice.register.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.service.EnrollmentRegistrationService;
import com.jeeplus.human.enrollment.enrollmentRegistration.utils.SnowFlake;
import com.jeeplus.human.practice.register.domain.Registration;
import com.jeeplus.human.practice.register.domain.RegistrationBank;
import com.jeeplus.human.practice.register.domain.RegistrationExperience;
import com.jeeplus.human.practice.register.domain.RegistrationFamilyMembers;
import com.jeeplus.human.practice.register.mapper.FamilyMembersMapper;
import com.jeeplus.human.practice.register.mapper.InterRegistrationMapper;
import com.jeeplus.human.practice.register.mapper.RegistrationExperienceMapper;
import com.jeeplus.human.practice.register.service.dto.RegistrationDto;
import com.jeeplus.sys.domain.WorkAttachmentInfo;
import com.jeeplus.sys.feign.*;
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.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author 王强
 * @version 1.0
 * @date 2023-09-13 14:11
 */
@Service
@Transactional
public class RegistrationService extends ServiceImpl<InterRegistrationMapper, Registration> {

    @Resource
    private InterRegistrationMapper mapper;

    @Resource
    private FamilyMembersMapper familyMembersMapper;

    @Resource
    private RegistrationBankService bankService;

    @Resource
    private RegistrationExperienceMapper experienceMapper;

    @Resource
    private EnrollmentRegistrationService enrollmentRegistrationService;

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

    public void updateStatusById(RegistrationDto dto) {
        mapper.updateStatusById(dto.getId(), dto.getType());
        //根据id将这一条实习登记信息物理删除
        mapper.deleteByIdOnPhysic(dto.getId());
    }

    public Registration findById(String id) {
        // 查询基础信息表
        Registration info = mapper.getById(id);
        if (null != info){
            List<RegistrationFamilyMembers> familyMembers = familyMembersMapper.getByRegisterId(id);
            info.setFamilyMembers(familyMembers);
            List<RegistrationExperience> experiences = experienceMapper.getByRegisterId(id);
            info.setExperiences(experiences);
        }
        return info;
    }

    public String remove(String id) {
        //删除实习经验表的数据
        experienceMapper.deleteByRegisterId(id);
        //删除家庭成员表的数据
        familyMembersMapper.deleteByRegisterId(id);
        // 删除基础信息表
        mapper.removeById(id);
        return "操作成功";
    }

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

    }

    /**
     * 根据id查实习人员信息
     * @param page
     * @param projectReportData
     * @return
     * @throws Exception
     */
    public IPage<RegistrationDto> findList2(Page<RegistrationDto> page, RegistrationDto projectReportData) throws Exception{
        QueryWrapper<RegistrationDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition (projectReportData,RegistrationDto.class);
        queryWrapper.eq("a.del_flag","0");
        queryWrapper.eq("a.id",projectReportData.getId());
        IPage<RegistrationDto> list = mapper.findList2(page, queryWrapper);
        return list;

    }

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

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

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

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

        //当审核通过的时候，将该人员加入到实习生角色中，根据联系电话发送短信到该实习生手机中，将实习状态改为“实习中”
        //根据他的姓名生成一个系统账号，就是创建一个用户信息
        if (StringUtils.isNotBlank(report.getType()) && !userDTO.isAdmin()){
            if (report.getType().equals("5")){
                //获取当前的用户，审核的人
                UserDTO dto = new UserDTO();
                //设置信息
                // 生成id
                String amountId = SnowFlake.getId();
                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.getPracticeOffice());
                dto.setOfficeDTO(officeDTO);

                OfficeDTO office = SpringUtil.getBean(IOfficeApi.class).getOfficeById(report.getPracticeOffice());
                // 获取实习生角色id
                Map<String,String> keyMap = new HashMap<>();
                keyMap.put("name", "实习生");
                keyMap.put("tenantId", office.getTenantId());
                List <RoleDTO> roleIdList = SpringUtil.getBean(IRoleApi.class).getRoleDTOByNameAndTenantId(keyMap);
//                List <RoleDTO> roleIdList = new ArrayList<>();
//                roleIdList.add(roleInfo);
                dto.setRoleDTOList(roleIdList);


                //发送短信通知
                String officeName = "";
                String networkAddress = "";
                if (null != office) {
                    TenantDTO tenantDTO = new TenantDTO();
                    tenantDTO.setId(office.getTenantId());
                    dto.setTenantDTO(tenantDTO);
                    if (office.getTenantId().equals("10003")){
                        officeName = "会计业务管理公司";
                        networkAddress = "cpapmis.xgccpm.com";
                    }else if (office.getTenantId().equals("10004")) {
                        officeName = "中审管理公司";
                        networkAddress = "zs.xgccpm.com";
                    }else if (office.getTenantId().equals("10001")) {
                        officeName = "评估管理公司";
                        networkAddress = "http://amc.xgccpm.com";
                    }
                } else {
                    TenantDTO tenantDTO = new TenantDTO();
                    tenantDTO.setId("10002");
                    dto.setTenantDTO(tenantDTO);
                    officeName = "综合管理公司";
                }



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


//                OfficeDTO office = SpringUtil.getBean(IOfficeApi.class).getOfficeById(report.getPracticeOffice());


                String randomCode = report.getName() + "你好!你好!欢迎来" + officeName + "实习，实习期间请及时在公司系统:" + networkAddress
                        + "中填写实习日志，系统初始账号密码为，系统初始账号密码为：" + report.getName() +
                        "/123456，请尽快登陆系统并修改初始密码！";
                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，请联系管理员!");
                }

                report.setPracticeStatus("实习中");
                report.setUserId(dto.getId());

                //发送完善工资卡信息  实习生完善银行卡号
                Map map = SpringUtil.getBean(IFlowableApi.class).getByNameForFen("实习生完善银行卡号");
                String procDefId = map.get("id")+"";

                //当流程结束的时候，发起工资卡信息完善流程
                String uid = SnowFlake.getId();
                RegistrationBank wageCard = new RegistrationBank();
                wageCard.setId(uid);
                wageCard.setCreateById("1");
                wageCard.setUpdateById("1");
                wageCard.setProcessDefinitionId(procDefId);
                wageCard.setRegisterId(report.getId());
                wageCard.setUserId(amountId);
                wageCard.setType("2");
                bankService.save(wageCard);

                String procDefKey = map.get("key")+"";
                String businessTable = "human_resources_practice_registration_bank";
                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);
            }
        }

        //先删除家庭成员信息，在重新添加
        familyMembersMapper.deleteByRegisterId(report.getId());
        List<RegistrationFamilyMembers> familyMembers = reportData.getFamilyMembers();
        if (CollectionUtils.isNotEmpty(familyMembers)){
            familyMembers.forEach(fa->{
                // 生成id
                String amountId = SnowFlake.getId();
                fa.setId(amountId);
                fa.setCreateById(userDTO.getId());
                fa.setCreateTime(new Date());
                fa.setUpdateById(userDTO.getId());
                fa.setUpdateTime(new Date());
                fa.setDelFlag(0);
                fa.setRegistrationId(report.getId());

                familyMembersMapper.insert(fa);
            });
        }
        //先删除实习经历信息
        experienceMapper.deleteByRegisterId(report.getId());
        List<RegistrationExperience> experiences = reportData.getExperiences();
        if (CollectionUtils.isNotEmpty(experiences)){
            experiences.forEach(fa->{
                // 生成id
                String amountId = UUID.randomUUID().toString().replace("-", "");
                fa.setId(amountId);
                fa.setCreateById(userDTO.getId());
                fa.setCreateTime(new Date());
                fa.setUpdateById(userDTO.getId());
                fa.setUpdateTime(new Date());
                fa.setDelFlag(0);
                fa.setRegistrationId(report.getId());

                experienceMapper.insert(fa);
            });
        }
        mapper.updateById(report);

        return report;
    }

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

        String currentToken = TokenProvider.getCurrentToken();
        Registration report = new Registration();
        BeanUtils.copyProperties(reportData, report);

        QueryWrapper<Registration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id_card", reportData.getIdCard());
        queryWrapper.eq("del_flag", 0);
        Integer integer = mapper.selectCount(queryWrapper);

        Integer mobilePhoneOnly = enrollmentRegistrationService.findMobilePhoneOnly(reportData.getMobilePhone());
        // 删除基础信息表
        if (integer <=0 && mobilePhoneOnly <=0){

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

            String uid = SnowFlake.getId();
            report.setId(uid);

            //先删除家庭成员信息，在重新添加
            familyMembersMapper.deleteByRegisterId(report.getId());
            List<RegistrationFamilyMembers> familyMembers = reportData.getFamilyMembers();
            if (CollectionUtils.isNotEmpty(familyMembers)){

                for (RegistrationFamilyMembers familyMember : familyMembers) {
                    // 生成id
                    String amountId = SnowFlake.getId();
                    familyMember.setId(amountId);
                    familyMember.setCreateById("1");
                    familyMember.setCreateTime(new Date());
                    familyMember.setUpdateById("1");
                    familyMember.setUpdateTime(new Date());
                    familyMember.setDelFlag(0);
                    familyMember.setRegistrationId(report.getId());
                    familyMembersMapper.insert(familyMember);
                }
            }
            //先删除实习经历信息
            experienceMapper.deleteByRegisterId(report.getId());
            List<RegistrationExperience> experiences = reportData.getExperiences();
            if (CollectionUtils.isNotEmpty(experiences)){
                for (RegistrationExperience experience : experiences) {
                    // 生成id
                    String amountId = SnowFlake.getId();
                    experience.setId(amountId);
                    experience.setCreateById("1");
                    experience.setCreateTime(new Date());
                    experience.setUpdateById("1");
                    experience.setUpdateTime(new Date());
                    experience.setDelFlag(0);
                    experience.setRegistrationId(report.getId());

                    experienceMapper.insert(experience);
                }
            }



            //if (null == currentToken) {
                //发起实习登记流程
                Map map = SpringUtil.getBean(IFlowableApi.class).getByNameForFen("实习登记");
                String procDefId = map.get("id")+"";

                report.setProcessDefinitionId(procDefId);
                mapper.insert(report);

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

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

                String businessId = uid;
                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 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;
    }

    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();
    }

    /**
     * 根据实习生的用户id修改实习状态
     * @param createById
     */
    public void updatePracticeStatus(String createById,String endTime) {
        mapper.updatePracticeStatus(createById,endTime);
    }

    /**
     * 查询超过3天未发起日志的实习中的信息
     * @return
     */
    public List<Registration> getTimeOutRegisters() {
        String dictValue = SpringUtil.getBean(IDictApi.class).getDictValue("remind_day", "practice_log_remind_day", "");
        Integer day = 7;//给个默认值，防止没有字典信息
        if(StringUtils.isNotBlank(dictValue)){
            day = Integer.valueOf(dictValue);
        }
        //获取3天前的时间
        String threeDayAgo = LocalDateTime.now().plusDays(-day).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<Registration> registrations = mapper.getTimeOutRegisters(threeDayAgo);
        return registrations;
    }

    /**
     * 获取最后一次发起报销且实习状态为结束，并且报销状态为完成的
     * @return
     */
    public List<Registration> getTimeOutReimburseRegisters() {
        List<Registration> registrations = mapper.getTimeOutReimburseRegisters();
        return registrations;
    }

    public void updateRegistration(Registration reportData) {

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

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

        //先删除家庭成员信息，在重新添加
        familyMembersMapper.deleteByRegisterId(report.getId());
        List<RegistrationFamilyMembers> familyMembers = reportData.getFamilyMembers();
        if (CollectionUtils.isNotEmpty(familyMembers)){
            familyMembers.forEach(fa->{
                // 生成id
                String amountId = SnowFlake.getId();
                fa.setId(amountId);
                fa.setCreateById(userDTO.getId());
                fa.setCreateTime(new Date());
                fa.setUpdateById(userDTO.getId());
                fa.setUpdateTime(new Date());
                fa.setDelFlag(0);
                fa.setRegistrationId(report.getId());

                familyMembersMapper.insert(fa);
            });
        }
        //先删除实习经历信息
        experienceMapper.deleteByRegisterId(report.getId());
        List<RegistrationExperience> experiences = reportData.getExperiences();
        if (CollectionUtils.isNotEmpty(experiences)){
            experiences.forEach(fa->{
                // 生成id
                String amountId = SnowFlake.getId();
                fa.setId(amountId);
                fa.setCreateById(userDTO.getId());
                fa.setCreateTime(new Date());
                fa.setUpdateById(userDTO.getId());
                fa.setUpdateTime(new Date());
                fa.setDelFlag(0);
                fa.setRegistrationId(report.getId());

                experienceMapper.insert(fa);
            });
        }
        mapper.updateById(report);
    }
}
