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


import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
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.executor.api.plan.OrderPlanApi;
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.SystemConfigSchemeDO;
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 java.util.Optional;
import java.util.concurrent.atomic.AtomicLong;

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.common.util.json.JsonUtils.toJsonString;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;

/**
 * @author 加工方案服务处理器
 */

@Service("processSchemeServiceHandler")
@Slf4j
public class ProcessSchemeServiceHandler extends AbstractSystemConfigServiceHandler {

    @Resource
    private SystemConfigSchemeMapper systemConfigSchemeMapper;


    @Resource
    private OrderPlanApi orderPlanApi;

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

        List<SystemConfigSchemeDO> systemConfigDOS = systemConfigSchemeMapper.selectSystemConfigList(pageReqVO.getType(),null);

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

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

    }

    @Override
    public void checkValid(String setting) {


        List<ProcessSchemeConfig> processSchemeConfigs = parseArray(setting, ProcessSchemeConfig.class);

        processSchemeConfigs.forEach(f->{

            String planName = Optional.ofNullable(f.getPlanName()).orElse("");

            checkValueIsNotNull(planName,"加工方案名称");

            String processLineConfig = Optional.ofNullable(f.getProcessLineConfig()).orElse("");

            checkValueIsNotNull(processLineConfig,"加工分线");

            String optimizationConfig = Optional.ofNullable(f.getOptimizationConfig()).orElse("");

            checkValueIsNotNull(optimizationConfig,"优化数据配置");

            String analyzer = Optional.ofNullable(f.getAnalyzer()).orElse("");

            checkValueIsNotNull(analyzer,"解析器");

        });


    }

    @Override
    public void beforeSaveConfig(ConfigSaveReqVO reqVO) {

        List<SystemConfigSchemeDO> systemConfigSchemeDOS = systemConfigSchemeMapper.selectList(new LambdaQueryWrapperX<SystemConfigSchemeDO>()
                .eq(SystemConfigSchemeDO::getOrganId,getUserOrganId())
                .eq(SystemConfigSchemeDO::getName, reqVO.getName())
                .neIfPresent(SystemConfigSchemeDO::getId,reqVO.getId()));

        AssertUtils.empty(systemConfigSchemeDOS,THIS_CONFIG_NAME_IS_EXISTS);

        List<ProcessSchemeConfig> processSchemeConfigs = parseArray(reqVO.getSetting(), ProcessSchemeConfig.class);

        AtomicLong sort = new AtomicLong(System.currentTimeMillis());

        processSchemeConfigs.forEach(f->{

            sort.addAndGet(1);

            f.setPlanConfigId(Optional.ofNullable(f.getPlanConfigId()).orElse(sort.get()));

        });

        reqVO.setSetting(toJsonString(processSchemeConfigs));

    }


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

        List<SystemConfigSchemeDO> systemConfigDOS = systemConfigSchemeMapper.selectSystemConfigList(reqVO.getType(), CommonStatusEnum.ENABLE.getStatus());

        if(systemConfigDOS.size() > 1){
            systemConfigSchemeMapper.update(new LambdaUpdateWrapper<SystemConfigSchemeDO>()
                    .eq(SystemConfigSchemeDO::getOrganId, OrganContextHolder.getOrganId())
                    .eq(SystemConfigSchemeDO::getId,systemConfigDO.getId())
                    .set(SystemConfigSchemeDO::getStatus, CommonStatusEnum.DISABLE.getStatus()));
        }
    }


    @Override
    public void deleteConfig(ConfigDeleteReqVO reqVO) {

        validateSystemConfigExists(reqVO.getId());

        Boolean data = orderPlanApi.getOrderProcessScheme(reqVO.getId()).getCheckedData();

        if(Boolean.TRUE.equals(data)){
            throw exception(SYSTEM_PROCESS_SCHEME_CONFIG_IS_PLAN);
        }

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

    }


    @Override
    public void updateConfigStatus(ConfigUpdateStatusReqVO reqVO) {

        Long id = reqVO.getId();

        // 校验存在
        SystemConfigSchemeDO systemConfigSchemeDO = systemConfigSchemeMapper.selectOne(new LambdaQueryWrapperX<SystemConfigSchemeDO>()
                .eq(SystemConfigSchemeDO::getId, id)
                .eq(SystemConfigSchemeDO::getOrganId, OrganContextHolder.getOrganId()));

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

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


        systemConfigSchemeMapper.update(new LambdaUpdateWrapper<SystemConfigSchemeDO>()
                .eq(SystemConfigSchemeDO::getOrganId, OrganContextHolder.getOrganId())
                .eq(SystemConfigSchemeDO::getDeleted,false)
                .notIn(SystemConfigSchemeDO::getId,reqVO.getId())
                .eq(SystemConfigSchemeDO::getType, systemConfigSchemeDO.getType())
                .set(SystemConfigSchemeDO::getStatus, CommonStatusEnum.DISABLE.getStatus()));


    }

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

        ArrayList<SystemConfigSchemeDO> systemConfigSchemeDOS = new ArrayList<>();

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

        systemConfigSchemeMapper.updateBatch(systemConfigSchemeDOS);

    }


    @Override
    public SystemConfigDO getSystemConfig(Long id) {

        SystemConfigSchemeDO systemConfigSchemeDO = validateSystemConfigExists(id);

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

    }


    @Override
    public void modifySystemConfig(ConfigSaveReqVO reqVO) {

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

    }


    private void checkValueIsNotNull(String value,String error) {

        if(CharSequenceUtil.isBlank(value)){
            throw exception(SYSTEM_PROCESS_SCHEME_DATA_ERROR,error);
        }

    }



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

        SystemConfigSchemeDO systemConfigSchemeDO = systemConfigSchemeMapper.selectOne(new LambdaQueryWrapperX<SystemConfigSchemeDO>()
                .eq(SystemConfigSchemeDO::getId, id)
                .eq(SystemConfigSchemeDO::getOrganId, OrganContextHolder.getOrganId()));

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

        return systemConfigSchemeDO;
    }
}
