package cn.iocoder.yudao.module.inspection.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.constant.InspectionConstants;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.inspection.entity.InspectionFile;
import cn.iocoder.yudao.module.inspection.entity.InspectionPickCar;
import cn.iocoder.yudao.module.inspection.entity.InspectionStaff;
import cn.iocoder.yudao.module.inspection.mapper.InspectionStaffMapper;
import cn.iocoder.yudao.module.inspection.mapper.InspectionWorkNodeMapper;
import cn.iocoder.yudao.module.inspection.query.InspectionStaffQuery;
import cn.iocoder.yudao.module.inspection.service.IInspectionFileService;
import cn.iocoder.yudao.module.inspection.service.InspectionStaffService;
import cn.iocoder.yudao.module.inspection.vo.ImportStaffVo;
import cn.iocoder.yudao.module.inspection.vo.InspectionStaffExportVo;
import cn.iocoder.yudao.module.inspection.vo.InspectionStaffSaveVo;
import cn.iocoder.yudao.module.inspection.vo.StaffImportExcelVO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserRoleDTO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

import static cn.iocoder.yudao.framework.common.config.CommonStr.USER_TYPE_STAFF;


/**
 * 检测员工子表(InspectionStaff)表服务实现类
 *
 * @author makejava
 * @since 2023-08-01 16:04:14
 */
@Service("InspectionStaffService")
public class InspectionStaffServiceImpl extends ServiceImpl<InspectionStaffMapper, InspectionStaff> implements InspectionStaffService {

    @Autowired
    private AdminUserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private IInspectionFileService inspectionFileService;

    @Autowired
    private InspectionWorkNodeMapper inspectionWorkNodeMapper;

    /**
     * 获取检测员工分页
     *
     * @param page
     * @param query
     * @return
     */
    @Override
    public IPage<InspectionStaffSaveVo> getList(Page<InspectionStaffSaveVo> page, InspectionStaffQuery query) {
        return baseMapper.getList(page, query);
    }

    /**
     * 获取所有检测员工
     *
     * @param query
     * @return
     */
    @Override
    public List<InspectionStaffExportVo> getAll(InspectionStaffQuery query) {
        return baseMapper.getAll(query);
    }

    /**
     * 编辑检测员工
     *
     * @param inspectionStaffVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean edit(InspectionStaffSaveVo inspectionStaffVo) {
        //更新system_users主表
        UserSaveReqVO userDTO = BeanUtil.copyProperties(inspectionStaffVo, UserSaveReqVO.class);
        userDTO.setId(inspectionStaffVo.getUserId());
        userService.updateUser(userDTO);


        //查询员工子表是否存在数据
        InspectionStaff staff = this.getOne(Wrappers.<InspectionStaff>lambdaQuery().eq(InspectionStaff::getUserId, inspectionStaffVo.getUserId()));
        if (ObjectUtil.isNull(staff)) {
            staff = new InspectionStaff();
            BeanUtil.copyProperties(inspectionStaffVo, staff);
            //新增
            this.save(staff);
        } else {
            //更新检测员工子表
            BeanUtil.copyProperties(inspectionStaffVo, staff);
            this.updateById(staff);
        }

        //查询文件夹
        InspectionStaff staff1 = this.getOne(Wrappers.<InspectionStaff>lambdaQuery().eq(InspectionStaff::getUserId, inspectionStaffVo.getUserId()));
        if (CollUtil.isNotEmpty(inspectionStaffVo.getFileList())) {
            addFile(inspectionStaffVo.getFileList(), inspectionStaffVo.getNickname(), staff1.getFolderId(), staff1.getUserId());
        }

        return true;
    }

    /**
     * 获取检测员工详情
     *
     * @param id
     * @return
     */
    @Override
    public InspectionStaffSaveVo get(Long id) {
        InspectionStaffSaveVo inspectionStaffSaveVo = baseMapper.get(id);
        // 查询用户角色集合
        List<UserRoleDTO> userRoleDTOS = permissionService.userRoleDTOList(Collections.singletonList(id));
        inspectionStaffSaveVo.setRoleIds(userRoleDTOS.stream()
                .filter(role -> "jiance".equals(role.getServicePackageId())) // 修正此行
                .filter(role -> !"jcyh".equals(role.getRoleCode()))
                .map(UserRoleDTO::getRoleId)
                .collect(Collectors.toList()));

        //将驾驶证类型转为数组
        if (ObjectUtil.isNotEmpty(inspectionStaffSaveVo.getDriverLicenseType())) {
            inspectionStaffSaveVo.setDriverLicenseTypeArr(Arrays.asList(inspectionStaffSaveVo.getDriverLicenseType().split(",")));
        }
        //查询文件表文件夹id是否存在
        if (ObjectUtil.isNotEmpty(inspectionStaffSaveVo.getFolderId())) {
            InspectionFile folder = inspectionFileService.getOne(Wrappers.<InspectionFile>lambdaQuery().eq(InspectionFile::getId, inspectionStaffSaveVo.getFolderId()));
            if (ObjectUtil.isNull(folder)) {
                inspectionStaffSaveVo.setFolderId(null);
            }
        }
        return inspectionStaffSaveVo;
    }

