package com.zcloud.basic.info.domain.model;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.exception.BizException;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.domain.model.BaseE;
import com.jjb.saas.framework.utils.DataEncryptDecryptUtil;
import com.zcloud.basic.info.domain.enums.CorpTypeEnum;
import com.zcloud.basic.info.domain.enums.UserEmploymentFlagEnum;
import com.zcloud.basic.info.domain.enums.UserFlowFlagEnum;
import com.zcloud.basic.info.domain.enums.UserTypeEnum;
import com.zcloud.basic.info.domain.gateway.DepartmentGateway;
import com.zcloud.gbscommon.excelEntity.UserExcelExportEntity;
import com.zcloud.gbscommon.excelEntity.UserExcelImportEntity;
import com.zcloud.gbscommon.utils.ExcelUtils;
import com.zcloud.gbscommon.utils.MD5;
import com.zcloud.gbscommon.utils.Sm2Util;
import com.zcloud.gbscommon.utils.Tools;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * web-domain
 *
 * @Author zhangyue
 * @Date 2025-11-04 14:07:34
 */
@Data
public class UserE extends BaseE {
    //GBS用户id
    private Long id;
    //业务主键id老系统id
    private String userId;
    //登录账号
    private String username;
    //姓名
    private String name;
    //企业id
    private Long corpinfoId;
    //是否主账号1是0否
    private Integer mainCorpFlag;
    //用户类型,1监管2企业3相关方
    private Integer userType;
    //部门id
    private Long departmentId;
    //岗位id
    private Long postId;
    //角色id
    private Long roleId;
    //邮箱
    private String email;
    //人员类型编码（主要负责人等）
    private String personnelType;
    //人员类型翻译
    private String personnelTypeName;
    //民族编码问一下有没有组件
    private String nation;
    //民族名称
    private String nationName;
    //身份证号
    private String userIdCard;
    //人脸头像url
    private String userAvatarUrl;
    //现住址
    private String currentAddress;
    //户口所在地
    private String locationAddress;

    private String rankLevel;
    private String phone;

    private String rankLevelName;

    //企业名称
    private String corpinfoName;
    //部门名称
    private String departmentName;
    //岗位名称
    private String postName;
    //人员在部门中的排序
    private Integer sort;
    //乐观锁
    private Integer version;
    //创建人
    private Long createId;
    //创建人姓名
    private String createName;
    //创建时间
    private LocalDateTime createTime;
    //更新人
    private Long updateId;
    //修改人名称
    private String updateName;
    //更新时间
    private LocalDateTime updateTime;
    //描述
    private String remarks;
    //是否删除
    private String deleteEnum;
    //租户ID
    private Long tenantId;
    //机构ID
    private Long orgId;
    //环境
    private String env;
    //是否部门领导0否1是
    private Integer departmentLeaderFlag;
    //是否分管领导0否1是
    private Integer deputyLeaderFlag;
    //文化程度 数据字典
    private String culturalLevel;
    //文化程度名称
    private String culturalLevelName;
    //婚姻状态
    private String maritalStatus;
    //婚姻状态名称
    private String maritalStatusName;
    //政治面貌
    private String politicalAffiliation;
    //政治面貌名称
    private String politicalAffiliationName;
    private Integer isSpecialJob;
    private Integer isDepaRrtmentHead;
    private Integer isLevelThree;
    private Integer isSignLabor;
    private Integer isPay;
    private Integer isSocial;
    private String socialNumber;
    private Integer isInjuriesPay;
    private LocalDate isInjuriesPayTime;
    private String payNumber;
    private Integer isBf;
    //密码
    private String password;
    //密码
    private String newPassword;
    // 入职状态
    private Integer employmentFlag;
    // 入职状态
    private Integer flowFlag;
    private Integer rzFlag;
    // 父级租户id
    private final Long parentTenantId = 1989259383784415232L;
    // 默认密码
    private final String defaultPassword = "Aa@12345678";

