package com.ruoyi.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SnowflakeUtil;
import com.ruoyi.domain.*;
import com.ruoyi.mapper.ReviewDetailsMapper;
import com.ruoyi.mapper.ReviewKeyPointMapper;
import com.ruoyi.mapper.ReviewStandardMapper;
import com.ruoyi.service.*;
import com.ruoyi.web.request.ReviewFindListRequest;
import com.ruoyi.web.request.ReviewStandardListByPageRequest;
import com.ruoyi.web.request.ReviewStandardListRequest;
import com.ruoyi.web.response.ReviewStandardInspectionContentResponse;
import com.ruoyi.web.response.ReviewStandardListResponse;
import com.ruoyi.web.response.ReviewStandardResponse;
import com.ruoyi.web.response.ReviewStandardTestInspectionContentResponse;
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.Date;
import java.util.List;

@Transactional
@Service
public class ReviewStandardServiceImpl extends ServiceImpl<ReviewStandardMapper, ReviewStandard> implements ReviewStandardService {

    @Autowired
    private ReviewKeyPointService reviewKeyPointService;

    @Autowired
    private ReviewDetailsService reviewDetailsService;

    @Autowired
    private ReviewSceneService reviewSceneService;

    @Autowired
    private ReviewStandardMapper reviewStandardMapper;

    @Autowired
    private ReviewKeyPointMapper reviewKeyPointMapper;

    @Autowired
    private ReviewDetailsMapper reviewDetailsMapper;

    /**
     * 查询所有审查 标准、要点、细则、场景 并组织成树状结构返回
     * @param standardId 关联到标准库中的id
     * @param type 问卷类型[system(体系审查),car(车型审查)]
     * @return
     */
    @Override
    public List<ReviewStandard> findTree(Long standardId, String type) {

        List<ReviewStandard> reviewStandardList = reviewStandardMapper.findListByStandardIdAndType(standardId, type); // 查询审查标准
        List<ReviewKeyPoint> reviewKeyPointList = reviewKeyPointService.findByStandardList(reviewStandardList); // 查询审查要点
        List<ReviewDetails> reivewDetailsList = reviewDetailsService.findByKeyPointsList(reviewKeyPointList); // 查询审查细则
        List<ReviewScene> reviewSceneList = reviewSceneService.findByDetailsList(reivewDetailsList); // 查询审查场景

        return buildTree(reviewStandardList, reviewKeyPointList, reivewDetailsList, reviewSceneList);

    }

    /**
     * 分页查询标准列表
     *
     * @return
     */
    @Override
    public List<ReviewStandardResponse> listByPage(ReviewStandardListByPageRequest request) {
        List<ReviewStandardResponse> list = reviewStandardMapper.selectReviewStandardList(request);
        return list;
    }

    /**
     * 通过标准ID查询检验内容(树状结构)
     *
     * @param id
     * @return
     */
    @Override
    public ReviewStandardInspectionContentResponse selectInspectionContent(Long id) {
        // 模拟一个审查标准集合
        ReviewStandard reviewStandard = ReviewStandard.builder().id(id).build();
        List<ReviewStandard> reviewStandardList = new ArrayList<>();
        reviewStandardList.add(reviewStandard);
        // 查询审查要点
        List<ReviewKeyPoint> reviewKeyPointList = reviewKeyPointService.findByStandardList(reviewStandardList);
        // 查询审查细则
        List<ReviewDetails> reivewDetailsList = reviewDetailsService.findByKeyPointsList(reviewKeyPointList);
        // 查询审查场景
        List<ReviewScene> reviewSceneList = reviewSceneService.findByDetailsList(reivewDetailsList);
        // 调用方法把数据变为树状结构
        List<ReviewDetails> reviewDetails = buildDetails(reivewDetailsList, reviewSceneList);
        List<ReviewKeyPoint> keyPoints = buildKeyPoint(reviewKeyPointList, reviewDetails);
        ReviewStandardInspectionContentResponse response = ReviewStandardInspectionContentResponse.builder().keyPointList(keyPoints).build();
        return response;
    }

