package com.cf.imes.module.system.service.parser;


import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.system.controller.admin.parser.vo.ParserTemplateReqVO;
import com.cf.imes.module.system.controller.admin.parser.vo.ParserTemplateRespVO;
import com.cf.imes.module.system.controller.admin.parser.vo.TemplateLimitReqVO;
import com.cf.imes.module.system.controller.admin.parser.vo.TemplateSimpleRespVO;
import com.cf.imes.module.system.dal.dataobject.parser.ParserDO;
import com.cf.imes.module.system.dal.dataobject.parser.ParserLimitDO;
import com.cf.imes.module.system.dal.dataobject.parser.ParserTemplateDO;
import com.cf.imes.module.system.dal.mysql.parser.ParserLimitMapper;
import com.cf.imes.module.system.dal.mysql.parser.ParserMapper;
import com.cf.imes.module.system.dal.mysql.parser.ParserTemplateMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.cf.imes.module.system.enums.ErrorCodeConstants.PARSER_TEMPLATE_NO_EXIST;


/**
 * @author 解析器模板管理 Service 实现类
 */
@Service
@Slf4j
public class ParserTemplateServiceImpl implements ParserTemplateService{


    @Resource
    private ParserTemplateMapper parserTemplateMapper;

    @Resource
    private ParserMapper parserMapper;


    @Resource
    private ParserLimitMapper parserLimitMapper;



    @Override
    public void update(ParserTemplateReqVO reqVO) {

        ParserTemplateDO parserTemplateDO = validateParserTemplateExists(reqVO.getId());

        parserTemplateDO.setName(reqVO.getName());
        parserTemplateDO.setSetting(reqVO.getSetting());
        parserTemplateDO.setIsEnabled(reqVO.getIsEnabled());

        parserTemplateMapper.updateById(parserTemplateDO);

    }




    @Override
    public Map<Integer, List<ParserTemplateRespVO>> getParserTemplateTree(Long type) {

        List<ParserTemplateDO> parserTemplateDOS = parserTemplateMapper.selectList(new LambdaQueryWrapperX<ParserTemplateDO>()
                .eq(ParserTemplateDO::getDeleted,false)
                .eqIfPresent(ParserTemplateDO::getParserType, type));

        if(CollUtil.isEmpty(parserTemplateDOS)){
            return new HashMap<>();
        }

        List<ParserTemplateRespVO> respVOS = BeanUtils.toBean(parserTemplateDOS, ParserTemplateRespVO.class);

        return respVOS.stream().collect(Collectors.groupingBy(ParserTemplateRespVO::getParserType));

    }




    @Override
    public ParserTemplateRespVO getParserTemplate(Long id) {

        ParserTemplateDO parserTemplateDO = validateParserTemplateExists(id);

        return BeanUtils.toBean(parserTemplateDO,ParserTemplateRespVO.class);

    }





    @Override
    public void updateParserTemplateLimit(TemplateLimitReqVO reqVO) {

        Long organId = reqVO.getOrganId();

        ParserLimitDO parserLimitDO = parserLimitMapper.selectById(organId);

        if(parserLimitDO == null){
            return;
        }

        List<Long> parserTemplateIds = reqVO.getParserTemplateIds();

        if(CollUtil.isNotEmpty(parserTemplateIds)){

            String templateIds = Optional.ofNullable(parserLimitDO.getParserIds()).orElse("[]");

            List<Long> templateIdList = JSON.parseArray(templateIds).toJavaList(Long.class).stream().distinct().toList();

            Result result = compareLists(parserTemplateIds, templateIdList);

            // 组织新增解析器
            List<Long> onlyInA = result.onlyInA;
            if(CollUtil.isNotEmpty(onlyInA)){
                List<ParserTemplateDO> parserTemplateDOS = parserTemplateMapper.selectBatchIds(onlyInA);

                List<ParserDO> parserDOS = new ArrayList<>();
                parserTemplateDOS.forEach(f-> parserDOS.add(
                        ParserDO.builder()
                                .parserType(f.getParserType())
                                .parserTemplateId(f.getId())
                                .organId(organId)
                                .name(f.getName())
                                .setting(f.getSetting())
                                .build()
                ));

                parserMapper.insertBatch(parserDOS);

            }

            // 删除组织的解析器
            List<Long> onlyInB = result.onlyInB;
            if(CollUtil.isNotEmpty(onlyInB)){
                parserMapper.delete(new LambdaQueryWrapperX<ParserDO>()
                        .eq(ParserDO::getOrganId, organId)
                        .eq(ParserDO::getDeleted,false)
                        .in(ParserDO::getId, onlyInB));

            }

        }

    }





    @Override
    public Map<Integer, List<TemplateSimpleRespVO>> getParserTemplateSimple(Long type) {

        List<ParserTemplateDO> parserTemplateDOS = parserTemplateMapper.selectList(new LambdaQueryWrapperX<ParserTemplateDO>()
                .eq(ParserTemplateDO::getDeleted,false)
                .eq(ParserTemplateDO::getIsEnabled,true)
                .eqIfPresent(ParserTemplateDO::getParserType, type)
                .select(ParserTemplateDO::getId,ParserTemplateDO::getName,ParserTemplateDO::getParserType));

        if(CollUtil.isEmpty(parserTemplateDOS)){
            return new HashMap<>();
        }

        List<TemplateSimpleRespVO> respVOS = BeanUtils.toBean(parserTemplateDOS, TemplateSimpleRespVO.class);

        return respVOS.stream().collect(Collectors.groupingBy(TemplateSimpleRespVO::getParserType));

    }





    @Override
    public List<Long> getOrganParserTemplateLimit(Long organId) {

        ParserLimitDO parserLimitDO = parserLimitMapper.selectById(organId);
        if(parserLimitDO == null){
            return new ArrayList<>();
        }

        String templateIds = Optional.ofNullable(parserLimitDO.getParserIds()).orElse("[]");

        return JSON.parseArray(templateIds).toJavaList(Long.class).stream().distinct().toList();

    }






    private ParserTemplateDO validateParserTemplateExists(Long id) {

        ParserTemplateDO parserTemplateDO = parserTemplateMapper.selectById(id);
        if (parserTemplateDO == null) {

            throw new ServiceException(PARSER_TEMPLATE_NO_EXIST);
        }

        return parserTemplateDO;

    }




    public static Result compareLists(List<Long> a, List<Long> b) {
        Set<Long> setA = new HashSet<>(a);
        Set<Long> setB = new HashSet<>(b);

        // 创建副本用于计算差集
        Set<Long> onlyInA = new HashSet<>(setA);
        onlyInA.removeAll(setB); // A 中有但 B 中没有的

        Set<Long> onlyInB = new HashSet<>(setB);
        onlyInB.removeAll(setA); // B 中有但 A 中没有的

        return new Result(new ArrayList<>(onlyInA), new ArrayList<>(onlyInB));
    }



    static class Result {
        List<Long> onlyInA;
        List<Long> onlyInB;

        public Result(List<Long> onlyInA, List<Long> onlyInB) {
            this.onlyInA = onlyInA;
            this.onlyInB = onlyInB;
        }
    }


}
