package com.cy.guoyan.admin.module.guoyan.service.researchtopicinfo;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.cy.guoyan.admin.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cy.guoyan.admin.framework.security.core.util.SecurityFrameworkUtils;
import com.cy.guoyan.admin.module.guoyan.dal.dataobject.researchtopiccategory.ResearchTopicCategoryDO;
import com.cy.guoyan.admin.module.guoyan.dal.mysql.researchtopiccategory.ResearchTopicCategoryMapper;
import com.cy.guoyan.admin.module.infra.controller.admin.file.vo.file.FileVO;
import com.cy.guoyan.admin.module.infra.dal.dataobject.file.FileDO;
import com.cy.guoyan.admin.module.infra.dal.mysql.file.FileMapper;
import com.cy.guoyan.admin.module.system.enums.common.JobTypeCodeConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

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

import com.cy.guoyan.admin.module.guoyan.controller.admin.researchtopicinfo.vo.*;
import com.cy.guoyan.admin.module.guoyan.dal.dataobject.researchtopicinfo.ResearchTopicInfoDO;
import com.cy.guoyan.admin.framework.common.pojo.PageResult;
import com.cy.guoyan.admin.framework.common.util.object.BeanUtils;

import com.cy.guoyan.admin.module.guoyan.dal.mysql.researchtopicinfo.ResearchTopicInfoMapper;

import static com.cy.guoyan.admin.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cy.guoyan.admin.framework.common.util.collection.CollectionUtils.convertList;
import static com.cy.guoyan.admin.module.system.enums.ErrorCodeConstants.*;