    /**
     * 保存检测员工
     *
     * @param inspectionStaffVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveInspectionStaff(InspectionStaffSaveVo inspectionStaffVo) {
        //新增system_users主表
        UserSaveReqVO userDTO = BeanUtil.copyProperties(inspectionStaffVo, UserSaveReqVO.class);
        userDTO.setId(inspectionStaffVo.getUserId());
        //获取当前人的租户id
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        userDTO.setTenantId(loginUser.getTenantId());
        Long userId = userService.createUser(userDTO);

//        //查询检测基础员工角色
//        List<RoleDO> role = roleService.getRoleListByCodesTenant(Collections.singletonList(InspectionConstants.INSPECTION_BASE_STAFF_ROLE));
//
//        if (ObjectUtil.isNull(role)) {
//            throw new RuntimeException("检测基础员工角色不存在");
//        }
//
//        Set<Long> roleIds = role.stream().map(RoleDO::getId).collect(Collectors.toSet());
//        //设置角色为检测基础员工
//        permissionService.assignUserRole(userId, roleIds);

        InspectionStaff inspectionStaff = BeanUtil.copyProperties(inspectionStaffVo, InspectionStaff.class);
        inspectionStaff.setUserId(userId);
        //新增检测员工子表
        this.save(inspectionStaff);
        if (ObjectUtil.isNotEmpty(inspectionStaffVo.getFileList())) {
            addFile(inspectionStaffVo.getFileList(), inspectionStaffVo.getNickname(), null, inspectionStaff.getUserId());
        }
        return inspectionStaff.getUserId();
    }

    /**
     * 导入检测员工
     *
     * @param list 检测员工
     * @return
     */
    @Override
    public Map<String, Object> importStaff(List<StaffImportExcelVO> list) {
        if (CollUtil.isEmpty(list)) {
            throw new RuntimeException("导入数据为空");
        }
        Map<String, Object> resultMap = new HashMap<>();

        //校验信息
        ImportStaffVo importStaffVo = validImportStaff(list);

        //保存用户信息
        int saveNum = saveImportStaff(importStaffVo.getSuccessList());
        resultMap.put("saveNum", saveNum);
        resultMap.put("failList", importStaffVo.getFailList());
        resultMap.put("successList", importStaffVo.getSuccessList());
        return resultMap;
    }

    /**
     * 添加文件夹
     *
     * @param userId 用户id
     * @return 文件夹id
     */
    @Override
    public Long addFolder(Long userId) {
        AdminUserDO user = userService.getUser(userId);
        if (ObjectUtil.isNotEmpty(user)) {
            Long folderId = inspectionFileService.addFolder(user.getNickname(), InspectionConstants.INSPECTION_STAFF_KEY);

            //查询员工子表是否存在数据
            InspectionStaff staff = this.getOne(Wrappers.<InspectionStaff>lambdaQuery().eq(InspectionStaff::getUserId, userId));
            if (ObjectUtil.isNull(staff)) {
                staff = new InspectionStaff();
                staff.setUserId(userId);
                staff.setFolderId(folderId);
                //新增
                this.save(staff);
            } else {
                //修改文件夹id
                this.update(Wrappers.<InspectionStaff>lambdaUpdate().eq(InspectionStaff::getUserId, userId).set(InspectionStaff::getFolderId, folderId));
            }
            return folderId;
        } else {
            log.error("用户不存在");
            return null;
        }
    }

