package com.css.simulation.resource.server.app.service;

import api.common.pojo.common.ResponseBodyVO;
import api.common.pojo.constants.DictConstants;
import api.common.pojo.param.scene.SceneEvaluationRuleParam;
import api.common.pojo.param.scene.ScoringRulesParam;
import api.common.pojo.po.scene.SceneEvaluationRulePO;
import api.common.pojo.po.scene.ScoringRulesPO;
import api.common.util.*;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SceneEvaluationRuleMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.ScoringRulesMapper;
import com.css.simulation.resource.server.infra.feign.service.FileDownService;
import com.css.simulation.resource.server.infra.util.AuthUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
@Service
public class ScoringRulesService {

    @Resource
    private ScoringRulesMapper scoringRulesMapper;
    @Resource
    private ScenePackageMapper scenePackageMapper;
    @Resource
    private SceneEvaluationRuleMapper sceneEvaluationRuleMapper;

    @Resource
    private FileDownService fileDownService;

    /**
     * 打分规则数据录入：
     */
    @SneakyThrows
    public void saveScoringRules(ScoringRulesPO params) {
        params.setCreateTime(TimeUtil.getNowForMysql());
        params.setModifyTime(TimeUtil.getNowForMysql());
        params.setRulesId(StringUtil.getRandomUUID());
        params.setRulesCode(StringUtil.getRandomCode());
        params.setCreateUserId(AuthUtil.getCurrentUserId());
        params.setIsDeleted("0");
        scoringRulesMapper.saveScoringRules(params);
        LogUtil.insert();
    }

    @SneakyThrows
    public List<ScoringRulesPO> queryScoringRulesListCSB(ScoringRulesParam params) {
        List<ScoringRulesPO> list = new ArrayList<>();
        if (params != null) {
            if (params.getShare() != null && params.getShare().equals("0")) {
                params.setCreateUserId(AuthUtil.getCurrentUserId());
            }
            list = scoringRulesMapper.queryScoringRulesList(params);
            params.setCreateUserId("");
            params.setShare("1");
            List<ScoringRulesPO> list1 = scoringRulesMapper.queryScoringRulesList(params);
            list.addAll(list1);
        }
        //查询共有
        return list;
    }

    @SneakyThrows
    public List<ScoringRulesPO> queryScoringRulesList(ScoringRulesParam params) {
        if (params != null && params.getShare() != null && params.getShare().equals("0")) {
            params.setCreateUserId(AuthUtil.getCurrentUserId());
        }
        return scoringRulesMapper.queryScoringRulesList(params);
    }


    @SneakyThrows
    public ScoringRulesPO queryScoringRules(ScoringRulesParam params) {
        return scoringRulesMapper.queryScoringRules(params);
    }

    @SneakyThrows
    public ScoringRulesPO queryScoringRulesByRuleName(ScoringRulesParam params) {
        return scoringRulesMapper.queryScoringRulesByRuleName(params);
    }

    @SneakyThrows
    public ScoringRulesPO querySelfOnly(String ruleName, String createUserId) {
        return scoringRulesMapper.querySelfOnly(ruleName, createUserId);
    }

    @SneakyThrows
    public int querySceneEvaluationRuleOnly(String ruleName, String ruleId) {
        return sceneEvaluationRuleMapper.querySceneEvaluationRuleOnly(ruleName, ruleId);
    }

    @SneakyThrows
    public void updateScoringRules(ScoringRulesPO params) {
        params.setModifyTime(TimeUtil.getNowForMysql());
        params.setModifyUserId(AuthUtil.getCurrentUserId());
        scoringRulesMapper.updateScoringRules(params);
        LogUtil.update();
    }

    /**
     * 删除打分规则
     *
     * @param params 参数
     */
    @SneakyThrows
    public void deleteScoringRules(ScoringRulesPO params) {
        params.setIsDeleted("1");
        params.setModifyTime(TimeUtil.getNowForMysql());
        params.setModifyUserId(AuthUtil.getCurrentUserId());
        scoringRulesMapper.updateScoringRules(params);
        //同步把使用该评分规则的测试包设为禁用
        scenePackageMapper.updateIsUnavailable3(params);
        LogUtil.delete();
    }

    @SneakyThrows
    public Integer queryCsbById(ScoringRulesParam params) {
        return scoringRulesMapper.queryCsbById(params);
    }