/**
 * 国资研究专题信息 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class ResearchTopicInfoServiceImpl implements ResearchTopicInfoService {

    @Resource
    private ResearchTopicInfoMapper researchTopicInfoMapper;

    @Resource
    private FileMapper fileMapper;

    @Resource
    private ResearchTopicCategoryMapper researchTopicCategoryMapper;


    @Override
    public Long createResearchTopicInfo(ResearchTopicInfoSaveReqVO createReqVO) {
        String nickname = String.valueOf(SecurityFrameworkUtils.getLoginUser().getInfo().get("nickname"));
        ResearchTopicInfoDO data = BeanUtils.toBean(createReqVO, ResearchTopicInfoDO.class);
        data.setCreatorName(nickname);
        DefaultIdentifierGenerator generator = new DefaultIdentifierGenerator();
        data.setId(generator.nextId(null));
        data.setAuditStatus("未审核");
        data.setStatus("正常");
        if (createReqVO.getOriginalPubDate() != null) {
            String year = createReqVO.getOriginalPubDate().substring(0, 4);
            data.setOriginalPubYear(Integer.parseInt(year));
        }
        data.setImported("0");
        if (StringUtils.isNotBlank(createReqVO.getImage())) {
            createReqVO.setImageDate(extractDate(createReqVO.getImage()));
        }

        researchTopicInfoMapper.insert(data);
        if (createReqVO.getFileList() != null) {
            createReqVO.getFileList().forEach(file -> {
                file.setJobTypeCode(JobTypeCodeConstants.GUO_ZI_RESEARCH_TOPIC_INFO);
                file.setBusinessId(String.valueOf(data.getId()));
                List<FileDO> fileDOList =BeanUtils.toBean(createReqVO.getFileList(), FileDO.class);
                fileMapper.updateBatch(fileDOList);
            });
        }

        if (StringUtils.isNotBlank(createReqVO.getTopicCategoryCode())) {
            String topicCategoryCodeStr = createReqVO.getTopicCategoryCode();
            List<String> codeList = Arrays.stream(topicCategoryCodeStr.split("\\."))
                    .filter(StringUtils::isNotBlank)
                    .collect(Collectors.toList());

            List<ResearchTopicCategoryDO> categoryList =
                    researchTopicCategoryMapper.selectList(
                            new LambdaQueryWrapperX<ResearchTopicCategoryDO>()
                                    .in(ResearchTopicCategoryDO::getCategoryCode, codeList));

            categoryList.forEach(item ->
                    item.setArticleCount(
                            Optional.ofNullable(item.getArticleCount()).orElse(0) + 1));
            researchTopicCategoryMapper.updateBatch(categoryList);
        }

        // 返回
        return data.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateResearchTopicInfo(ResearchTopicInfoSaveReqVO updateReqVO) {
        // 1. 获取当前用户昵称
        String nickname = String.valueOf(
                SecurityFrameworkUtils.getLoginUser().getInfo().get("nickname"));

        // 2. 查询旧业务数据
        ResearchTopicInfoDO old = researchTopicInfoMapper.selectById(updateReqVO.getId());
        if (old == null) {
            throw exception(RESEARCH_TOPIC_INFO_NOT_EXISTS);
        }

        // 3. 查询旧附件
        List<FileDO> oldFiles = fileMapper.selectList(new LambdaQueryWrapperX<FileDO>()
                .eq(FileDO::getBusinessId, old.getId())
                .eq(FileDO::getJobTypeCode, JobTypeCodeConstants.GUO_ZI_RESEARCH_TOPIC_INFO));

        // 4. 取新附件（前端应传文件 ID 列表）
        List<Long> newFileIds = Optional.ofNullable(updateReqVO.getFileList())
                .orElse(Collections.emptyList())
                .stream()
                .map(FileVO::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 5. 做 diff
        Set<Long> oldSet = oldFiles.stream()
                .map(FileDO::getId)
                .collect(Collectors.toSet());
        Set<Long> newSet = new HashSet<>(newFileIds);

        // old - new => 需要移除的旧文件
        List<Long> removeIds = oldSet.stream()
                .filter(id -> !newSet.contains(id))
                .collect(Collectors.toList());

        // new - old => 需要新增绑定的文件
        List<Long> addIds = newSet.stream()
                .filter(id -> !oldSet.contains(id))
                .collect(Collectors.toList());

        // 6. 处理删除
        if (!removeIds.isEmpty()) {
            fileMapper.deleteByIds(removeIds);
        }

        if (StringUtils.isNotBlank(updateReqVO.getImage())) {
            updateReqVO.setImageDate(extractDate(updateReqVO.getImage()));
        }

        // 7. 处理新增
        if (!addIds.isEmpty()) {
            List<FileVO> fileList = updateReqVO.getFileList().stream()
                    .filter(fileVO -> fileVO.getId() != null && addIds.contains(fileVO.getId()))
                    .collect(Collectors.toList());

            fileList.forEach(f-> {
                f.setJobTypeCode(JobTypeCodeConstants.GUO_ZI_RESEARCH_TOPIC_INFO);
                f.setBusinessId(String.valueOf(updateReqVO.getId()));
            });

            List<FileDO> addFileList =BeanUtils.toBean(fileList, FileDO.class);
            fileMapper.updateBatch(addFileList);
        }


        // 8. 更新业务表本身
        ResearchTopicInfoDO updateObj = BeanUtils.toBean(updateReqVO, ResearchTopicInfoDO.class);
        updateObj.setUpdaterName(nickname);
        researchTopicInfoMapper.updateById(updateObj);
    }


    @Override
    public void deleteResearchTopicInfo(Long id) {
        // 校验存在
        validateResearchTopicInfoExists(id);
        // 删除
        researchTopicInfoMapper.deleteById(id);
    }

    @Override
        public void deleteResearchTopicInfoListByIds(List<Long> ids) {
        // 校验存在
        validateResearchTopicInfoExists(ids);
        // 删除
        researchTopicInfoMapper.deleteByIds(ids);
        }

    private void validateResearchTopicInfoExists(List<Long> ids) {
        List<ResearchTopicInfoDO> list = researchTopicInfoMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(RESEARCH_TOPIC_INFO_NOT_EXISTS);
        }
    }

    private void validateResearchTopicInfoExists(Long id) {
        if (researchTopicInfoMapper.selectById(id) == null) {
            throw exception(RESEARCH_TOPIC_INFO_NOT_EXISTS);
        }
    }

    @Override
    public ResearchTopicInfoRespVO getResearchTopicInfo(Long id) {
        ResearchTopicInfoDO infoDO = researchTopicInfoMapper.selectById(id);
        if (infoDO == null) {
            throw exception(RESEARCH_TOPIC_INFO_NOT_EXISTS);
        }

        ResearchTopicInfoRespVO bean = BeanUtils.toBean(infoDO, ResearchTopicInfoRespVO.class);

        List<FileDO> fileList = fileMapper.selectList(new LambdaQueryWrapperX<FileDO>()
                .eq(FileDO::getBusinessId, String.valueOf(id))
                .eq(FileDO::getJobTypeCode, JobTypeCodeConstants.GUO_ZI_RESEARCH_TOPIC_INFO));

        List<FileVO> fileRespVOList =BeanUtils.toBean(fileList, FileVO.class);

        bean.setFileList(fileRespVOList);

        return bean;
    }

    @Override
    public PageResult<ResearchTopicInfoDO> getResearchTopicInfoPage(ResearchTopicInfoPageReqVO pageReqVO) {
//        pageReqVO.setPageSize(-1);
        PageResult<ResearchTopicInfoDO> researchTopicInfoDOPageResult = researchTopicInfoMapper.selectPage(pageReqVO);

//        for (ResearchTopicInfoDO aDo : researchTopicInfoDOPageResult.getList()) {
//            DefaultIdentifierGenerator generator = new DefaultIdentifierGenerator();
//            long newId = generator.nextId(null);
//            // 构建更新条件
//            UpdateWrapper<ResearchTopicInfoDO> wrapper = new UpdateWrapper<>();
//            wrapper.eq("oid", aDo.getOid()).set("id", newId);
//
//            // 执行更新，只更新 id 字段
//            researchTopicInfoMapper.update(null, wrapper);
//        }
        return researchTopicInfoDOPageResult;
    }

    @Override
    public void auditResearchTopicInfo(Long id, String auditStatus) {
        ResearchTopicInfoDO infoDO = researchTopicInfoMapper.selectById(id);
        if (infoDO == null) {
            throw exception(RESEARCH_TOPIC_INFO_NOT_EXISTS);
        }
        String nickname = String.valueOf(
                SecurityFrameworkUtils.getLoginUser().getInfo().get("nickname"));
        infoDO.setAuditStatus(auditStatus);
        infoDO.setAuditor(nickname);
        infoDO.setAuditTime(LocalDateTime.now());
        researchTopicInfoMapper.updateById(infoDO);
    }
    @Override
    public void voidResearchTopicInfo(Long id, String status) {
        ResearchTopicInfoDO infoDO = researchTopicInfoMapper.selectById(id);
        if (infoDO == null) {
            throw exception(RESEARCH_TOPIC_INFO_NOT_EXISTS);
        }
        infoDO.setStatus(status);
        researchTopicInfoMapper.updateById(infoDO);
    }

    public static String extractDate(String path) {
        // 正则匹配中间的8位数字
        String regex = "/(\\d{8})/";
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(regex);
        java.util.regex.Matcher matcher = pattern.matcher(path);

        if (matcher.find()) {
            return matcher.group(1); // 返回匹配到的日期部分
        }

        return null;
    }


}