    /**
     * 获取已完成项目
     *
     * @param userId
     * @return
     */
    @Override
    public IPage<Map<String, Object>> getFinishProjectByUserId(Page<Map<String, Object>> page, Long userId) {
        return inspectionWorkNodeMapper.selectStaffProjectByUserId(page,userId);
    }

    /**
     * 保存检测员工
     *
     * @param successList
     * @return
     */
    private int saveImportStaff(List<StaffImportExcelVO> successList) {
        //将员工插入主表
        Map<String, Long> users = new HashMap<>();
        for (StaffImportExcelVO staffImportExcelVO : successList) {
            UserSaveReqVO createReqVO = new UserSaveReqVO();
            createReqVO.setUsername(staffImportExcelVO.getMobile());
            createReqVO.setMobile(staffImportExcelVO.getMobile());
            createReqVO.setNickname(staffImportExcelVO.getUsername());
            createReqVO.setPassword("123456");

            Long userId = userService.createUser(createReqVO);
            users.put(staffImportExcelVO.getMobile(), userId);
            //创建员工文件夹
            Long folderId = addFolder(userId);
            //修改文件夹id
            this.update(Wrappers.<InspectionStaff>lambdaUpdate().eq(InspectionStaff::getUserId, userId).set(InspectionStaff::getFolderId, folderId));
        }


        //插入检测员工子表
        List<InspectionStaff> inspectionStaffList = new ArrayList<>();
        for (StaffImportExcelVO staffImportExcelVO : successList) {
            Long userId = users.get(staffImportExcelVO.getMobile());
            InspectionStaff inspectionStaff = BeanUtil.copyProperties(staffImportExcelVO, InspectionStaff.class);
            inspectionStaff.setUserId(userId);
            inspectionStaffList.add(inspectionStaff);

            permissionService.assignUserRole(userId, Collections.singleton(staffImportExcelVO.getRoleId()));
        }
        this.saveBatch(inspectionStaffList);
        return 0;
    }

