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.SystemConfigProcessDO;
import com.cf.imes.module.system.dal.dataobject.systemconfig.SystemConfigSchemeDO;
import com.cf.imes.module.system.dal.mysql.systemconfig.SystemConfigProcessMapper;
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("processScreeningServiceHandler")
@Slf4j
public class ProcessScreeningServiceHandler extends AbstractSystemConfigServiceHandler {


    @Resource
    private SystemConfigProcessMapper systemConfigProcessMapper;

    @Resource
    private SystemConfigSchemeMapper systemConfigSchemeMapper;

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

        List<SystemConfigProcessDO> systemConfigDOS = systemConfigProcessMapper.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<SystemConfigProcessDO> systemConfigProcessDOS = systemConfigProcessMapper.selectList(new LambdaQueryWrapperX<SystemConfigProcessDO>()
                .eq(SystemConfigProcessDO::getOrganId,getUserOrganId())
                .eq(SystemConfigProcessDO::getName, reqVO.getName())
                .neIfPresent(SystemConfigProcessDO::getId,reqVO.getId()));

        AssertUtils.empty(systemConfigProcessDOS,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);

        validateProcessConfigUsedAlready(id);

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

    }


    @Override
    public void updateConfigStatus(ConfigUpdateStatusReqVO reqVO) {

        Long id = reqVO.getId();

        // 校验存在
        SystemConfigProcessDO systemConfigProcessDO = systemConfigProcessMapper.selectOne(new LambdaQueryWrapperX<SystemConfigProcessDO>()
                .eq(SystemConfigProcessDO::getId, id)
                .eq(SystemConfigProcessDO::getOrganId, OrganContextHolder.getOrganId()));
        if (ObjectUtil.isNull(systemConfigProcessDO)) {
            throw exception(SYSTEM_CONFIG_NOT_EXISTS);
        }

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

    }

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

        ArrayList<SystemConfigProcessDO> systemConfigProcessDOS = new ArrayList<>();

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

        systemConfigProcessMapper.updateBatch(systemConfigProcessDOS);

    }


    @Override
    public SystemConfigDO getSystemConfig(Long id) {

        SystemConfigProcessDO systemConfigProcessDO = validateSystemConfigExists(id);

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

    }


    @Override
    public void modifySystemConfig(ConfigSaveReqVO reqVO) {

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

    }



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

        SystemConfigProcessDO systemConfigProcessDO = systemConfigProcessMapper.selectOne(new LambdaQueryWrapperX<SystemConfigProcessDO>()
                .eq(SystemConfigProcessDO::getId, id)
                .eq(SystemConfigProcessDO::getOrganId, OrganContextHolder.getOrganId()));

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

        return systemConfigProcessDO;
    }


    private void validateProcessConfigUsedAlready(Long id){

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

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

        if(CollUtil.isNotEmpty(systemConfigSchemeDOS)){

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

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

        if(processLineConfigIds.contains(id)){
            throw exception(PROCESS_CONFIG_USED_ALREADY);
        }


    }



}
