package com.zcloud.basic.info.command;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.exception.BizException;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.system.client.dept.facade.DeptFacade;
import com.jjb.saas.system.client.role.facade.RoleFacade;
import com.jjb.saas.system.client.role.response.RoleCO;
import com.jjb.saas.system.client.user.facade.UserFacade;
import com.zcloud.basic.info.domain.gateway.DepartmentGateway;
import com.zcloud.basic.info.domain.gateway.PostGateway;
import com.zcloud.basic.info.domain.gateway.UserEmploymentLogGateway;
import com.zcloud.basic.info.domain.gateway.UserGateway;
import com.zcloud.basic.info.domain.model.DepartmentE;
import com.zcloud.basic.info.domain.model.PostE;
import com.zcloud.basic.info.domain.model.UserE;
import com.zcloud.basic.info.domain.model.UserEmploymentLogE;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoDO;
import com.zcloud.basic.info.persistence.dataobject.DepartmentDO;
import com.zcloud.basic.info.persistence.dataobject.PostDO;
import com.zcloud.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.repository.CorpInfoRepository;
import com.zcloud.basic.info.persistence.repository.DepartmentRepository;
import com.zcloud.basic.info.persistence.repository.PostRepository;
import com.zcloud.basic.info.persistence.repository.UserRepository;
import com.zcloud.gbscommon.excelEntity.UserExcelImportEntity;
import com.zcloud.gbscommon.utils.ExcelUtils;
import com.zcloud.gbscommon.utils.UuidUtil;
import lombok.AllArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;


/**
* web-app
* @Author zhangyue
* @Date 2025-11-04 14:07:21
*/
@Component
@AllArgsConstructor
public class UserImportExe {
    private final UserGateway userGateway;
    private final UserEmploymentLogGateway userEmploymentLogGateway;
    private final CorpInfoRepository corpInfoRepository;
    private final DepartmentRepository departmentRepository;
    private final PostRepository postRepository;
    private final PostGateway postGateway;
    private final UserRepository userRepository;
    private final DepartmentGateway departmentGateway;
    @DubboReference
    private RoleFacade roleFacade;
    @DubboReference
    private DeptFacade deptFacade;
    @DubboReference
    private UserFacade userFacade;

    @Transactional(rollbackFor = Exception.class)
    public void importUserTable(MultipartFile file, Integer corpFlag) {
        Long corpinfoId = AuthContext.getTenantId();
        if(corpinfoId == null){
            throw new BizException("未选择租户");
        }

        CorpInfoDO corpInfoDO = corpInfoRepository.getById(corpinfoId);
        // 角色数据
        MultiResponse<RoleCO> roleCOMultiResponse = roleFacade.listRoles();
        if (roleCOMultiResponse == null || CollUtil.isEmpty(roleCOMultiResponse.getData())) {
            throw new BizException("未创建角色，请联系管理员");
        }
        //
        Boolean b = corpInfoRepository.isSupper();
        Long roleId = null;
        List<RoleCO> roleCOList = roleCOMultiResponse.getData();
        if(b){
            //是
            Optional<RoleCO> superCorpRoleOpt = roleCOList.stream()
                    .filter(roleCO -> roleCO.getRoleName().contains("股份端普通用户"))
                    .findFirst();
            if (superCorpRoleOpt.isPresent()) {
                roleId = superCorpRoleOpt.get().getId();
            }
        }else{
            // 普通租户查找普通用户或个人账号
            Optional<RoleCO> normalRoleOpt = roleCOList.stream()
                    .filter(roleCO -> roleCO.getRoleName().contains("普通用户") ||
                            roleCO.getRoleName().contains("个人账户"))
                    .findFirst();
            if (normalRoleOpt.isPresent()) {
                roleId = normalRoleOpt.get().getId();
            }
        }
        if(roleId == null){
            throw new BizException("未创建角色，请联系管理员");
        }

        // 部门数据
        List<DepartmentDO> departmentDOList = departmentRepository.listByCorpInfoId(corpinfoId);
        List<DepartmentDO> departmentDOTempList = new ArrayList<>();
        // 岗位数据
        List<PostDO> postDOList = postRepository.listByCorpInfoId(corpinfoId);
        // 用户名数据
        List<UserDO> userDOList = userRepository.listByCorpInfoId(corpinfoId);
        List<UserDO> userDOTempList = new ArrayList<>();

        List<UserExcelImportEntity> list = new ArrayList<>();
        try {
            ExcelUtils.readBatch(file, UserExcelImportEntity.class, list);
            if (list.isEmpty()) {
                throw new BizException("文件为空");
            }
        } catch (Exception e) {
            throw new BizException("文件解析失败");
        }

        // 开始处理导入逻辑
        for (UserExcelImportEntity importEntity : list) {
            try {
                processSingleUser(importEntity, corpFlag, corpinfoId, corpInfoDO, departmentDOList, departmentDOTempList, postDOList, userDOList, userDOTempList, roleId);
            } catch (Exception e) {
                if(CollUtil.isNotEmpty(departmentDOTempList)){
                    // 删除底座创建的部门
                    for (DepartmentDO departmentDO : departmentDOTempList) {
                        deptFacade.deleteById(departmentDO.getId());
                    }
                }
                if(CollUtil.isNotEmpty(userDOTempList)){
                    for (UserDO userDO : userDOTempList) {
                        userFacade.delete(userDO.getId());
                    }
                }
                throw new BizException("导入该用户失败: " + importEntity.getUsername() + ", 原因: " + e.getMessage());
            }
        }
    }

