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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.info.collection.domain.CcdiBizIntermediary;
import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo;
import com.ruoyi.info.collection.domain.CcdiIntermediaryEnterpriseRelation;
import com.ruoyi.info.collection.domain.dto.*;
import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryEnterpriseRelationExcel;
import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryEntityExcel;
import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryPersonExcel;
import com.ruoyi.info.collection.domain.vo.CcdiIntermediaryEnterpriseRelationVO;
import com.ruoyi.info.collection.domain.vo.CcdiIntermediaryEntityDetailVO;
import com.ruoyi.info.collection.domain.vo.CcdiIntermediaryPersonDetailVO;
import com.ruoyi.info.collection.domain.vo.CcdiIntermediaryRelativeVO;
import com.ruoyi.info.collection.domain.vo.CcdiIntermediaryVO;
import com.ruoyi.info.collection.enums.DataSource;
import com.ruoyi.info.collection.enums.EnterpriseSource;
import com.ruoyi.info.collection.mapper.CcdiBizIntermediaryMapper;
import com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper;
import com.ruoyi.info.collection.mapper.CcdiIntermediaryEnterpriseRelationMapper;
import com.ruoyi.info.collection.mapper.CcdiIntermediaryMapper;
import com.ruoyi.info.collection.service.ICcdiIntermediaryEnterpriseRelationImportService;
import com.ruoyi.info.collection.service.ICcdiIntermediaryEntityImportService;
import com.ruoyi.info.collection.service.ICcdiIntermediaryPersonImportService;
import com.ruoyi.info.collection.service.ICcdiIntermediaryService;
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.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 中介Service业务层处理
 *
 * @author ruoyi
 * @date 2026-02-04
 */
@Service
public class CcdiIntermediaryServiceImpl implements ICcdiIntermediaryService {

    @Resource
    private CcdiBizIntermediaryMapper bizIntermediaryMapper;

    @Resource
    private CcdiEnterpriseBaseInfoMapper enterpriseBaseInfoMapper;

    @Resource
    private CcdiIntermediaryMapper intermediaryMapper;

    @Resource
    private CcdiIntermediaryEnterpriseRelationMapper enterpriseRelationMapper;

    @Resource
    private ICcdiIntermediaryPersonImportService personImportService;

    @Resource
    private ICcdiIntermediaryEntityImportService entityImportService;

    @Resource
    private ICcdiIntermediaryEnterpriseRelationImportService enterpriseRelationImportService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private EnterpriseAutoFillService enterpriseAutoFillService;

    /**
     * 分页查询中介列表
     * 使用XML联合查询实现,支持个人中介和实体中介的灵活查询
     * 使用MyBatis Plus分页插件自动处理分页
     *
     * @param page     分页对象
     * @param queryDTO 查询条件
     * @return 中介VO分页结果
     */
    @Override
    public Page<CcdiIntermediaryVO> selectIntermediaryPage(Page<CcdiIntermediaryVO> page, CcdiIntermediaryQueryDTO queryDTO) {
        // 直接调用Mapper的联合查询方法，MyBatis Plus会自动处理分页
        return intermediaryMapper.selectIntermediaryList(page, queryDTO);
    }

    /**
     * 查询个人中介详情
     *
     * @param bizId 人员ID
     * @return 个人中介详情VO
     */
    @Override
    public CcdiIntermediaryPersonDetailVO selectIntermediaryPersonDetail(String bizId) {
        CcdiBizIntermediary person = bizIntermediaryMapper.selectById(bizId);
        if (person == null || !isIntermediaryPerson(person)) {
            return null;
        }

        CcdiIntermediaryPersonDetailVO vo = new CcdiIntermediaryPersonDetailVO();
        BeanUtils.copyProperties(person, vo);
        // 设置中介类型为个人
        vo.setIntermediaryType("1");
        return vo;
    }