    /**
     * 根据标准主键ID查询车型试验的检验内容
     * @param id
     * @return
     */
    @Override
    public List<ReviewStandardTestInspectionContentResponse> selectTestInspectionContent(Long id) {
        List<ReviewStandardTestInspectionContentResponse> list = reviewStandardMapper.selectTestInspectionContent(id);
        return list;
    }

    @Override
    public List<ReviewStandardListResponse> findReviewStandardList(ReviewStandardListRequest request) {
        return reviewStandardMapper.findReviewStandardList(request);
    }

    // 标准-要点
    @Override
    public List<ReviewStandard> findKeyPointList(ReviewFindListRequest request) {

        List<ReviewKeyPoint> keyPointList = reviewKeyPointMapper.findKeyPointList(request);

        List<ReviewStandard> standardList = reviewStandardMapper.findByKeyPointList(keyPointList,request);

        return onlyBuildStandard(standardList,keyPointList);
    }

    // 标准-要点-细则
    @Override
    public List<ReviewStandard> findDetailsList(ReviewFindListRequest request) {

        List<ReviewDetails> detailsList = reviewDetailsMapper.findDetailsList(request);

        List<ReviewKeyPoint> keyPointList = reviewKeyPointMapper.findByDetailsList(detailsList);

        List<ReviewStandard> standardList = reviewStandardMapper.findByKeyPointList(keyPointList,request);

        List<ReviewKeyPoint> keyPointListTree = buildKeyPoint(keyPointList,detailsList);

        return buildStandard(standardList,keyPointListTree);
    }

    /**
     * 将审查 标准、要点、细则、场景 按照父子关系拆分写入到各自的表中
     * @param reviewStandardList
     */
    @Override
    public void initData(List<ReviewStandard> reviewStandardList) {

        Date now = new Date();

        for(ReviewStandard reviewStandard : reviewStandardList) {
            initStandard(SnowflakeUtil.generate(), reviewStandard);
        }
    }

    /**
     * 保存审查标准数据
     * @param id
     * @param reviewStandard
     */
    private void initStandard(Long id, ReviewStandard reviewStandard) {
        reviewStandard.setId(id);
        initKeyPoint(id, reviewStandard.getKeyPointList());
        save(reviewStandard);
    }

    /**
     * 保存审查要点数据
     * @param parentId
     * @param reviewKeyPointList
     */
    private void initKeyPoint(Long parentId, List<ReviewKeyPoint> reviewKeyPointList) {
        for(ReviewKeyPoint reviewKeyPoint : reviewKeyPointList) {
            Long id = SnowflakeUtil.generate();
            reviewKeyPoint.setId(id);
            reviewKeyPoint.setReviewStandardId(parentId);
            initDetails(id, reviewKeyPoint.getReviewDetailsList());
            reviewKeyPointService.save(reviewKeyPoint);
        }
    }

    /**
     * 保存审查细则数据
     * @param parentId
     * @param reviewDetailsList
     */
    private void initDetails(Long parentId, List<ReviewDetails> reviewDetailsList) {
        for(ReviewDetails reviewDetails : reviewDetailsList) {
            Long id = SnowflakeUtil.generate();
            reviewDetails.setId(id);
            reviewDetails.setReviewKeypointId(parentId);
            initScene(id, reviewDetails.getReviewSceneList());
            reviewDetailsService.save(reviewDetails);
        }
    }

    /**
     * 保存审查场景数据
     * @param parentId
     * @param reviewSceneList
     */
    private void initScene(Long parentId, List<ReviewScene> reviewSceneList) {

        Date now = new Date();

        for(ReviewScene reviewScene : reviewSceneList) {
            Long id = SnowflakeUtil.generate();
            reviewScene.setId(id);
            reviewScene.setReviewDetailsId(parentId);
            reviewSceneService.save(reviewScene);

        }
    }

    /**
     * 将审查 标准、要点、细则、场景 组织成树状结构返回
     * @param reviewStandardList 审查标准集合
     * @param reviewKeyPointList 审查要点集合
     * @param reviewDetailsList  审查细则集合
     * @param reviewSceneList    审查场景集合
     * @return
     */
    private List<ReviewStandard> buildTree(List<ReviewStandard> reviewStandardList, List<ReviewKeyPoint> reviewKeyPointList, List<ReviewDetails> reviewDetailsList, List<ReviewScene> reviewSceneList) {

        List<ReviewDetails> reviewDetails = buildDetails(reviewDetailsList, reviewSceneList);
        List<ReviewKeyPoint> keyPoints = buildKeyPoint(reviewKeyPointList, reviewDetails);
        List<ReviewStandard> standards = buildStandard(reviewStandardList, keyPoints);

        return standards;
    }