    /**
     * 处理单个用户导入
     */
    private void processSingleUser(UserExcelImportEntity importEntity, Integer corpFlag,
                                   Long corpinfoId,
                                   CorpInfoDO corpInfoDO,
                                   List<DepartmentDO> departmentDOList,
                                   List<DepartmentDO> departmentDOTempList,
                                   List<PostDO> postDOList,
                                   List<UserDO> userDOList,
                                   List<UserDO> userDOTempList,
                                   Long roleId) {

        // 1. 处理部门层级，获取最终部门ID
        Long departmentId = processDepartmentHierarchy(importEntity, corpinfoId, departmentDOList, departmentDOTempList);

        // 2. 处理岗位，获取岗位ID
        Long postId = processPost(importEntity, corpinfoId, corpInfoDO, departmentId, postDOList);

        // 3. 处理角色信息
//        Long roleId = processRoleInfo(importEntity, roleList);

        // 4. 处理用户信息
        processUserInfo(importEntity, corpFlag, corpinfoId, corpInfoDO, departmentId, postId, userDOList, userDOTempList, roleId);
    }

    /**
     * 处理部门层级结构
     */
    private Long processDepartmentHierarchy(UserExcelImportEntity importEntity, Long corpinfoId,
                                            List<DepartmentDO> allDepartments,
                                            List<DepartmentDO> departmentDOTempList) {

        if(StringUtils.isEmpty(importEntity.getDepartmentName1())
                && StringUtils.isEmpty(importEntity.getDepartmentName2())
                && StringUtils.isEmpty(importEntity.getDepartmentName3())
                && StringUtils.isEmpty(importEntity.getDepartmentName4())
                && StringUtils.isEmpty(importEntity.getDepartmentName5())){
            throw new BizException("部门层级不能为空。");
        }

        String[] deptLevels = {
                importEntity.getDepartmentName1(),
                importEntity.getDepartmentName2(),
                importEntity.getDepartmentName3(),
                importEntity.getDepartmentName4(),
                importEntity.getDepartmentName5()
        };

        // 首先获取或创建固定的一级部门（公司同名部门）
        DepartmentDO rootDept = getOrCreateRootDepartment(corpinfoId, allDepartments);

        // 验证一级部门名称是否与Excel中的部门1匹配
        if (StringUtils.isNotBlank(importEntity.getDepartmentName1()) &&
                !importEntity.getDepartmentName1().equals(rootDept.getName())) {
            throw new BizException("所属部门1名称与公司名称不一致: 所属部门1应该为:" + rootDept.getName());
        }

        Long currentParentId = rootDept.getId(); // 从一级部门开始
        DepartmentDO currentDept = rootDept;

        // 从一级部门开始处理（但一级部门已经存在，所以从二级开始创建）
        for (int level = 0; level < deptLevels.length; level++) {
            String deptName = deptLevels[level];

            // 如果当前层级部门名为空，则停止处理
            if (StringUtils.isBlank(deptName)) {
                break;
            }

            deptName = deptName.trim();

            // 一级部门已经存在，跳过创建
            if (level == 0) {
                // 一级部门使用现有的根部门，继续处理下级
                continue;
            }

            // 查找或创建部门（从二级部门开始）
            currentDept = findOrCreateDepartment(deptName, currentParentId, level + 1, corpinfoId, allDepartments, departmentDOTempList);

            if (currentDept == null) {
                throw new BizException("创建部门失败: " + deptName + " (层级: " + (level + 1) + ")");
            }

            // 当前部门作为下一级的父部门
            currentParentId = currentDept.getId();
        }

        // 返回最终的部门ID
        // 如果没有下级部门，则返回一级部门ID；否则返回最后创建的部门ID
        return currentDept != null ? currentDept.getId() : rootDept.getId();
    }