    private final String publicKey = "0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee";
    private final String privateKey = "1cfcaab309f614f10d2fed833331b65da75da7682963a6673a9a5d836b6f8c18";

    // 年龄
    private Integer age;

    //生日
    private String birthday;

    // 性别
    private String sex;
    // 微信openid
    private String openId;

    public static Boolean checkUserInfoComplete(UserE userE, Integer flowFlag) {
        return StringUtils.isNotEmpty(userE.getUsername()) &&
                StringUtils.isNotEmpty(userE.getPhone()) &&
                StringUtils.isNotEmpty(userE.getUserIdCard()) &&
                flowFlag != null;
    }


    public void initAdd(Long tenantId, UserE userE) {
        if (StringUtils.isEmpty(userE.getUserId())) {
            userE.setUserId(Tools.get32UUID());
        }
        userE.setTenantId(!ObjectUtils.isEmpty(userE.getTenantId()) ? userE.getTenantId() : tenantId);
        userE.setCorpinfoId(!ObjectUtils.isEmpty(userE.getCorpinfoId()) ? userE.getCorpinfoId() : tenantId);
        userE.setEmploymentFlag(1);
        userE.setPassword(defaultPassword);
    }

    public void initFormOnboarding(Long corpinfoId, Long departmentId, String postName, String userId) {
        this.setCorpinfoId(corpinfoId);
        this.setDepartmentId(departmentId);
        this.setPostName(postName);
        this.setEmploymentFlag(UserEmploymentFlagEnum.ENTRY_AUDIT.getCode());
        if (StringUtils.isNotEmpty(userId)) {
            this.setUserId(userId);
        }
    }

    public void initFromRZ(Long corpinfoId, Long roleId, RzUserRecordE rzUserRecordE) {
        this.setCorpinfoId(corpinfoId);
        this.setDepartmentId(corpinfoId);
        this.setName(rzUserRecordE.getEmployeeName());
        this.setPhone(rzUserRecordE.getPhoneNumber());
        this.setUsername(rzUserRecordE.getPhoneNumber());
        this.setRoleId(roleId);
        this.setPostName(rzUserRecordE.getPositionName());
        this.setUserIdCard(rzUserRecordE.getIdCardNumber());
    }

    /**
     * 校验密码是否相同, 并且是否符合规范
     */
    public void checkPassword(String password, String confirmPassword) {
        if (!password.equals(confirmPassword)) {
            throw new BizException("两次输入的密码不一致");
        }
        if (password.length() < 8 || password.length() > 32) {
            throw new BizException("密码长度必须在8到32个字符之间");
        }
        if (!password.matches("^[A-Za-z\\d!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>/?]{8,32}$")) {
            throw new BizException("密码必须包含大小写字母和数字，且长度大于8");
        }

        // 检查至少包含两种类型
        int typeCount = 0;
        if (password.matches(".*[A-Za-z].*")) typeCount++;  // 包含字母
        if (password.matches(".*\\d.*")) typeCount++;        // 包含数字
        if (password.matches(".*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>/?].*")) typeCount++;  // 包含符号

        if (typeCount < 2) {
            throw new BizException("密码必须包含两种以上的字符类型");
        }

    }


    /**
     * 校验验证码
     */

    /**
     * 人员修改过程中，是否存在转岗、入职离职
     *
     * @param oldUserE
     * @param newUserE
     * @return
     */
    public boolean verifyTransferPosition(UserE oldUserE, UserE newUserE) {
        if (!oldUserE.getCorpinfoId().equals(newUserE.getCorpinfoId())) {
            return true;
        }
        if (!oldUserE.getDepartmentId().equals(newUserE.getDepartmentId())) {
            return true;
        }
        if (!oldUserE.getPostId().equals(newUserE.getPostId())) {
            return true;
        }
        if (!oldUserE.getEmploymentFlag().equals(newUserE.getEmploymentFlag())) {
            return true;
        }
        return false;
    }

