package com.nasc.custom.service.impl;

import com.nasc.common.core.text.Convert;
import com.nasc.common.exception.ServiceException;
import com.nasc.custom.domain.*;
import com.nasc.custom.mapper.*;
import com.nasc.custom.service.INascMatterService;
import com.nasc.custom.service.INascQuestionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: Yujianq
 * @Date: 2024/6/4 16:36
 * @Description: 审查事项前置问题
 * @return:
 */
@Service
public class NascQuestionServiceImpl implements INascQuestionService {

    @Autowired
    private NascPreQuestionMapper preQuestionMapper;

    @Autowired
    private NascPreQuestionOptionMapper preQuestionOptionMapper;

    @Autowired
    private NascMaterialMapper materialMapper;

    @Autowired
    private NascMaterialListMapper materialListMapper;

    @Override
    public List<NascPreQuestion> selectQuestionList(NascPreQuestion question) {
        return preQuestionMapper.getQuestionByMatterId(question.getMatterId());
    }

    @Override
    public Long checkQuestionDuplicates(NascPreQuestion question) {
        return preQuestionMapper.checkQuestionDuplicates(question);
    }

    @Override
    @Transactional
    public int insertPreQuestion(NascPreQuestion question) {
        // 保存前置问题信息
        int rows = preQuestionMapper.insertPreQuestion(question);
        List<NascPreQuestionOption> preQuestionOptionList = question.getPreQuestionOptionList();
        saveOption(question, preQuestionOptionList);
        return rows;
    }

    @Override
    @Transactional
    public int updatePreQuestion(NascPreQuestion question) {
        /** 先删除选项和材料信息 **/
        List<NascPreQuestionOption> preQuestionOptionList = question.getPreQuestionOptionList();
        List<Long> optionIds = new ArrayList<Long>();
//        long[] optionIds = preQuestionOptionList.stream().mapToLong(NascPreQuestionOption::getId).toArray();
        // 删除材料清单列表
        for (NascPreQuestionOption option : preQuestionOptionList) {
            if (option.getId() != null) {
                optionIds.add(option.getId());
            }
            if (option.getMaterial() != null) {
                materialListMapper.deleteMaterialListByMaterialId(option.getMaterial().getId());
            }
        }
        long[] longs = optionIds.stream().mapToLong(Long::longValue).toArray();
        // 删除选项相关的材料信息
        materialMapper.deleteMaterialByOptionIds(longs);
        // 删除问题相关的选项
        preQuestionOptionMapper.deleteOptionByQuestionId(question.getId());
        /** 重新存储选项和材料信息 **/
        saveOption(question, preQuestionOptionList);
        // 修改前置问题
        return preQuestionMapper.updatePreQuestion(question);
    }

    @Override
    @Transactional
    public int deleteQuestionById(Long id) {
        // 查询该问题是否被设置问题跳转
        if (preQuestionOptionMapper.getQuestionByJumpNum(id) > 0) {
            throw new ServiceException("该问题已被配置为跳转问题，无法删除！");
        }
        // 根据问题ID查询所有选项信息
        List<NascPreQuestionOption> optionList = preQuestionOptionMapper.getPreQuestionOptionListByQuestionId(id);
        long[] optionIds = optionList.stream().mapToLong(NascPreQuestionOption::getId).toArray();
        // 删除材料清单信息
        for (NascPreQuestionOption option: optionList) {
            if (option.getMaterial() != null) {
                materialListMapper.deleteMaterialListByMaterialId(option.getMaterial().getId());
            }
        }
        // 删除选项相关的材料信息
        materialMapper.deleteMaterialByOptionIds(optionIds);
        // 删除选项信息
        preQuestionOptionMapper.deleteOptionByQuestionId(id);
        // 删除问题信息
        return preQuestionMapper.deleteQuestionById(id);
    }

    @Override
    public NascPreQuestion getQuestionInfo(Long id) {
        NascPreQuestion question = preQuestionMapper.getQuestionById(id);
        // 查询问题选项和选项对应的材料信息
        List<NascPreQuestionOption> optionList = preQuestionOptionMapper.getPreQuestionOptionListByQuestionId(id);
        for (NascPreQuestionOption option : optionList) {
            if (option.getJumpToMatterId() == 0) {
                NascMaterial material = option.getMaterial();
                material.setMaterialList(materialListMapper.getMaterialListByMaterialId(material.getId()));
            }
        }
        question.setPreQuestionOptionList(optionList);
        return question;
    }

    /**
     * @Author: Yujianq
     * @Date: 2024/6/7 15:48
     * @Description: 保存前置问题选项对应的材料信息
     * @param question
     * @param preQuestionOptionList
     * @return: void
     */
    private void saveOption(NascPreQuestion question, List<NascPreQuestionOption> preQuestionOptionList) {
        boolean hasDuplicateNames = preQuestionOptionList.stream()
                .map(NascPreQuestionOption::getDesc)
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .values().stream().anyMatch(count -> count > 1);
        if (hasDuplicateNames) {
            throw new ServiceException("选项名称重复！");
        }

        for (NascPreQuestionOption option : preQuestionOptionList) {
            option.setQuestionId(question.getId());
            // 保存前置问题选项信息
            preQuestionOptionMapper.insertPreQuestionOption(option);
            // 保存前置问题选项对应的材料信息
            if (option.getJumpToMatterId() == 0) {
                NascMaterial material = option.getMaterial();
                material.setOptionId(option.getId());
                // 存储材料信息
                materialMapper.insertMaterial(material);
                // 保存材料清单
                saveMaterialList(material.getMaterialList(), material.getId());
            }
        }
    }

    /**
     * @Author: Yujianq
     * @Date: 2024/6/13 15:40
     * @Description: 保存材料清单列表
     * @param materialLists
     * @param materialId
     * @return: void
     */
    public void saveMaterialList(List<NascMaterialList> materialLists, Long materialId) {
        for (NascMaterialList materialList: materialLists) {
            materialList.setMaterialId(materialId);
            materialListMapper.insertMaterialList(materialList);
        }
    }

}
