package com.ruoyi.dpc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.dpc.domain.DpcEmployee;
import com.ruoyi.dpc.domain.DpcEmployeeRelative;
import com.ruoyi.dpc.domain.dto.DpcEmployeeAddDTO;
import com.ruoyi.dpc.domain.dto.DpcEmployeeEditDTO;
import com.ruoyi.dpc.domain.dto.DpcEmployeeQueryDTO;
import com.ruoyi.dpc.domain.dto.DpcEmployeeRelativeAddDTO;
import com.ruoyi.dpc.domain.vo.DpcEmployeeVO;
import com.ruoyi.dpc.mapper.DpcEmployeeMapper;
import com.ruoyi.dpc.mapper.DpcEmployeeRelativeMapper;
import com.ruoyi.dpc.service.IDpcEmployeeService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 员工信息 服务层处理
 *
 * @author ruoyi
 * @date 2026-01-28
 */
@Service
public class DpcEmployeeServiceImpl implements IDpcEmployeeService {

    @Resource
    private DpcEmployeeMapper employeeMapper;

    @Resource
    private DpcEmployeeRelativeMapper relativeMapper;

    /**
     * 查询员工列表
     *
     * @param queryDTO 查询条件
     * @return 员工VO集合
     */
    @Override
    public List<DpcEmployeeVO> selectEmployeeList(DpcEmployeeQueryDTO queryDTO) {
        LambdaQueryWrapper<DpcEmployee> wrapper = buildQueryWrapper(queryDTO);
        List<DpcEmployee> list = employeeMapper.selectList(wrapper);
        List<DpcEmployeeVO> voList = new ArrayList<>();
        for (DpcEmployee employee : list) {
            voList.add(convertToVO(employee));
        }
        return voList;
    }

    /**
     * 查询员工列表（用于导出）
     *
     * @param queryDTO 查询条件
     * @return 员工实体集合
     */
    @Override
    public List<DpcEmployee> selectEmployeeListForExport(DpcEmployeeQueryDTO queryDTO) {
        LambdaQueryWrapper<DpcEmployee> wrapper = buildQueryWrapper(queryDTO);
        return employeeMapper.selectList(wrapper);
    }

    /**
     * 查询员工详情
     *
     * @param employeeId 员工ID
     * @return 员工VO
     */
    @Override
    public DpcEmployeeVO selectEmployeeById(Long employeeId) {
        return employeeMapper.selectEmployeeWithRelatives(employeeId);
    }