    public void checkNull(List<UserE> userList) {
        if (CollUtil.isNotEmpty(userList)) {
            throw new BizException("岗位有相应人员，请解除相关岗位信息后删除。");
        }
    }


    // 导出
    public void exportUserTable(HttpServletResponse httpServletResponse, List<UserExcelExportEntity> userExcelEntities) {
        try {
            ExcelUtils.exportExcel(httpServletResponse, UserExcelExportEntity.class, "人员信息", userExcelEntities);
        } catch (Exception e) {
            throw new BizException("导出失败");
        }
    }

    public void initCorpInfo(CorpInfoE examTypeE, Long departmentId, Long corpInfoId) {
        this.setId(corpInfoId);
        this.setName(examTypeE.getCorpName());
        this.setUsername(examTypeE.getCorpName());
        this.setDepartmentId(departmentId);
        this.setUserType(CorpTypeEnum.getUserTypeByCode(examTypeE.getType()));
        this.setCorpinfoId(corpInfoId);
        this.setOrgId(examTypeE.getTenantId());
        this.setTenantId(examTypeE.getTenantId());
    }

    public void dataProcessingRights(Long tenantId, Map<String, Object> params) {
        if (ObjectUtils.isEmpty(params.get("allFlag")) && ObjectUtils.isEmpty(params.get("eqCorpinfoId"))) {
            params.put("eqCorpinfoId", tenantId);
        }
    }

    public void resetPassword(Integer type) {
        String encrypt = Sm2Util.encryptHex(MD5.md5(CorpTypeEnum.getPasswordByCode(type)), publicKey);
        this.setPassword(encrypt);
    }

    public void encryptionPassword() {
        if (StringUtils.isNotEmpty(password)) {
            this.setPassword(Sm2Util.encryptHex(MD5.md5(password), publicKey));
        }
        if (StringUtils.isNotEmpty(newPassword)) {
            this.setNewPassword(Sm2Util.encryptHex(MD5.md5(newPassword), publicKey));
        }
    }

    public Boolean checkUserPassword(String password, String content) {
        String s = DataEncryptDecryptUtil.sm2Decrypt(privateKey, publicKey, content);
        String s1 = MD5.md5(password);
        return s.equalsIgnoreCase(s1);
    }
    public Boolean checkUserEncryptionPassword(String password, String content) {
        String newPassword = DataEncryptDecryptUtil.sm2Decrypt(privateKey, publicKey, password);
        String oldPassword = DataEncryptDecryptUtil.sm2Decrypt(privateKey, publicKey, content);
//        String s1 = MD5.md5(password);
        return newPassword.equalsIgnoreCase(oldPassword);

    }

    public static void main(String[] args) {
        String publicKey = "0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee";
        String privateKey = "1cfcaab309f614f10d2fed833331b65da75da7682963a6673a9a5d836b6f8c18";

        System.out.println(Sm2Util.encryptHex(MD5.md5("1234"), publicKey));
        System.out.println(Sm2Util.encryptHex(MD5.md5("1234"), publicKey));
        String sign = Sm2Util.sign(privateKey, "1234");
        boolean verify = Sm2Util.verify(publicKey, "04cd0a62599ab4613c6f1c6af1e4eaf5e650fadfd1d4fd9b7350975011bf3bccdf31c7eda8096f182f44e5601bc99554057441370bb45a8baa3386e2b6fd21110b97e579df964612167ec264d8d9752fea3630ad4d67e1dd52defd3817ffa38a19966456574fa85e59bdb889d817ccac6763c90ffe2ba5fafd567188c7a6e4b098", sign);
        System.out.println(verify);
        String s = DataEncryptDecryptUtil.sm2Decrypt(privateKey, publicKey, "04cd0a62599ab4613c6f1c6af1e4eaf5e650fadfd1d4fd9b7350975011bf3bccdf31c7eda8096f182f44e5601bc99554057441370bb45a8baa3386e2b6fd21110b97e579df964612167ec264d8d9752fea3630ad4d67e1dd52defd3817ffa38a19966456574fa85e59bdb889d817ccac6763c90ffe2ba5fafd567188c7a6e4b098");
        System.out.println(s);
        String inputMd5 = MD5.md5("1234");
        System.out.println(inputMd5);
    }



