package com.supervision.police.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.supervision.common.domain.R;
import com.supervision.common.utils.StringUtils;
import com.supervision.neo4j.dto.ResultDTO;
import com.supervision.neo4j.utils.Neo4jUtils;
import com.supervision.police.domain.*;
import com.supervision.police.dto.AnalyseCaseDTO;
import com.supervision.police.dto.AtomicData;
import com.supervision.police.dto.JudgeLogic;
import com.supervision.police.mapper.*;
import com.supervision.police.service.ModelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.Driver;
import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class ModelServiceImpl implements ModelService {

    private final Driver driver;

    private final ModelCaseMapper modelCaseMapper;

    private final ModelAtomicIndexMapper modelAtomicIndexMapper;

    private final ModelAtomicResultMapper modelAtomicResultMapper;

    private final ModelIndexMapper modelIndexMapper;

    private final ModelIndexResultMapper modelIndexResultMapper;

    private final CasePersonMapper casePersonMapper;

    @Override
    public R<?> analyseCase(AnalyseCaseDTO analyseCaseDTO) {
        ModelCase modelCase = modelCaseMapper.selectById(analyseCaseDTO.getCaseId());
        // 获取行为人ID
        CasePerson casePerson = casePersonMapper.selectOne(new LambdaQueryWrapper<CasePerson>().eq(CasePerson::getCaseId, analyseCaseDTO.getCaseId())
                .eq(CasePerson::getRoleCode, "1").eq(CasePerson::getName, analyseCaseDTO.getLawActor()));
        if (ObjectUtil.isEmpty(casePerson)) {
            throw new RuntimeException("未找到的行为人" + analyseCaseDTO.getLawActor());
        }
        //原子指标
        List<ModelAtomicIndex> atomicIndices = modelAtomicIndexMapper.selectByCaseType(modelCase.getCaseType());
        Map<String, Boolean> atomicResultMap = new HashMap<>();
        for (ModelAtomicIndex atomicIndex : atomicIndices) {
            //原子指标结果
            ModelAtomicResult result = new ModelAtomicResult();
            result.setCasePersonId(casePerson.getId());
            result.setCaseId(analyseCaseDTO.getCaseId());
            result.setAtomicId(atomicIndex.getId());
            //查询语句
            String ql = atomicIndex.getQueryLang();

            //原子指标结果表
            try {
                // index_source==1
                List<ModelAtomicIndex> list = analyseCaseDTO.getAtomicIndexList();
                //index_source==3

                //查询图谱  index_source: 1人工定义  2数据库查询	3图谱生成	  4大模型
                if ("1".endsWith(atomicIndex.getIndexSource())) {
                    // list
                } else if ("2".endsWith(atomicIndex.getIndexSource()) && StringUtils.isNotEmpty(ql)) {
                    //
                } else if ("3".endsWith(atomicIndex.getIndexSource()) && StringUtils.isNotEmpty(ql)) {
                    // 使用知识图谱进行计算
                    analyseGraphCase(analyseCaseDTO, result, ql);
                } else if ("4".endsWith(atomicIndex.getIndexSource())) {
                    //
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            //保存原子指标结果表
            ModelAtomicResult exist = modelAtomicResultMapper.selectByCaseIdAndAtomicId(analyseCaseDTO.getCaseId(), casePerson.getId(), atomicIndex.getId());
            if (exist == null) {
                modelAtomicResultMapper.insert(result);
            } else {
                result.setId(exist.getId());
                modelAtomicResultMapper.updateById(result);
            }
            // 所有原子指标id,判断结果是否为1,如果为1,则符合,为true
            atomicResultMap.put(result.getAtomicId(), "1".equals(result.getAtomicResult()));
        }
        // 最终计算得分
        calculateFinalScore(analyseCaseDTO, modelCase, atomicResultMap);
        return R.ok();
    }

    /**
     * 最终计算得分
     */
    private void calculateFinalScore(AnalyseCaseDTO analyseCaseDTO, ModelCase modelCase, Map<String, Boolean> atomicResultMap) {
        // 计算指标结果
        int score = 0;
        // 根据案件类型获取所有的指标
        List<ModelIndex> modelIndices = modelIndexMapper.selectByCaseType(modelCase.getCaseType());
        for (ModelIndex modelIndex : modelIndices) {
            ModelIndexResult result = new ModelIndexResult();
            result.setCaseId(analyseCaseDTO.getCaseId());
            result.setIndexId(modelIndex.getId());
            Set<String> atomicIds = new HashSet<>();
            // 判断逻辑是否为空,如果不为空,就根据判断逻辑进行判断
            if (StringUtils.isNotEmpty(modelIndex.getJudgeLogic())) {
                List<JudgeLogic> judgeLogics = JSONUtil.toList(modelIndex.getJudgeLogic(), JudgeLogic.class);
                if (CollUtil.isNotEmpty(judgeLogics)) {
                    boolean finalJudgeResult = false;
                    // 遍历组
                    for (int i = 0; i < judgeLogics.size(); i++) {
                        // 组内结果
                        boolean innerGroupJudge = false;
                        JudgeLogic logic = judgeLogics.get(i);
                        // 获取组之间的的判断逻辑
                        String rowLogic = logic.getRowLogic();
                        // 首先对组内进行判断,判断组内的结果
                        List<AtomicData> atomicData = logic.getAtomicData();
                        for (int j = 0; j < atomicData.size(); j++) {
                            AtomicData data = atomicData.get(j);
                            atomicIds.add(data.getAtomicIndex());
                            // 这里可能不存在,如果不存在,就默认为false
                            Boolean ato = atomicResultMap.getOrDefault(data.getAtomicIndex(), false);
                            String relationalSymbol = data.getRelationalSymbol();
                            // 判断,如果是2 虚构,4不存在 ,5 未知,则取反,即判断结果为false
                            if ("2".equals(relationalSymbol) || "4".equals(relationalSymbol) || "5".equals(relationalSymbol)) {
                                ato = !ato;
                            }
                            if (j == 0) {
                                innerGroupJudge = ato;
                            } else {
                                if ("1".equals(rowLogic)) {
                                    innerGroupJudge = innerGroupJudge && ato;
                                } else if ("2".equals(rowLogic)) {
                                    innerGroupJudge = innerGroupJudge || ato;
                                }
                            }
                        }
                        String groupLogic = logic.getGroupLogic();
                        if (i == 0) {
                            finalJudgeResult = innerGroupJudge;
                        } else {
                            // 如果组间判断为1 与,则进行与操作
                            if ("1".equals(groupLogic)) {
                                finalJudgeResult = finalJudgeResult && innerGroupJudge;
                                // 如果组间判断为或,则进行或操作
                            } else if ("2".equals(groupLogic)) {
                                finalJudgeResult = finalJudgeResult || innerGroupJudge;
                            }
                        }
                    }
                    result.setIndexResult(finalJudgeResult ? "true" : "false");
                    result.setAtomicIds(StringUtils.join(atomicIds, ","));
                }
            }
            // 最后保存结果
            ModelIndexResult exist = modelIndexResultMapper.selectByCaseIdAndIndexId(analyseCaseDTO.getCaseId(), modelIndex.getId());
            if (exist == null) {
                modelIndexResultMapper.insert(result);
            } else {
                result.setId(exist.getId());
                modelIndexResultMapper.updateById(result);
            }

            if ("true".equals(result.getIndexResult())) {
                score = score + modelIndex.getIndexScore();
            }
        }
        modelCase.setTotalScore(score);
        modelCaseMapper.updateById(modelCase);
    }

    private void analyseGraphCase(AnalyseCaseDTO analyseCaseDTO, ModelAtomicResult result, String ql) {
        Session session = driver.session();
        //图谱
        int i = 1;
        Map<String, Object> params = new HashMap<>();
        // 行为人
        params.put("lawActor", analyseCaseDTO.getLawActor());
        // 案号
        params.put("caseId", analyseCaseDTO.getCaseId());
        // 参数中是否传了受害人
        String lawPartys = analyseCaseDTO.getLawParty();
        // 如果有受害人的话就进行分割
        String[] split = StringUtils.isEmpty(lawPartys) ? new String[0] : lawPartys.split(",");
        if (ql.contains("$lawParty") && split.length > 1) {
            i = split.length;
        }
        for (int j = 0; j < i; j++) {
            if (split.length > 0) {
                params.put("lawParty", split[j]);
            }
            Result run;
            try {
                run = session.run(ql, params);
            } catch (Exception e) {
                log.info("图数据库查询出现错误,查询语句{},参数{}", ql, JSONUtil.toJsonStr(params));
                return;
            }

            List<ResultDTO> res = Neo4jUtils.getResultDTOList(run);
            if (res.isEmpty()) {
                result.setAtomicResult("-1");
            } else {
                ResultDTO resultDTO = res.get(0);
                if (StringUtils.isNotEmpty(resultDTO.getRelId())) {
                    //存在关系
                    result.setAtomicResult("1");
                    result.setRecordSplitId(resultDTO.getRecordId());
                    result.setRecordId(resultDTO.getRecordsId());
                    break;
                } else {
                    result.setAtomicResult("0");
                }
            }
        }
    }

}