    /**
     * 验证导入员工数据
     *
     * @param list
     * @return
     */
    private ImportStaffVo validImportStaff(List<StaffImportExcelVO> list) {
        List<StaffImportExcelVO> successList = new ArrayList<>();
        List<StaffImportExcelVO> failList = new ArrayList<>();

        //查询检测角色
        RoleDO roleDO = new RoleDO();
        roleDO.setServicePackageId("jiance");
        List<RoleDO> roleDOS = roleService.pageByQuery(roleDO);
        Map<String, Long> roleMap = roleDOS.stream().collect(Collectors.toMap(RoleDO::getName, RoleDO::getId));

        //根据手机号查询员工
        List<AdminUserDO> list1 = userService.list(Wrappers.<AdminUserDO>lambdaQuery().in(AdminUserDO::getMobile, list.stream().map(StaffImportExcelVO::getMobile).collect(Collectors.toList())));
        Map<String, Long> mobileMap = list1.stream().collect(Collectors.toMap(AdminUserDO::getMobile, AdminUserDO::getId));

        //判断第一条数据是否是测试数据
        if (ObjectUtil.isNotEmpty(list)) {
            if ("测试员工".equals(list.get(0).getUsername())) {
                list.remove(0);
            }
        }
        for (StaffImportExcelVO staffImportExcelVO : list) {
            if (ObjectUtil.isNull(staffImportExcelVO)) {
                continue;
            }
            //判断员工姓名是否为空
            if (ObjectUtil.isEmpty(staffImportExcelVO.getUsername())) {
                staffImportExcelVO.setReason("员工姓名不能为空");
                failList.add(staffImportExcelVO);
                continue;
            }
            // 判断手机号是否为空
            if (ObjectUtil.isEmpty(staffImportExcelVO.getMobile())) {
                staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "手机号不能为空");
                failList.add(staffImportExcelVO);
                continue;
            }
            //判断手机号是否存在
            if (ObjectUtil.isNotEmpty(mobileMap.get(staffImportExcelVO.getMobile()))) {
                staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "的手机号已存在");
                failList.add(staffImportExcelVO);
                continue;
            }
            //如果身份证存在验证身份证是否正确
            if (ObjectUtil.isNotEmpty(staffImportExcelVO.getIdCard())) {
                if (!IdcardUtil.isValidCard(staffImportExcelVO.getIdCard())) {
                    staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "身份证格式不正确");
                    failList.add(staffImportExcelVO);
                    continue;
                }
            }
            //判断员工角色是否为空
            if (ObjectUtil.isEmpty(staffImportExcelVO.getRoleName())) {
                staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "员工角色不能为空");
                failList.add(staffImportExcelVO);
                continue;
            }
            //查询员工角色对应id
            Long roleId = roleMap.get(staffImportExcelVO.getRoleName());
            staffImportExcelVO.setRoleId(roleId);
            //如果驾驶证类型不为空，将字符串里的所有英文转成大写
            if (ObjectUtil.isNotEmpty(staffImportExcelVO.getDriverLicenseType())) {
                staffImportExcelVO.setDriverLicenseType(staffImportExcelVO.getDriverLicenseType().toUpperCase());
                //将中文逗号替换为英文
                staffImportExcelVO.setDriverLicenseType(staffImportExcelVO.getDriverLicenseType().replaceAll("，", ","));
            }
            successList.add(staffImportExcelVO);
        }
        ImportStaffVo importStaffVo = new ImportStaffVo();
        importStaffVo.setSuccessList(successList);
        importStaffVo.setFailList(failList);
        return importStaffVo;
    }

    /**
     * 添加员工附件
     *
     * @param fileList 文件集合
     * @param nickname 员工姓名
     * @param fatherId 父级文件夹id
     */
    public void addFile(List<FileDO> fileList, String nickname, Long fatherId, Long userId) {
        if (ObjectUtil.isEmpty(fatherId)) {
            //添加文件夹
            InspectionFile inspectionFile = new InspectionFile();
            inspectionFile.setFileName(nickname + InspectionConstants.INSPECTION_FOLDER_SUFFIX);
            inspectionFile.setType(InspectionConstants.INSPECTION_FOLDER);

            fatherId = inspectionFileService.insertInspectionFile(inspectionFile).getId();

            //更新员工子表中的文件夹id
            this.update(Wrappers.<InspectionStaff>lambdaUpdate()
                    .eq(InspectionStaff::getUserId, userId)
                    .set(InspectionStaff::getFolderId, fatherId));
        } else {

            //删除文件下的所有文件
            inspectionFileService.remove(Wrappers.<InspectionFile>lambdaQuery()
                    .eq(InspectionFile::getFatherId, fatherId)
                    .eq(InspectionFile::getType, InspectionConstants.INSPECTION_FILE)
                    .eq(InspectionFile::getIsStaffFile, InspectionConstants.INSPECTION_IS_STAFF_FILE));
        }

        //添加文件
        List<InspectionFile> fileDOList = new ArrayList<>();
        for (FileDO fileDO : fileList) {
            InspectionFile file = new InspectionFile();
            file.setFileName(removeFileExtension(fileDO.getName()));
            file.setFilePath(fileDO.getUrl());
            file.setType(InspectionConstants.INSPECTION_FILE);
            file.setFatherId(fatherId);
            file.setIsStaffFile(InspectionConstants.INSPECTION_IS_STAFF_FILE);

            fileDOList.add(file);
        }

        //批量插入文件
        inspectionFileService.insertBatchInspectionFile(fileDOList);
    }

    /**
     * 去除文件名中的后缀
     *
     * @param filename
     * @return
     */
    public String removeFileExtension(String filename) {
        if (filename == null) {
            return null; // 或者你可以选择返回一个空字符串，取决于你的业务需求
        }
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return filename; // 如果没有找到点，则返回原文件名
        }
        return filename.substring(0, lastDotIndex);
    }
}

