package com.ruoyi.info.collection.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.info.collection.domain.CcdiStaffEnterpriseRelation;
import com.ruoyi.info.collection.domain.CcdiStaffFmyRelation;
import com.ruoyi.info.collection.domain.dto.CcdiStaffEnterpriseRelationAddDTO;
import com.ruoyi.info.collection.domain.dto.CcdiStaffEnterpriseRelationEditDTO;
import com.ruoyi.info.collection.domain.dto.CcdiStaffEnterpriseRelationQueryDTO;
import com.ruoyi.info.collection.domain.excel.CcdiStaffEnterpriseRelationExcel;
import com.ruoyi.info.collection.domain.vo.CcdiStaffEnterpriseRelationOptionVO;
import com.ruoyi.info.collection.domain.vo.CcdiStaffEnterpriseRelationVO;
import com.ruoyi.info.collection.enums.DataSource;
import com.ruoyi.info.collection.enums.EnterpriseSource;
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
import com.ruoyi.info.collection.mapper.CcdiStaffEnterpriseRelationMapper;
import com.ruoyi.info.collection.service.ICcdiStaffEnterpriseRelationImportService;
import com.ruoyi.info.collection.service.ICcdiStaffEnterpriseRelationService;
import com.ruoyi.info.collection.service.support.EnterpriseAutoFillService;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 员工实体关系信息 服务层处理
 *
 * @author ruoyi
 * @date 2026-02-09
 */
@Service
public class CcdiStaffEnterpriseRelationServiceImpl implements ICcdiStaffEnterpriseRelationService {

    @Resource
    private CcdiStaffEnterpriseRelationMapper relationMapper;

    @Resource
    private CcdiStaffFmyRelationMapper familyRelationMapper;

    @Resource
    private ICcdiStaffEnterpriseRelationImportService relationImportService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private EnterpriseAutoFillService enterpriseAutoFillService;

    /**
     * 查询员工实体关系列表
     *
     * @param queryDTO 查询条件
     * @return 员工实体关系VO集合
     */
    @Override
    public java.util.List<CcdiStaffEnterpriseRelationVO> selectRelationList(CcdiStaffEnterpriseRelationQueryDTO queryDTO) {
        Page<CcdiStaffEnterpriseRelationVO> page = new Page<>(1, Integer.MAX_VALUE);
        Page<CcdiStaffEnterpriseRelationVO> resultPage = relationMapper.selectRelationPage(page, queryDTO);
        return resultPage.getRecords();
    }

    /**
     * 分页查询员工实体关系列表
     *
     * @param page     分页对象
     * @param queryDTO 查询条件
     * @return 员工实体关系VO分页结果
     */
    @Override
    public Page<CcdiStaffEnterpriseRelationVO> selectRelationPage(Page<CcdiStaffEnterpriseRelationVO> page, CcdiStaffEnterpriseRelationQueryDTO queryDTO) {
        return relationMapper.selectRelationPage(page, queryDTO);
    }

    /**
     * 查询员工实体关系列表（用于导出）
     *
     * @param queryDTO 查询条件
     * @return 员工实体关系Excel实体集合
     */
    @Override
    public java.util.List<CcdiStaffEnterpriseRelationExcel> selectRelationListForExport(CcdiStaffEnterpriseRelationQueryDTO queryDTO) {
        Page<CcdiStaffEnterpriseRelationVO> page = new Page<>(1, Integer.MAX_VALUE);
        Page<CcdiStaffEnterpriseRelationVO> resultPage = relationMapper.selectRelationPage(page, queryDTO);

        return resultPage.getRecords().stream().map(vo -> {
            CcdiStaffEnterpriseRelationExcel excel = new CcdiStaffEnterpriseRelationExcel();
            BeanUtils.copyProperties(vo, excel);
            return excel;
        }).collect(Collectors.toList());
    }

    @Override
    public java.util.List<CcdiStaffEnterpriseRelationOptionVO> selectFamilyOptions(String query) {
        return relationMapper.selectFamilyOptions(query);
    }

    /**
     * 查询员工实体关系详情
     *
     * @param id 主键ID
     * @return 员工实体关系VO
     */
    @Override
    public CcdiStaffEnterpriseRelationVO selectRelationById(Long id) {
        return relationMapper.selectRelationById(id);
    }