    /**
     * 新增员工
     *
     * @param addDTO 新增DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int insertEmployee(DpcEmployeeAddDTO addDTO) {
        // 检查柜员号唯一性
        LambdaQueryWrapper<DpcEmployee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DpcEmployee::getTellerNo, addDTO.getTellerNo());
        if (employeeMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("该柜员号已存在");
        }

        // 检查身份证号唯一性
        wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DpcEmployee::getIdCard, addDTO.getIdCard());
        if (employeeMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("该身份证号已存在");
        }

        DpcEmployee employee = new DpcEmployee();
        BeanUtils.copyProperties(addDTO, employee);
        int result = employeeMapper.insert(employee);

        // 插入亲属信息
        if (addDTO.getRelatives() != null && !addDTO.getRelatives().isEmpty()) {
            for (DpcEmployeeRelativeAddDTO relativeAddDTO : addDTO.getRelatives()) {
                DpcEmployeeRelative relative = new DpcEmployeeRelative();
                BeanUtils.copyProperties(relativeAddDTO, relative);
                relative.setEmployeeId(employee.getEmployeeId());
                relativeMapper.insert(relative);
            }
        }

        return result;
    }

    /**
     * 修改员工
     *
     * @param editDTO 编辑DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int updateEmployee(DpcEmployeeEditDTO editDTO) {
        // 检查柜员号唯一性（排除自己）
        if (StringUtils.isNotEmpty(editDTO.getTellerNo())) {
            LambdaQueryWrapper<DpcEmployee> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DpcEmployee::getTellerNo, editDTO.getTellerNo())
                    .ne(DpcEmployee::getEmployeeId, editDTO.getEmployeeId());
            if (employeeMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("该柜员号已存在");
            }
        }

        // 检查身份证号唯一性（排除自己）
        if (StringUtils.isNotEmpty(editDTO.getIdCard())) {
            LambdaQueryWrapper<DpcEmployee> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DpcEmployee::getIdCard, editDTO.getIdCard())
                    .ne(DpcEmployee::getEmployeeId, editDTO.getEmployeeId());
            if (employeeMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("该身份证号已存在");
            }
        }

        DpcEmployee employee = new DpcEmployee();
        BeanUtils.copyProperties(editDTO, employee);
        int result = employeeMapper.updateById(employee);

        // 删除原有亲属信息
        LambdaQueryWrapper<DpcEmployeeRelative> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DpcEmployeeRelative::getEmployeeId, editDTO.getEmployeeId());
        relativeMapper.delete(wrapper);

        // 插入新的亲属信息
        if (editDTO.getRelatives() != null && !editDTO.getRelatives().isEmpty()) {
            for (DpcEmployeeRelativeAddDTO relativeAddDTO : editDTO.getRelatives()) {
                DpcEmployeeRelative relative = new DpcEmployeeRelative();
                BeanUtils.copyProperties(relativeAddDTO, relative);
                relative.setEmployeeId(editDTO.getEmployeeId());
                relativeMapper.insert(relative);
            }
        }

        return result;
    }

    /**
     * 批量删除员工
     *
     * @param employeeIds 需要删除的员工ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteEmployeeByIds(Long[] employeeIds) {
        // 级联删除亲属信息
        for (Long employeeId : employeeIds) {
            LambdaQueryWrapper<DpcEmployeeRelative> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DpcEmployeeRelative::getEmployeeId, employeeId);
            relativeMapper.delete(wrapper);
        }
        return employeeMapper.deleteBatchIds(List.of(employeeIds));
    }

    /**
     * 导入员工数据
     *
     * @param addDTOList     新增DTO列表
     * @param isUpdateSupport 是否更新支持
     * @return 结果
     */
    @Override
    @Transactional
    public String importEmployee(List<DpcEmployeeAddDTO> addDTOList, Boolean isUpdateSupport) {
        if (StringUtils.isNull(addDTOList) || addDTOList.isEmpty()) {
            return "至少需要一条数据";
        }

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (DpcEmployeeAddDTO addDTO : addDTOList) {
            try {
                // 验证数据
                validateEmployeeData(addDTO, isUpdateSupport);

                DpcEmployee employee = new DpcEmployee();
                BeanUtils.copyProperties(addDTO, employee);

                employeeMapper.insert(employee);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、").append(addDTO.getName()).append(" 导入成功");
            } catch (Exception e) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、").append(addDTO.getName()).append(" 导入失败：");
                failureMsg.append(e.getMessage());
            }
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new RuntimeException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条");
            return successMsg.toString();
        }
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<DpcEmployee> buildQueryWrapper(DpcEmployeeQueryDTO queryDTO) {
        LambdaQueryWrapper<DpcEmployee> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(queryDTO.getName()), DpcEmployee::getName, queryDTO.getName())
                .eq(StringUtils.isNotEmpty(queryDTO.getTellerNo()), DpcEmployee::getTellerNo, queryDTO.getTellerNo())
                .eq(StringUtils.isNotEmpty(queryDTO.getOrgNo()), DpcEmployee::getOrgNo, queryDTO.getOrgNo())
                .eq(StringUtils.isNotEmpty(queryDTO.getIdCard()), DpcEmployee::getIdCard, queryDTO.getIdCard())
                .eq(StringUtils.isNotEmpty(queryDTO.getStatus()), DpcEmployee::getStatus, queryDTO.getStatus())
                .orderByDesc(DpcEmployee::getCreateTime);
        return wrapper;
    }

    /**
     * 验证员工数据
     */
    private void validateEmployeeData(DpcEmployeeAddDTO addDTO, Boolean isUpdateSupport) {
        // 检查柜员号唯一性
        LambdaQueryWrapper<DpcEmployee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DpcEmployee::getTellerNo, addDTO.getTellerNo());
        if (employeeMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("该柜员号已存在");
        }

        // 检查身份证号唯一性
        wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DpcEmployee::getIdCard, addDTO.getIdCard());
        if (employeeMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("该身份证号已存在");
        }

        // 验证状态
        if (!"0".equals(addDTO.getStatus()) && !"1".equals(addDTO.getStatus())) {
            throw new RuntimeException("状态只能填写'在职'或'离职'");
        }
    }

    /**
     * 转换为VO对象
     */
    private DpcEmployeeVO convertToVO(DpcEmployee employee) {
        if (employee == null) {
            return null;
        }

        DpcEmployeeVO vo = new DpcEmployeeVO();
        BeanUtils.copyProperties(employee, vo);

        // 设置状态描述
        if ("0".equals(employee.getStatus())) {
            vo.setStatusDesc("在职");
        } else if ("1".equals(employee.getStatus())) {
            vo.setStatusDesc("离职");
        }

        return vo;
    }
}