    @SneakyThrows
    public List<Map<String, Object>> queryScoringRulesListCSBNew(ScoringRulesParam params) {
        Optional.ofNullable(params).orElseThrow(() -> new RuntimeException("参数为空。"));
        if (params.getShare() != null && params.getShare().equals("0")) {
            params.setCreateUserId(AuthUtil.getCurrentUserId());
        }
        List<Map<String, Object>> treeList = new ArrayList<>();
        List<ScoringRulesPO> listSy = scoringRulesMapper.queryScoringRulesList(params);

        //查询共有
        params.setCreateUserId("");
        params.setShare("1");
        List<ScoringRulesPO> listGy = scoringRulesMapper.queryScoringRulesList(params);

        Map<String, Object> typeMap = new HashMap<>();
        typeMap.put("code", "公有");
        typeMap.put("name", "公有");
        List<Map<String, Object>> colourList = new LinkedList<>();
        listGy.forEach(vo -> {
            Map<String, Object> colourMap = new HashMap<>();
            colourMap.put("code", vo.getRulesId());
            colourMap.put("name", vo.getRuleName());
            colourMap.put("vo", vo);
            colourList.add(colourMap);
        });
        typeMap.put("children", colourList);
        Map<String, Object> typeMap1 = new HashMap<>();
        typeMap1.put("code", "私有");
        typeMap1.put("name", "私有");
        List<Map<String, Object>> colourList1 = new LinkedList<>();
        listSy.forEach(vo -> {
            Map<String, Object> colourMap = new HashMap<>();
            colourMap.put("code", vo.getRulesId());
            colourMap.put("name", vo.getRuleName());
            colourMap.put("vo", vo);
            colourList1.add(colourMap);
        });
        typeMap1.put("children", colourList1);
        treeList.add(typeMap);
        treeList.add(typeMap1);
        return treeList;
    }


    @SneakyThrows
    public ResponseBodyVO<String> uploadPyScriptAndSaveRule(MultipartFile file, SceneEvaluationRulePO sceneEvaluationRulePO) {

        boolean hasRuleId = StringUtil.isEmpty(sceneEvaluationRulePO.getRuleId());

        // 检查是否存在同名场景评价规则
        int repeatPyScriptAndSaveRuleCount = querySceneEvaluationRuleOnly(sceneEvaluationRulePO.getRuleName(),
                hasRuleId ? null : sceneEvaluationRulePO.getRuleId());
        if (repeatPyScriptAndSaveRuleCount > 0) {
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "场景规则 " + sceneEvaluationRulePO.getRuleName() + " 已存在，请重新命名。");
        }
        // 新建或者是编辑时重新上传文件
        if ((hasRuleId) || sceneEvaluationRulePO.getUploadNewFile()) {
            String roleCode = AuthUtil.getCurrentUserRoleCode();
            if (!DictConstants.ROLE_CODE_ADMIN.equals(roleCode) && !DictConstants.ROLE_CODE_SYSADMIN.equals(roleCode)) {
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "非管理员禁止上传文件");
            }
            // 检查文件内容是否合规
            String pyStr = new String(file.getBytes(), StandardCharsets.UTF_8);
            //1 校验 python 语法错误
            String pylint = PythonUtil.pylint(pyStr, PythonUtil.C, PythonUtil.R, PythonUtil.W, PythonUtil.E0401, PythonUtil.E0601);
            if (!pylint.contains(PythonUtil.PASS)) {
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "代码格式错误，请检查。");
            }
            // 获取文件原本的名字
            String originName = file.getOriginalFilename();
            if (null == originName) {
                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "文件名为空，请检查！");
            }
            String fileName = originName.substring(0, originName.lastIndexOf("."));
            Integer nowTime = TimeUtil.getRq(new Date(), 0);
            String randomCode = StringUtil.getRandomCode();
            fileName = "/" + DictConstants.SCENE_EVALUATION_RULE_PY_FILE + "/" + nowTime + "/" + randomCode + "/" + fileName;
            ResponseBodyVO<String> response = fileDownService.upload(file, fileName);
            if (response.isStatus()) {
                String previewUrl = response.getInfo();
                sceneEvaluationRulePO.setScriptName(fileName);
                sceneEvaluationRulePO.setScriptPath(previewUrl);
            }
            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "上传失败！");
        }

        // 判断 ruleId 是否为空
        if (StringUtil.isEmpty(sceneEvaluationRulePO.getRuleId())) {
            // 创建
            saveSceneEvaluationRule(sceneEvaluationRulePO);
        } else {
            // 修改
            updateSceneEvaluationRule(sceneEvaluationRulePO);
        }
        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
    }

    /**
     * 查询场景评价规则列表
     */
    @SneakyThrows
    public List<SceneEvaluationRulePO> querySceneEvaluationRuleList(SceneEvaluationRuleParam params) {
        return sceneEvaluationRuleMapper.querySceneEvaluationRuleList(params);
    }


    @SneakyThrows
    public void saveSceneEvaluationRule(SceneEvaluationRulePO params) {
        params.setCreateTime(TimeUtil.getNowForMysql());
        params.setModifyTime(TimeUtil.getNowForMysql());
        params.setRuleId(StringUtil.getRandomUUID());
        params.setRuleCode(StringUtil.getRandomCode());
        params.setCreateUserId(AuthUtil.getCurrentUserId());
        params.setIsDeleted("0");
        sceneEvaluationRuleMapper.saveSceneEvaluationRule(params);
        LogUtil.insert();
    }

    @SneakyThrows
    public void updateSceneEvaluationRule(SceneEvaluationRulePO params) {
        params.setModifyTime(TimeUtil.getNowForMysql());
        params.setModifyUserId(AuthUtil.getCurrentUserId());
        sceneEvaluationRuleMapper.updateSceneEvaluationRule(params);
        LogUtil.update();
    }

}