    /**
     * 获取或创建固定的一级部门（公司同名部门）
     */
    private DepartmentDO getOrCreateRootDepartment(Long corpinfoId, List<DepartmentDO> allDepartments) {
        // 先从现有部门中查找一级部门（父ID为0）
        DepartmentDO rootDept = allDepartments.stream()
                .filter(dept -> dept.getParentId() != null && dept.getParentId() == 0L)
                .findFirst()
                .orElse(null);

        if (rootDept != null) {
            return rootDept;
        }

        // 如果根部门不存在，需要创建（根据你的业务需求决定）
        // 这里保持你的原有逻辑，抛出异常
        throw new BizException("所属部门1不存在，该部门无法手动创建");
    }

    /**
     * 查找或创建部门（从二级部门开始使用）
     */
    private DepartmentDO findOrCreateDepartment(String deptName, Long parentId, int level,
                                                Long corpinfoId, List<DepartmentDO> allDepartments,List<DepartmentDO> departmentDOTempList) {
        // 在现有部门中查找
        DepartmentDO existingDept = findDepartmentInList(allDepartments, parentId, deptName);
        if (existingDept != null) {
            return existingDept;
        }

        // 不存在则创建新部门
        DepartmentDO newDept = createNewDepartment(deptName, parentId, level, corpinfoId);

        // 将新部门添加到列表中
        allDepartments.add(newDept);
        departmentDOTempList.add(newDept);

        return newDept;
    }

    /**
     * 在部门列表中查找指定部门
     */
    private DepartmentDO findDepartmentInList(List<DepartmentDO> departments, Long parentId, String name) {
        return departments.stream()
                .filter(dept -> {
                    // 根部门的父ID是0，不是null
                    boolean parentMatch = (parentId == null && dept.getParentId() == 0L) ||
                            (parentId != null && parentId.equals(dept.getParentId()));
                    return parentMatch && name.equals(dept.getName());
                })
                .findFirst()
                .orElse(null);
    }

    /**
     * 创建新部门
     */
    private DepartmentDO createNewDepartment(String name, Long parentId, int level, Long corpinfoId) {
        DepartmentE department = new DepartmentE();
        department.setName(name);
        department.setParentId(parentId);
        department.setCorpinfoId(corpinfoId);
        department.setDepOrder(9999);

        Long departmentId = departmentGateway.add(department);

        DepartmentDO departmentDO = new DepartmentDO();
        BeanUtils.copyProperties(department, departmentDO);
        departmentDO.setId(departmentId);
        return departmentDO;
    }

    /**
     * 处理岗位信息
     */
    private Long processPost(UserExcelImportEntity importEntity, Long corpinfoId,
                             CorpInfoDO corpInfoDO,
                             Long departmentId, List<PostDO> allPosts) {
        if (StringUtils.isBlank(importEntity.getPostName())) {
            throw new BizException("岗位名称不能为空");
        }

        String postName = importEntity.getPostName().trim();

        // 查找该部门下是否存在该岗位
        PostDO existingPost = findPostInList(allPosts, departmentId, postName);
        if (existingPost != null) {
            return existingPost.getId();
        }

        // 不存在则创建新岗位
        PostDO newPost = createNewPost(postName, departmentId, corpinfoId, corpInfoDO);

        // 将新岗位添加到列表中
        allPosts.add(newPost);

        return newPost.getId();
    }

