package com.cf.imes.module.system.service.systemconfig.factory.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.module.system.controller.admin.systemconfig.vo.*;
import com.cf.imes.module.system.dal.dataobject.systemconfig.SystemConfigDO;
import com.cf.imes.module.system.dal.dataobject.systemconfig.SystemConfigDataDO;
import com.cf.imes.module.system.dal.dataobject.systemconfig.SystemConfigSchemeDO;
import com.cf.imes.module.system.dal.mysql.systemconfig.SystemConfigDataMapper;
import com.cf.imes.module.system.dal.mysql.systemconfig.SystemConfigSchemeMapper;
import com.cf.imes.module.system.service.systemconfig.factory.service.AbstractSystemConfigServiceHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.framework.common.util.json.JsonUtils.parseArray;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;

/**
 * @author 数据处理服务处理器
 */
@Service("dataProcessServiceHandler")
@Slf4j
public class DataProcessServiceHandler extends AbstractSystemConfigServiceHandler {

    @Resource
    private SystemConfigDataMapper systemConfigDataMapper;

    @Resource
    private SystemConfigSchemeMapper systemConfigSchemeMapper;

    @Override
    public List<SystemConfigDO> selectList(ConfigPageReqVO pageReqVO) {

        List<SystemConfigDataDO> systemConfigDOS = systemConfigDataMapper.selectSystemConfigList(pageReqVO.getType(),null);

        if (systemConfigDOS.isEmpty()){
            return null;
        }

        return BeanUtils.toBean(systemConfigDOS,SystemConfigDO.class);

    }



    @Override
    public void checkValid(String setting) {
        // todo checkValid
    }

    @Override
    public void beforeSaveConfig(ConfigSaveReqVO reqVO) {

        List<SystemConfigDataDO> systemConfigDataDOS = systemConfigDataMapper.selectList(new LambdaQueryWrapperX<SystemConfigDataDO>()
                .eq(SystemConfigDataDO::getOrganId,getUserOrganId())
                .eq(SystemConfigDataDO::getName, reqVO.getName())
                .neIfPresent(SystemConfigDataDO::getId,reqVO.getId()));

        AssertUtils.empty(systemConfigDataDOS,THIS_CONFIG_NAME_IS_EXISTS);

    }

    @Override
    public void afterSaveConfig(SystemConfigDO systemConfigDO, ConfigSaveReqVO reqVO) {
        // todo afterSaveConfig
    }


    @Override
    public void deleteConfig(ConfigDeleteReqVO reqVO) {

        Long id = reqVO.getId();

        validateSystemConfigExists(id);

        validateDataConfigUsedAlready(id);

        systemConfigDataMapper.deleteConfig(reqVO.getId(),getUserOrganId());

    }

    @Override
    public void updateConfigStatus(ConfigUpdateStatusReqVO reqVO) {

        Long id = reqVO.getId();

        // 校验存在
        SystemConfigDataDO systemConfigDataDO = systemConfigDataMapper.selectOne(new LambdaQueryWrapperX<SystemConfigDataDO>()
                .eq(SystemConfigDataDO::getId, id)
                .eq(SystemConfigDataDO::getOrganId, OrganContextHolder.getOrganId()));

        if (ObjectUtil.isNull(systemConfigDataDO)) {
            throw exception(SYSTEM_CONFIG_NOT_EXISTS);
        }

        // 更新状态
        systemConfigDataMapper.update(new LambdaUpdateWrapper<SystemConfigDataDO>()
                .eq(SystemConfigDataDO::getId, id)
                .set(SystemConfigDataDO::getStatus, reqVO.getStatus()));

    }

    @Override
    public void updateConfigSort(List<ConfigUpdateSortReqVO> reqVO) {

        ArrayList<SystemConfigDataDO> systemConfigDataDOS = new ArrayList<>();

        reqVO.forEach(f->
                systemConfigDataDOS.add(BeanUtils.toBean(SystemConfigDO
                        .builder()
                        .id(f.getId())
                        .type(f.getType())
                        .status(f.getStatus())
                        .sort(f.getSort())
                        .build(),SystemConfigDataDO.class)));

        systemConfigDataMapper.updateBatch(systemConfigDataDOS);


    }

    @Override
    public SystemConfigDO getSystemConfig(Long id) {

        SystemConfigDataDO systemConfigDataDO = validateSystemConfigExists(id);

        return BeanUtils.toBean(systemConfigDataDO,SystemConfigDO.class);

    }


    @Override
    public void modifySystemConfig(ConfigSaveReqVO reqVO) {

        // 校验规则
        checkValid(reqVO.getSetting());
        // 系统配置保存前操作
        beforeSaveConfig(reqVO);
        SystemConfigDataDO systemConfigDataDO;
        if (ObjectUtil.isNotNull(reqVO.getId())) {
            systemConfigDataDO = validateSystemConfigExists(reqVO.getId());
            // 覆盖配置
            systemConfigDataDO.setSetting(reqVO.getSetting());
            // 覆盖名称
            systemConfigDataDO.setName(reqVO.getName());
            // 更新时间
            systemConfigDataDO.setUpdateTime(LocalDateTime.now());
            // 更新
            systemConfigDataMapper.updateById(systemConfigDataDO);
        } else {
            systemConfigDataDO = BeanUtils.toBean(reqVO, SystemConfigDataDO.class);
            // 新增
            systemConfigDataMapper.insert(systemConfigDataDO);
        }
        // 系统配置保存后操作
        afterSaveConfig(systemConfigDataDO, reqVO);


    }



    /**
     * 校验基础配置是否存在
     *
     * @param id
     * @return
     */
    private SystemConfigDataDO validateSystemConfigExists(Long id) {

        SystemConfigDataDO systemConfigDataDO = systemConfigDataMapper.selectOne(new LambdaQueryWrapperX<SystemConfigDataDO>()
                .eq(SystemConfigDataDO::getId, id)
                .eq(SystemConfigDataDO::getOrganId, OrganContextHolder.getOrganId()));

        if (ObjectUtil.isNull(systemConfigDataDO)) {
            throw exception(SYSTEM_CONFIG_NOT_EXISTS);
        }

        return systemConfigDataDO;
    }



    private void validateDataConfigUsedAlready(Long id){

        List<SystemConfigSchemeDO> systemConfigSchemeDOS = systemConfigSchemeMapper.selectOrganConfig(OrganContextHolder.getOrganId());

        List<Long> optimizationConfigIds = new ArrayList<>();

        if(CollUtil.isNotEmpty(systemConfigSchemeDOS)){

            try {
                systemConfigSchemeDOS.forEach(f -> {
                    List<ProcessSchemeConfig> processSchemeConfigs = parseArray(f.getSetting(), ProcessSchemeConfig.class);
                    optimizationConfigIds.addAll(processSchemeConfigs.stream().map(m -> Long.valueOf(m.getOptimizationConfig())).distinct().toList());
                });

            }catch (Exception e){
                log.error("删除数据处理解析加工方案组配置报错："+e.getMessage());
            }
        }

        if(optimizationConfigIds.contains(id)){
            throw exception(OPTIMIZATION_CONFIG_USED_ALREADY);
        }


    }




}