    /**
     * 构建父子关系 - 审查细则&审查场景
     * @param reviewDetailsList 审查细则集合
     * @param reviewSceneList   审查场景集合
     * @return
     */
    private List<ReviewDetails> buildDetails(List<ReviewDetails> reviewDetailsList, List<ReviewScene> reviewSceneList) {

        for(ReviewDetails reviewDetails : reviewDetailsList) {

            Long detailsId = reviewDetails.getId();
            List<ReviewScene> children = new ArrayList<>();

            for(ReviewScene reviewScene : reviewSceneList) {
                if(reviewScene.getReviewDetailsId().equals(detailsId)) {
                    children.add(reviewScene);
                }
            }

            if(children.size() > 0) {
                reviewDetails.setReviewSceneList(children);
            }

        }

        return reviewDetailsList;

    }

    /**
     * 构建父子关系 - 审查要点&审查细则
     * @param reviewKeyPointList 审查要点集合
     * @param reviewDetailsList  审查细则集合
     * @return
     */
    private List<ReviewKeyPoint> buildKeyPoint(List<ReviewKeyPoint> reviewKeyPointList, List<ReviewDetails> reviewDetailsList) {

        for(ReviewKeyPoint reviewKeyPoint : reviewKeyPointList) {

            Long keyPointId = reviewKeyPoint.getId();
            List<ReviewDetails> children = new ArrayList<>();

            for(ReviewDetails reviewDetails : reviewDetailsList) {
                if(reviewDetails.getReviewKeypointId().equals(keyPointId)) {
                    reviewDetails.setReviewKeypointText(reviewKeyPoint.getText());
                    children.add(reviewDetails);
                }
            }

            if(children.size() > 0) {
                reviewKeyPoint.setReviewDetailsList(children);
            }
        }


        return reviewKeyPointList;
    }

    /**
     * 构建负责关系 - 审查标准&审查要点
     * @param reviewStandardList 审查标准集合
     * @param reviewKeyPointList 审查要点集合
     * @return
     */
    private List<ReviewStandard> buildStandard(List<ReviewStandard> reviewStandardList, List<ReviewKeyPoint> reviewKeyPointList) {

        for(ReviewStandard reviewStandard : reviewStandardList) {

            Long standardId = reviewStandard.getId();
            List<ReviewKeyPoint> children = new ArrayList<>();

            for(ReviewKeyPoint reviewKeyPoint : reviewKeyPointList) {
                if(reviewKeyPoint.getReviewStandardId().equals(standardId)) {

                    // 为该要点下的所有细则冗余标准信息,便于前端显示
                    reviewKeyPoint.getReviewDetailsList().stream().forEach(details -> {
                        details.setStandardText(reviewStandard.getText());
                        details.setStandardId(reviewStandard.getId());
                        details.setChapter(reviewStandard.getChapter());
                    });

                    children.add(reviewKeyPoint);
                }
            }

            if(children.size() > 0) {
                reviewStandard.setKeyPointList(children);
            }

        }

        return reviewStandardList;
    }

    /**
     * 构建负责关系 - 只构建 审查标准&审查要点
     * @param reviewStandardList
     * @param reviewKeyPointList
     * @return
     */
    private List<ReviewStandard> onlyBuildStandard(List<ReviewStandard> reviewStandardList, List<ReviewKeyPoint> reviewKeyPointList) {

        for(ReviewStandard reviewStandard : reviewStandardList) {

            Long standardId = reviewStandard.getId();
            List<ReviewKeyPoint> children = new ArrayList<>();

            for(ReviewKeyPoint reviewKeyPoint : reviewKeyPointList) {
                if(reviewKeyPoint.getReviewStandardId().equals(standardId)) {
                    children.add(reviewKeyPoint);
                }
            }

            if(children.size() > 0) {
                reviewStandard.setKeyPointList(children);
            }

        }

        return reviewStandardList;
    }


}