    /**
     * 在岗位列表中查找指定岗位
     */
    private PostDO findPostInList(List<PostDO> posts, Long departmentId, String name) {
        return posts.stream()
                .filter(post -> departmentId.equals(post.getDepartmentId()) && name.equals(post.getPostName()))
                .findFirst()
                .orElse(null);
    }

    /**
     * 创建新岗位
     */
    private PostDO createNewPost(String name, Long departmentId, Long corpinfoId, CorpInfoDO corpInfoDO) {

        PostDO post = new PostDO();
        post.setPostName(name);
        post.setDepartmentId(departmentId);
        post.setCorpinfoId(corpinfoId);
        post.setCorpinfoName(corpInfoDO.getCorpName());

        PostE postE = new PostE();
        BeanUtils.copyProperties(post, postE);
        Long postId = postGateway.add(postE);
        post.setId(postId);
        return post;
    }

    /**
     * 处理角色信息
     */
    private Long processRoleInfo(UserExcelImportEntity importEntity, List<RoleCO> roleList) {
//        if(StringUtils.isBlank(importEntity.getRoleName())){
//            throw new BizException("角色名称不能为空");
//        }
//        try {
//            Map<String, RoleCO> roleCOMap = roleList.stream().collect(Collectors.toMap(RoleCO::getRoleName, role -> role));
//            String roleName = importEntity.getRoleName();
//            if(roleCOMap.get(roleName) == null){
//                throw new BizException("角色不存在: " + roleName);
//            }
//            return roleCOMap.get(roleName).getId();
//        }catch (IllegalStateException e){
//            throw new BizException("系统角色名称重复，请联系管理员");
//        }
        return null;
    }

    /**
     * 处理用户信息
     */
    private void processUserInfo(UserExcelImportEntity importEntity, Integer corpFlag,
                                 Long corpinfoId,
                                 CorpInfoDO corpInfoDO,
                                 Long departmentId, Long postId,
                                 List<UserDO> allUsers,
                                 List<UserDO> userDOTempList,
                                 Long roleId) {
        // 检查用户名是否已存在
        boolean usernameExists = allUsers.stream()
                .anyMatch(user -> importEntity.getUsername().equals(user.getUsername()));

        if (usernameExists) {
            throw new BizException("用户名已存在: " + importEntity.getUsername());
        }

        // 创建用户
        UserE user = new UserE();
        user.setUserId(UuidUtil.get32UUID());
        user.setUsername(importEntity.getUsername());
        user.setPhone(importEntity.getUsername());
        user.setUserType(corpFlag);
        user.setMainCorpFlag(0);
        user.setRoleId(roleId);
        user.setDepartmentId(departmentId);
        user.setPostId(postId);
        user.setCorpinfoId(corpinfoId);
        user.setName(importEntity.getName());
        user.setUserIdCard(encodeBase64IdCard(importEntity.getUserIdCard()));
        user.setPersonnelType(importEntity.getPersonnelType());
        user.setPersonnelTypeName(importEntity.getPersonnelTypeName());
        user.resetPassword(corpInfoDO.getType());
        userGateway.add(user);
        String corpName = null;
        if(corpInfoDO != null && !ObjectUtils.isEmpty(corpInfoDO.getCorpName())){
            corpName = corpInfoDO.getCorpName();
        }
        UserEmploymentLogE userEmploymentLogE = new UserEmploymentLogE();
        userEmploymentLogE.initAdd(userEmploymentLogE, corpName, user.getId());
        userEmploymentLogGateway.add(userEmploymentLogE);

        // 将新用户添加到列表中
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(user, userDO);
        allUsers.add(userDO);
        userDOTempList.add(userDO);
    }
    private static String encodeBase64IdCard(String userIdCard) {
        if (StringUtils.isEmpty(userIdCard)) {
            return null;
        }
        try {
            return Base64.getEncoder().encodeToString(userIdCard.trim().getBytes("UTF-8"));
        } catch (Exception ex) {
            return userIdCard.trim();
        }
    }
}