    public boolean verifyTransferFlow(UserE oldUserE, UserE newUserE) {
        if (newUserE.getFlowFlag() == null) {
            return false;
        }
        if (!oldUserE.getFlowFlag().equals(newUserE.getFlowFlag())) {
            return true;
        }
        return false;
    }

    public void checkPhone(List<UserE> userEList) {
        if (CollUtil.isEmpty(userEList)) {
            return;
        }
        //判断AuthContext.gettenantId在userList中是否存在
        if (CollUtil.isNotEmpty(userEList)) {
            //判断是否有当前企业
            boolean flag = userEList.stream().anyMatch(userE -> userE.getCorpinfoId().equals(AuthContext.getTenantId()));
            if (flag) {
                //需要修改，不是提示
                throw new BizException("当前手机号当前企业已存在,请联系管理员");
            } else {
                throw new BizException("当前手机号已在其他企业存在,请联系管理员");
            }
        }
    }

    public void checkXGfPhone(List<UserE> userEList) {

        //判断在其他企业是否是固定人员
        List<UserE> userList = userEList.stream().
                filter(userE -> UserFlowFlagEnum.FIXED.getCode().equals(userE.getFlowFlag()))
                .filter(userE -> !AuthContext.getTenantId().equals(userE.getCorpinfoId()))
                .filter(userE -> UserEmploymentFlagEnum.ON.getCode().equals(userE.getEmploymentFlag())
                        || UserEmploymentFlagEnum.ENTRY_AUDIT.getCode().equals(userE.getEmploymentFlag())
                        || UserEmploymentFlagEnum.RESIGNATION_AUDIT.getCode().equals(userE.getEmploymentFlag()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(userList)) {
            throw new BizException("当前手机号已在其他企业属于固定人员");
        }
        userEList.forEach(userE -> {
            //如果是企业不是相关方企业，则不行
            if(!userE.getUserType().equals(UserTypeEnum.XGF.getCode()) && (UserEmploymentFlagEnum.ON.getCode().equals(userE.getEmploymentFlag())
                    || UserEmploymentFlagEnum.ENTRY_AUDIT.getCode().equals(userE.getEmploymentFlag())
                    || UserEmploymentFlagEnum.RESIGNATION_AUDIT.getCode().equals(userE.getEmploymentFlag()))){
                throw new BizException("当前手机号已存在");
            }
        });

        //判断是否在当前企业存在
        //判断是否有当前企业
        boolean flag = userEList.stream().filter(userE -> UserEmploymentFlagEnum.ON.getCode().equals(userE.getEmploymentFlag())
                || UserEmploymentFlagEnum.ENTRY_AUDIT.getCode().equals(userE.getEmploymentFlag())
                || UserEmploymentFlagEnum.RESIGNATION_AUDIT.getCode().equals(userE.getEmploymentFlag())
                 ).anyMatch(userE -> AuthContext.getTenantId().equals(userE.getCorpinfoId()));
        if (flag) {
            throw new BizException("当前手机号当前企业已存在");
        }

    }

    public void checkIdCardExist(List<UserE> userEList) {
        //判断this.getPhone()在userList中有不一样的，判定已存在
        //过滤掉this.phone不在userList中的值
        List<UserE> userList = userEList.stream().filter(userE -> !userE.getPhone().equals(this.getPhone())).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(userList)) {
            throw new BizException("当前身份证号已存在");
        }

    }


}