    /**
     * 新增员工实体关系
     *
     * @param addDTO 新增DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int insertRelation(CcdiStaffEnterpriseRelationAddDTO addDTO) {
        validateEffectiveFamily(addDTO.getPersonId());

        if (relationMapper.existsByPersonIdAndSocialCreditCode(addDTO.getPersonId(), addDTO.getSocialCreditCode())) {
            throw new RuntimeException("该亲属身份证号和统一社会信用代码组合已存在");
        }

        CcdiStaffEnterpriseRelation relation = new CcdiStaffEnterpriseRelation();
        BeanUtils.copyProperties(addDTO, relation);

        relation.setStatus(1);

        if (relation.getIsEmployee() == null) {
            relation.setIsEmployee(0);
        }
        if (relation.getIsEmpFamily() == null) {
            relation.setIsEmpFamily(1);
        }
        if (relation.getIsCustomer() == null) {
            relation.setIsCustomer(0);
        }
        if (relation.getIsCustFamily() == null) {
            relation.setIsCustFamily(0);
        }
        if (StringUtils.isEmpty(relation.getDataSource())) {
            relation.setDataSource("MANUAL");
        }

        enterpriseAutoFillService.ensureExists(new EnterpriseAutoFillService.EnterpriseFillItem(
                addDTO.getSocialCreditCode(),
                addDTO.getEnterpriseName(),
                EnterpriseSource.EMP_RELATION.getCode(),
                DataSource.MANUAL.getCode(),
                SecurityUtils.getUsername()
        ));

        int result = relationMapper.insert(relation);

        return result;
    }

    /**
     * 修改员工实体关系
     *
     * @param editDTO 编辑DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int updateRelation(CcdiStaffEnterpriseRelationEditDTO editDTO) {
        // 使用LambdaUpdateWrapper只更新非null字段，保护系统字段不被覆盖
        LambdaUpdateWrapper<CcdiStaffEnterpriseRelation> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(CcdiStaffEnterpriseRelation::getId, editDTO.getId());

        // 只更新前端可编辑的字段
        updateWrapper.set(editDTO.getRelationPersonPost() != null, CcdiStaffEnterpriseRelation::getRelationPersonPost, editDTO.getRelationPersonPost());
        updateWrapper.set(editDTO.getEnterpriseName() != null, CcdiStaffEnterpriseRelation::getEnterpriseName, editDTO.getEnterpriseName());
        updateWrapper.set(editDTO.getStatus() != null, CcdiStaffEnterpriseRelation::getStatus, editDTO.getStatus());
        updateWrapper.set(editDTO.getRemark() != null, CcdiStaffEnterpriseRelation::getRemark, editDTO.getRemark());

        // 注意：以下字段不可修改
        // - personId（亲属身份证号，业务主键）
        // - socialCreditCode（统一社会信用代码，业务主键）
        // - dataSource（数据来源，系统字段）
        // - isEmployee（是否为员工，系统字段）
        // - isEmpFamily（是否为员工家属，系统字段）
        // - isCustomer（是否为客户，系统字段）
        // - isCustFamily（是否为客户家属，系统字段）

        int result = relationMapper.update(null, updateWrapper);

        return result;
    }

    /**
     * 批量删除员工实体关系
     *
     * @param ids 需要删除的主键ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteRelationByIds(Long[] ids) {
        return relationMapper.deleteBatchIds(java.util.List.of(ids));
    }

    /**
     * 导入员工实体关系数据（异步）
     *
     * @param excelList Excel实体列表
     * @return 任务ID
     */
    @Override
    @Transactional
    public String importRelation(java.util.List<CcdiStaffEnterpriseRelationExcel> excelList) {
        if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
            throw new RuntimeException("至少需要一条数据");
        }

        // 生成任务ID
        String taskId = UUID.randomUUID().toString();
        long startTime = System.currentTimeMillis();

        // 获取当前用户名
        String userName = SecurityUtils.getUsername();

        // 初始化Redis状态
        String statusKey = "import:staffEnterpriseRelation:" + taskId;
        Map<String, Object> statusData = new HashMap<>();
        statusData.put("taskId", taskId);
        statusData.put("status", "PROCESSING");
        statusData.put("totalCount", excelList.size());
        statusData.put("successCount", 0);
        statusData.put("failureCount", 0);
        statusData.put("progress", 0);
        statusData.put("startTime", startTime);
        statusData.put("message", "正在处理...");

        redisTemplate.opsForHash().putAll(statusKey, statusData);
        redisTemplate.expire(statusKey, 7, TimeUnit.DAYS);

        // 调用异步导入服务
        relationImportService.importRelationAsync(excelList, taskId, userName);

        return taskId;
    }

    private CcdiStaffFmyRelation validateEffectiveFamily(String familyCertNo) {
        CcdiStaffFmyRelation validFamily = familyRelationMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<CcdiStaffFmyRelation>()
                        .eq(CcdiStaffFmyRelation::getRelationCertNo, familyCertNo)
                        .eq(CcdiStaffFmyRelation::getIsEmpFamily, Boolean.TRUE)
                        .eq(CcdiStaffFmyRelation::getStatus, 1)
                        .last("LIMIT 1")
        );
        if (validFamily != null) {
            return validFamily;
        }

        CcdiStaffFmyRelation existingFamily = familyRelationMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<CcdiStaffFmyRelation>()
                        .select(CcdiStaffFmyRelation::getId)
                        .eq(CcdiStaffFmyRelation::getRelationCertNo, familyCertNo)
                        .last("LIMIT 1")
        );
        if (existingFamily == null) {
            throw new RuntimeException("亲属身份证号[" + familyCertNo + "]不存在，请先维护员工亲属关系");
        }
        throw new RuntimeException("亲属身份证号[" + familyCertNo + "]不是有效员工亲属，请先维护有效的员工亲属关系");
    }
}