    @Override
    public List<CcdiIntermediaryRelativeVO> selectIntermediaryRelativeList(String bizId) {
        CcdiBizIntermediary owner = requireIntermediaryPerson(bizId);
        LambdaQueryWrapper<CcdiBizIntermediary> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CcdiBizIntermediary::getRelatedNumId, owner.getPersonId())
                .ne(CcdiBizIntermediary::getPersonSubType, "本人")
                .orderByDesc(CcdiBizIntermediary::getCreateTime);
        return bizIntermediaryMapper.selectList(wrapper).stream().map(this::buildRelativeVo).toList();
    }

    @Override
    public CcdiIntermediaryRelativeVO selectIntermediaryRelativeDetail(String relativeBizId) {
        CcdiBizIntermediary relative = bizIntermediaryMapper.selectById(relativeBizId);
        if (relative == null || isIntermediaryPerson(relative)) {
            return null;
        }
        return buildRelativeVo(relative);
    }

    /**
     * 查询实体中介详情
     *
     * @param socialCreditCode 统一社会信用代码
     * @return 实体中介详情VO
     */
    @Override
    public CcdiIntermediaryEntityDetailVO selectIntermediaryEntityDetail(String socialCreditCode) {
        CcdiEnterpriseBaseInfo entity = enterpriseBaseInfoMapper.selectById(socialCreditCode);
        if (entity == null) {
            return null;
        }

        CcdiIntermediaryEntityDetailVO vo = new CcdiIntermediaryEntityDetailVO();
        BeanUtils.copyProperties(entity, vo);
        // 设置中介类型为实体
        vo.setIntermediaryType("2");
        // 设置业务ID(使用socialCreditCode作为bizId,前端判断是否为新增模式)
        vo.setBizId(socialCreditCode);
        return vo;
    }

    /**
     * 新增个人中介
     *
     * @param addDTO 新增DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int insertIntermediaryPerson(CcdiIntermediaryPersonAddDTO addDTO) {
        // 检查人员ID唯一性
        if (!checkPersonIdUnique(addDTO.getPersonId(), null)) {
            throw new RuntimeException("该证件号已存在");
        }

        CcdiBizIntermediary person = new CcdiBizIntermediary();
        BeanUtils.copyProperties(addDTO, person);
        person.setPersonSubType("本人");
        person.setRelatedNumId(null);
        person.setDataSource("MANUAL");

        return bizIntermediaryMapper.insert(person);
    }

    /**
     * 修改个人中介
     *
     * @param editDTO 编辑DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int updateIntermediaryPerson(CcdiIntermediaryPersonEditDTO editDTO) {
        // 检查人员ID唯一性（排除自己）
        if (StringUtils.isNotEmpty(editDTO.getPersonId())) {
            if (!checkPersonIdUnique(editDTO.getPersonId(), editDTO.getBizId())) {
                throw new RuntimeException("该证件号已存在");
            }
        }

        CcdiBizIntermediary existing = bizIntermediaryMapper.selectById(editDTO.getBizId());
        if (existing == null || !isIntermediaryPerson(existing)) {
            throw new RuntimeException("中介本人不存在");
        }

        CcdiBizIntermediary person = new CcdiBizIntermediary();
        BeanUtils.copyProperties(editDTO, person);
        person.setPersonSubType("本人");
        person.setRelatedNumId(null);
        int updated = bizIntermediaryMapper.updateById(person);
        syncRelativeOwnerPersonId(existing.getPersonId(), editDTO.getPersonId());
        return updated;
    }

    @Override
    @Transactional
    public int insertIntermediaryRelative(String bizId, CcdiIntermediaryRelativeAddDTO addDTO) {
        CcdiBizIntermediary owner = requireIntermediaryPerson(bizId);
        validateRelativePersonSubType(addDTO.getPersonSubType());
        if (!checkRelativePersonUnique(owner.getPersonId(), addDTO.getPersonId(), null)) {
            throw new RuntimeException("该中介本人下已存在相同证件号亲属");
        }

        CcdiBizIntermediary relative = new CcdiBizIntermediary();
        BeanUtils.copyProperties(addDTO, relative);
        relative.setRelatedNumId(owner.getPersonId());
        relative.setDataSource("MANUAL");
        return bizIntermediaryMapper.insert(relative);
    }

    @Override
    @Transactional
    public int updateIntermediaryRelative(CcdiIntermediaryRelativeEditDTO editDTO) {
        CcdiBizIntermediary existing = bizIntermediaryMapper.selectById(editDTO.getBizId());
        if (existing == null || isIntermediaryPerson(existing)) {
            throw new RuntimeException("中介亲属不存在");
        }
        validateRelativePersonSubType(editDTO.getPersonSubType());
        if (StringUtils.isNotEmpty(editDTO.getPersonId())
                && !checkRelativePersonUnique(existing.getRelatedNumId(), editDTO.getPersonId(), editDTO.getBizId())) {
            throw new RuntimeException("该中介本人下已存在相同证件号亲属");
        }

        CcdiBizIntermediary relative = new CcdiBizIntermediary();
        BeanUtils.copyProperties(editDTO, relative);
        relative.setRelatedNumId(existing.getRelatedNumId());
        return bizIntermediaryMapper.updateById(relative);
    }

    @Override
    @Transactional
    public int deleteIntermediaryRelative(String relativeBizId) {
        CcdiBizIntermediary existing = bizIntermediaryMapper.selectById(relativeBizId);
        if (existing == null || isIntermediaryPerson(existing)) {
            throw new RuntimeException("中介亲属不存在");
        }
        return bizIntermediaryMapper.deleteById(relativeBizId);
    }

    /**
     * 新增实体中介
     *
     * @param addDTO 新增DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int insertIntermediaryEntity(CcdiIntermediaryEntityAddDTO addDTO) {
        // 检查统一社会信用代码唯一性
        if (StringUtils.isNotEmpty(addDTO.getSocialCreditCode())) {
            if (!checkSocialCreditCodeUnique(addDTO.getSocialCreditCode(), null)) {
                throw new RuntimeException("该统一社会信用代码已存在");
            }
        }

        CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
        BeanUtils.copyProperties(addDTO, entity);
        entity.setRiskLevel("1");
        entity.setEntSource("INTERMEDIARY");
        entity.setDataSource("MANUAL");

        return enterpriseBaseInfoMapper.insert(entity);
    }

    /**
     * 修改实体中介
     *
     * @param editDTO 编辑DTO
     * @return 结果
     */
    @Override
    @Transactional
    public int updateIntermediaryEntity(CcdiIntermediaryEntityEditDTO editDTO) {
        CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
        BeanUtils.copyProperties(editDTO, entity);

        return enterpriseBaseInfoMapper.updateById(entity);
    }

    @Override
    public List<CcdiIntermediaryEnterpriseRelationVO> selectIntermediaryEnterpriseRelationList(String bizId) {
        return enterpriseRelationMapper.selectByIntermediaryBizId(bizId);
    }

    @Override
    public CcdiIntermediaryEnterpriseRelationVO selectIntermediaryEnterpriseRelationDetail(Long id) {
        return enterpriseRelationMapper.selectDetailById(id);
    }

    @Override
    @Transactional
    public int insertIntermediaryEnterpriseRelation(String bizId, CcdiIntermediaryEnterpriseRelationAddDTO addDTO) {
        CcdiBizIntermediary owner = requireIntermediaryPerson(bizId);
        validateEnterpriseRelation(owner.getBizId(), addDTO.getSocialCreditCode(), null);

        CcdiIntermediaryEnterpriseRelation relation = new CcdiIntermediaryEnterpriseRelation();
        BeanUtils.copyProperties(addDTO, relation);
        relation.setIntermediaryBizId(owner.getBizId());
        enterpriseAutoFillService.ensureExists(new EnterpriseAutoFillService.EnterpriseFillItem(
                addDTO.getSocialCreditCode(),
                null,
                EnterpriseSource.INTERMEDIARY.getCode(),
                DataSource.MANUAL.getCode(),
                SecurityUtils.getUsername()
        ));
        return enterpriseRelationMapper.insert(relation);
    }

    @Override
    @Transactional
    public int updateIntermediaryEnterpriseRelation(CcdiIntermediaryEnterpriseRelationEditDTO editDTO) {
        CcdiIntermediaryEnterpriseRelation existing = enterpriseRelationMapper.selectById(editDTO.getId());
        if (existing == null) {
            throw new RuntimeException("中介关联机构不存在");
        }
        validateEnterpriseRelation(existing.getIntermediaryBizId(), editDTO.getSocialCreditCode(), existing.getId());

        CcdiIntermediaryEnterpriseRelation relation = new CcdiIntermediaryEnterpriseRelation();
        BeanUtils.copyProperties(editDTO, relation);
        relation.setIntermediaryBizId(existing.getIntermediaryBizId());
        enterpriseAutoFillService.ensureExists(new EnterpriseAutoFillService.EnterpriseFillItem(
                editDTO.getSocialCreditCode(),
                null,
                EnterpriseSource.INTERMEDIARY.getCode(),
                DataSource.MANUAL.getCode(),
                SecurityUtils.getUsername()
        ));
        return enterpriseRelationMapper.updateById(relation);
    }

    @Override
    @Transactional
    public int deleteIntermediaryEnterpriseRelation(Long id) {
        return enterpriseRelationMapper.deleteById(id);
    }

    /**
     * 批量删除中介
     *
     * @param ids 需要删除的ID数组
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteIntermediaryByIds(String[] ids) {
        int count = 0;
        for (String id : ids) {
            CcdiBizIntermediary intermediary = bizIntermediaryMapper.selectById(id);
            if (intermediary != null) {
                if (isIntermediaryPerson(intermediary)) {
                    bizIntermediaryMapper.delete(new LambdaQueryWrapper<CcdiBizIntermediary>()
                            .eq(CcdiBizIntermediary::getRelatedNumId, intermediary.getPersonId())
                            .ne(CcdiBizIntermediary::getPersonSubType, "本人"));
                    enterpriseRelationMapper.delete(new LambdaQueryWrapper<CcdiIntermediaryEnterpriseRelation>()
                            .eq(CcdiIntermediaryEnterpriseRelation::getIntermediaryBizId, id));
                }
                count += bizIntermediaryMapper.deleteById(id);
                continue;
            }

            if (enterpriseBaseInfoMapper.selectById(id) != null) {
                count += enterpriseBaseInfoMapper.deleteById(id);
            }
        }
        return count;
    }

    /**
     * 校验人员ID唯一性
     *
     * @param personId 人员ID
     * @param bizId    排除的人员ID
     * @return true=唯一, false=不唯一
     */
    @Override
    public boolean checkPersonIdUnique(String personId, String bizId) {
        LambdaQueryWrapper<CcdiBizIntermediary> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CcdiBizIntermediary::getPersonId, personId)
                .eq(CcdiBizIntermediary::getPersonSubType, "本人");
        if (StringUtils.isNotEmpty(bizId)) {
            wrapper.ne(CcdiBizIntermediary::getBizId, bizId);
        }
        return bizIntermediaryMapper.selectCount(wrapper) == 0;
    }

    /**
     * 校验统一社会信用代码唯一性
     *
     * @param socialCreditCode 统一社会信用代码
     * @param excludeId        排除的ID
     * @return true=唯一, false=不唯一
     */
    @Override
    public boolean checkSocialCreditCodeUnique(String socialCreditCode, String excludeId) {
        LambdaQueryWrapper<CcdiEnterpriseBaseInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CcdiEnterpriseBaseInfo::getSocialCreditCode, socialCreditCode);
        if (StringUtils.isNotEmpty(excludeId)) {
            wrapper.ne(CcdiEnterpriseBaseInfo::getSocialCreditCode, excludeId);
        }
        return enterpriseBaseInfoMapper.selectCount(wrapper) == 0;
    }

    /**
     * 导入个人中介数据(异步)
     *
     * @param list Excel实体列表
     * @return 任务ID
     */
    @Override
    @Transactional
    public String importIntermediaryPerson(List<CcdiIntermediaryPersonExcel> list) {
        String taskId = UUID.randomUUID().toString();
        long startTime = System.currentTimeMillis();

        // 初始化Redis状态
        String statusKey = "import:intermediary:" + taskId;
        Map<String, Object> statusData = new HashMap<>();
        statusData.put("taskId", taskId);
        statusData.put("status", "PROCESSING");
        statusData.put("totalCount", list.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);

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

        // 调用异步方法
        personImportService.importPersonAsync(list, taskId, userName);

        return taskId;
    }

    @Override
    @Transactional
    public String importIntermediaryEnterpriseRelation(List<CcdiIntermediaryEnterpriseRelationExcel> list) {
        String taskId = UUID.randomUUID().toString();
        long startTime = System.currentTimeMillis();

        String statusKey = "import:intermediary-enterprise-relation:" + taskId;
        Map<String, Object> statusData = new HashMap<>();
        statusData.put("taskId", taskId);
        statusData.put("status", "PROCESSING");
        statusData.put("totalCount", list.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);

        String userName = SecurityUtils.getUsername();
        enterpriseRelationImportService.importAsync(list, taskId, userName);
        return taskId;
    }

    /**
     * 导入实体中介数据(异步)
     *
     * @param list Excel实体列表
     * @return 任务ID
     */
    @Override
    @Transactional
    public String importIntermediaryEntity(List<CcdiIntermediaryEntityExcel> list) {
        String taskId = UUID.randomUUID().toString();
        long startTime = System.currentTimeMillis();

        // 初始化Redis状态
        String statusKey = "import:intermediary-entity:" + taskId;
        Map<String, Object> statusData = new HashMap<>();
        statusData.put("taskId", taskId);
        statusData.put("status", "PROCESSING");
        statusData.put("totalCount", list.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);

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

        // 调用异步方法
        entityImportService.importEntityAsync(list, taskId, userName);

        return taskId;
    }

    private boolean isIntermediaryPerson(CcdiBizIntermediary person) {
        return "本人".equals(person.getPersonSubType());
    }

    private CcdiBizIntermediary requireIntermediaryPerson(String bizId) {
        CcdiBizIntermediary owner = bizIntermediaryMapper.selectById(bizId);
        if (owner == null || !isIntermediaryPerson(owner)) {
            throw new RuntimeException("中介本人不存在");
        }
        return owner;
    }

    private void validateRelativePersonSubType(String personSubType) {
        if ("本人".equals(personSubType)) {
            throw new RuntimeException("亲属关系不能为本人");
        }
    }

    private boolean checkRelativePersonUnique(String ownerPersonId, String personId, String excludeBizId) {
        LambdaQueryWrapper<CcdiBizIntermediary> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CcdiBizIntermediary::getRelatedNumId, ownerPersonId)
                .eq(CcdiBizIntermediary::getPersonId, personId)
                .ne(CcdiBizIntermediary::getPersonSubType, "本人");
        if (StringUtils.isNotEmpty(excludeBizId)) {
            wrapper.ne(CcdiBizIntermediary::getBizId, excludeBizId);
        }
        return bizIntermediaryMapper.selectCount(wrapper) == 0;
    }

    private void validateEnterpriseRelation(String bizId, String socialCreditCode, Long excludeId) {
        requireIntermediaryPerson(bizId);
        boolean exists = enterpriseRelationMapper.existsByIntermediaryBizIdAndSocialCreditCode(bizId, socialCreditCode);
        if (exists) {
            if (excludeId == null) {
                throw new RuntimeException("该中介已关联此机构");
            }
            CcdiIntermediaryEnterpriseRelation existing = enterpriseRelationMapper.selectById(excludeId);
            if (existing == null || !socialCreditCode.equals(existing.getSocialCreditCode())) {
                throw new RuntimeException("该中介已关联此机构");
            }
        }
    }

    private void syncRelativeOwnerPersonId(String oldOwnerPersonId, String newOwnerPersonId) {
        if (StringUtils.isEmpty(oldOwnerPersonId)
                || StringUtils.isEmpty(newOwnerPersonId)
                || oldOwnerPersonId.equals(newOwnerPersonId)) {
            return;
        }

        CcdiBizIntermediary relative = new CcdiBizIntermediary();
        relative.setRelatedNumId(newOwnerPersonId);
        bizIntermediaryMapper.update(relative, new LambdaQueryWrapper<CcdiBizIntermediary>()
                .eq(CcdiBizIntermediary::getRelatedNumId, oldOwnerPersonId)
                .ne(CcdiBizIntermediary::getPersonSubType, "本人"));
    }

    private CcdiIntermediaryRelativeVO buildRelativeVo(CcdiBizIntermediary relative) {
        CcdiIntermediaryRelativeVO vo = new CcdiIntermediaryRelativeVO();
        BeanUtils.copyProperties(relative, vo);
        return vo;
    }
}
