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

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.controller.admin.researchtopicinfo.vo.ResearchTopicInfoRespVO;
import com.cy.guoyan.admin.module.guoyan.dal.dataobject.researchtopiccategory.ResearchTopicCategoryDO;
import com.cy.guoyan.admin.module.guoyan.dal.dataobject.researchtopicinfo.ResearchTopicInfoDO;
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.stateownedreformbestpracticeinfo.vo.*;
import com.cy.guoyan.admin.module.guoyan.dal.dataobject.stateownedreformbestpracticeinfo.StateOwnedReformBestPracticeInfoDO;
import com.cy.guoyan.admin.framework.common.pojo.PageResult;
import com.cy.guoyan.admin.framework.common.pojo.PageParam;
import com.cy.guoyan.admin.framework.common.util.object.BeanUtils;

import com.cy.guoyan.admin.module.guoyan.dal.mysql.stateownedreformbestpracticeinfo.StateOwnedReformBestPracticeInfoMapper;

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.framework.common.util.collection.CollectionUtils.diffList;
import static com.cy.guoyan.admin.module.system.enums.ErrorCodeConstants.*;

/**
 * 国资改革最佳实践数据信息 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class StateOwnedReformBestPracticeInfoServiceImpl implements StateOwnedReformBestPracticeInfoService {

    @Resource
    private StateOwnedReformBestPracticeInfoMapper stateOwnedReformBestPracticeInfoMapper;

    @Resource
    private FileMapper fileMapper;

    @Override
    public Long createStateOwnedReformBestPracticeInfo(StateOwnedReformBestPracticeInfoSaveReqVO createReqVO) {
        String nickname = String.valueOf(SecurityFrameworkUtils.getLoginUser().getInfo().get("nickname"));
        StateOwnedReformBestPracticeInfoDO data = BeanUtils.toBean(createReqVO, StateOwnedReformBestPracticeInfoDO.class);
        data.setCreatorName(nickname);
        DefaultIdentifierGenerator generator = new DefaultIdentifierGenerator();
        data.setId(generator.nextId(null));
        data.setAuditStatus("未审核");
        data.setStatus("正常");

        stateOwnedReformBestPracticeInfoMapper.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);
            });
        }
        return data.getId();
    }

    @Override
    public void updateStateOwnedReformBestPracticeInfo(StateOwnedReformBestPracticeInfoSaveReqVO updateReqVO) {

        StateOwnedReformBestPracticeInfoDO old = stateOwnedReformBestPracticeInfoMapper.selectById(updateReqVO.getId());
        if (old == null) {
            throw exception(STATE_OWNED_REFORM_BEST_PRACTICE_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);
        }

        // 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);
        }

        StateOwnedReformBestPracticeInfoDO updateObj = BeanUtils.toBean(updateReqVO, StateOwnedReformBestPracticeInfoDO.class);
        stateOwnedReformBestPracticeInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteStateOwnedReformBestPracticeInfo(Long id) {
        // 校验存在
        validateStateOwnedReformBestPracticeInfoExists(id);
        // 删除
        stateOwnedReformBestPracticeInfoMapper.deleteById(id);
    }

    @Override
        public void deleteStateOwnedReformBestPracticeInfoListByIds(List<Long> ids) {
        // 校验存在
        validateStateOwnedReformBestPracticeInfoExists(ids);
        // 删除
        stateOwnedReformBestPracticeInfoMapper.deleteByIds(ids);
        }

    private void validateStateOwnedReformBestPracticeInfoExists(List<Long> ids) {
        List<StateOwnedReformBestPracticeInfoDO> list = stateOwnedReformBestPracticeInfoMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(STATE_OWNED_REFORM_BEST_PRACTICE_INFO_NOT_EXISTS);
        }
    }

    private void validateStateOwnedReformBestPracticeInfoExists(Long id) {
        if (stateOwnedReformBestPracticeInfoMapper.selectById(id) == null) {
            throw exception(STATE_OWNED_REFORM_BEST_PRACTICE_INFO_NOT_EXISTS);
        }

    }

    @Override
    public StateOwnedReformBestPracticeInfoRespVO getStateOwnedReformBestPracticeInfo(Long id) {
        StateOwnedReformBestPracticeInfoDO old = stateOwnedReformBestPracticeInfoMapper.selectById(id);
        if (old == null) {
            throw exception(STATE_OWNED_REFORM_BEST_PRACTICE_INFO_NOT_EXISTS);
        }
        StateOwnedReformBestPracticeInfoRespVO bean = BeanUtils.toBean(old, StateOwnedReformBestPracticeInfoRespVO.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<StateOwnedReformBestPracticeInfoDO> getStateOwnedReformBestPracticeInfoPage(StateOwnedReformBestPracticeInfoPageReqVO pageReqVO) {
        return stateOwnedReformBestPracticeInfoMapper.selectPage(pageReqVO);
    }

    @Override
    public void auditStateOwnedReformBestPracticeInfo(Long id, String auditStatus) {
        StateOwnedReformBestPracticeInfoDO infoDO = stateOwnedReformBestPracticeInfoMapper.selectById(id);
        if (infoDO == null) {
            throw exception(STATE_OWNED_REFORM_BEST_PRACTICE_INFO_NOT_EXISTS);
        }
        String nickname = String.valueOf(
                SecurityFrameworkUtils.getLoginUser().getInfo().get("nickname"));
        infoDO.setAuditStatus(auditStatus);
        infoDO.setAuditor(nickname);
        infoDO.setAuditTime(LocalDateTime.now());
        stateOwnedReformBestPracticeInfoMapper.updateById(infoDO);
    }

    @Override
    public void voidStateOwnedReformBestPracticeInfo(Long id, String status) {
        StateOwnedReformBestPracticeInfoDO infoDO = stateOwnedReformBestPracticeInfoMapper.selectById(id);
        if (infoDO == null) {
            throw exception(STATE_OWNED_REFORM_BEST_PRACTICE_INFO_NOT_EXISTS);
        }
        infoDO.setStatus(status);
        stateOwnedReformBestPracticeInfoMapper.updateById(infoDO);
    }


}