package cn.cslg.report.service.impl;

import cn.cslg.report.common.model.dto.AvoidDesignDirectionDTO;
import cn.cslg.report.common.model.dto.AvoidDesignLittleDirectionDTO;
import cn.cslg.report.common.model.dto.AvoidFeaturesDTO;
import cn.cslg.report.common.model.vo.AvoidDesignRightVO;
import cn.cslg.report.common.model.vo.AvoidDesignWholeVO;
import cn.cslg.report.common.model.vo.AvoidFeaturesVO;
import cn.cslg.report.entity.*;
import cn.cslg.report.exception.XiaoShiException;
import cn.cslg.report.mapper.AssoAvoidDesignWholeLittleDirectionMapper;
import cn.cslg.report.mapper.AvoidDesignLittleDirectionMapper;
import cn.cslg.report.mapper.AvoidDesignWholeDirectionMapper;
import cn.cslg.report.mapper.AvoidFeatureMapper;
import cn.cslg.report.service.IAvoidDesignDirectionService;
import cn.cslg.report.service.OutInterfaceService;
import cn.cslg.report.service.business.FeatureService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 回避设计方案的Service层接口实现类
 *
 * @Author chenyu
 * @Data 2023/2/2
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class AvoidDesignDirectionServiceImpl implements IAvoidDesignDirectionService {
    private final AvoidDesignWholeDirectionMapper avoidDesignWholeDirectionMapper;  //回避设计总体方向表的Mapper层接口装配
    private final AvoidDesignLittleDirectionMapper avoidDesignLittleDirectionMapper;  //回避设计方向表的Mapper层接口装配
    private final AssoAvoidDesignWholeLittleDirectionMapper assoAvoidDesignWholeLittleDirectionMapper;  //回避设计总体方向和方向关联表的Mapper层接口装配
    private final AvoidFeatureMapper avoidFeatureMapper;  //特征标的Mapper层接口装配
    private final OutInterfaceService outInterfaceService;
    private final FeatureService featureService;
    //private final CacheUtils cacheUtils;
    //private final LoginUtils loginUtils;

    /**
     * 新增回避设计方案
     *
     * @param avoidDesignDirectionDTO 回避设计方案数据对象
     */
    @Override
    public void addAvoidDesignDirection(AvoidDesignDirectionDTO avoidDesignDirectionDTO) {
        log.info("开始处理【新增回避设计方案】的业务，参数为：{}", avoidDesignDirectionDTO);

        //1.从回避设计方案中取出报告reportId和回避设计总体方向wholeDirection，将它们插入回避设计总体方向表
        Integer reportId = avoidDesignDirectionDTO.getReportId();
        String wholeDirection = avoidDesignDirectionDTO.getWholeDirection();
        //将获取到的报告reportId与回避设计总体方向wholeDirection数据赋值给回避设计总体方向表实体类后插入
        AvoidDesignWholeDirection avoidDesignWholeDirection = new AvoidDesignWholeDirection()
                .setReportId(reportId)
                .setWholeDirection(wholeDirection);
        //先根据报告id删除原有回避设计总体方向表数据
        log.info("删除原有回避设计总体方向表数据");
        avoidDesignWholeDirectionMapper.deleteByReportId(reportId);
        //将数据插入回避设计总体方向表
        log.info("新增数据插入回避设计总体方向表");
        int rows = avoidDesignWholeDirectionMapper.insert(avoidDesignWholeDirection);
        if (rows != 1) {
            String message = "数据插入回避设计总体方向表失败，新增回避设计方案失败(数据已回滚)，服务器忙请稍后再次尝试";
            log.info("{}", message);
            throw new XiaoShiException(message);
        }

        //2.从回避设计方案中取出权要特征解释等和回避设计方向littleDirection等数据的对象的集合avoidDesignLittleDirectionDTOs，处理后把数据分别插入各自表中
        List<AvoidDesignLittleDirectionDTO> avoidDesignLittleDirectionDTOs = avoidDesignDirectionDTO.getAvoidDesignLittleDirectionDTOs();
        //遍历集合取出每个权要的特征数据插入特征表，插入后取出每个特征的特征featureId和回避设计方向littleDirection存入回避设计方向表
        List<AvoidFeatures> avoidFeatures = new ArrayList<>();
        for (AvoidDesignLittleDirectionDTO avoidDesignLittleDirectionDTO : avoidDesignLittleDirectionDTOs) {
            List<AvoidFeaturesDTO> featuresDTOS = avoidDesignLittleDirectionDTO.getFeatures();
            //avoidFeatures.addAll(features);
            for (AvoidFeaturesDTO featuresDTO : featuresDTOS) {
                AvoidFeatures avoidFeature = new AvoidFeatures();
                BeanUtils.copyProperties(featuresDTO, avoidFeature);
                avoidFeatures.add(avoidFeature);
            }
        }

        //先根据报告id删除原有特征表数据
        log.info("删除原有特征表数据");
        avoidFeatureMapper.deleteByReportId(reportId);
        //遍历清空特征集合中前端传来的初始特征id
        //for (AvoidFeatures avoidFeature : avoidFeatures) {
        //    avoidFeature.setId(null);
        //}
        //批量插入特征数据，插入特征表后再遍历取出特征featureId和回避设计方向littleDirection，存入回避设计方向表实体类对象集合
        log.info("新增数据插入特征表");
        rows = avoidFeatureMapper.insertBatch(avoidFeatures);
        if (rows != avoidFeatures.size()) {
            String message = "数据插入特征表失败，新增回避设计方案失败(数据已回滚)，服务器忙请稍后再次尝试";
            log.info("{}", message);
            throw new XiaoShiException(message);
        }

        List<AvoidDesignLittleDirection> avoidDesignLittleDirections = new ArrayList<>();
        for (AvoidFeatures avoidFeature : avoidFeatures) {
            Integer featureId = avoidFeature.getId();
            Integer rightId = avoidFeature.getRightId();
            String littleDirection = avoidFeature.getLittleDirection();
            AvoidDesignLittleDirection avoidDesignLittleDirection = new AvoidDesignLittleDirection()
                    .setReportId(reportId)
                    .setFeatureId(featureId)
                    .setRightId(rightId)
                    .setLittleDirection(littleDirection);
            avoidDesignLittleDirections.add(avoidDesignLittleDirection);
        }
        //先根据报告id删除原有回避设计方向表数据
        log.info("删除原有回避设计方向表数据");
        avoidDesignLittleDirectionMapper.deleteByReportId(reportId);
        //将数据插入回避设计方向表
        log.info("新增数据插入回避设计方向表");
        rows = avoidDesignLittleDirectionMapper.insertBatch(avoidDesignLittleDirections);
        if (rows != avoidDesignLittleDirections.size()) {
            String message = "数据插入回避设计方向表失败，新增回避设计方案失败(数据已回滚)，服务器忙请稍后再次尝试";
            log.info("{}", message);
            throw new XiaoShiException(message);
        }

        //3.以上回避设计总体方向等数据和回避设计方向等数据分别插入两张表后，再取出各自的id，将两个id(回避设计总体方向avoidDesignWholeDirectionId、回避设计方向avoidDesignLittleDirectionId)插入回避设计总体方向和回避设计方向关联表
        Integer avoidDesignWholeDirectionId = avoidDesignWholeDirection.getId();
        ArrayList<Integer> avoidDesignLittleDirectionIds = new ArrayList<>();
        for (AvoidDesignLittleDirection avoidDesignLittleDirection : avoidDesignLittleDirections) {
            Integer avoidDesignLittleDirectionId = avoidDesignLittleDirection.getId();
            avoidDesignLittleDirectionIds.add(avoidDesignLittleDirectionId);
        }
        //将获取到的回避设计总体方向avoidDesignWholeDirectionId与回避设计方向avoidDesignLittleDirectionId赋值给新创建的回避设计总体方向和回避设计方向关联表实体类后插入
        ArrayList<AssoAvoidDesignWholeLittleDirection> assoAvoidDesignWholeLittleDirections = new ArrayList<>();
        for (Integer avoidDesignLittleDirectionId : avoidDesignLittleDirectionIds) {
            AssoAvoidDesignWholeLittleDirection assoAvoidDesignWholeLittleDirection = new AssoAvoidDesignWholeLittleDirection()
                    .setReportId(reportId)
                    .setAvoidDesignWholeDirectionId(avoidDesignWholeDirectionId)
                    .setAvoidDesignLittleDirectionId(avoidDesignLittleDirectionId);
            assoAvoidDesignWholeLittleDirections.add(assoAvoidDesignWholeLittleDirection);
        }
        //先根据报告id删除原有回避设计总体方向和回避设计方向关联表数据
        log.info("删除原有回避设计总体方向和回避设计方向关联表数据");
        assoAvoidDesignWholeLittleDirectionMapper.deleteByReportId(reportId);
        //将数据插入回避设计总体方向和回避设计方向关联表
        log.info("新增数据插入回避设计总体方向和回避设计方向关联表");
        rows = assoAvoidDesignWholeLittleDirectionMapper.insertBatch(assoAvoidDesignWholeLittleDirections);
        if (rows != assoAvoidDesignWholeLittleDirections.size()) {
            String message = "数据插入回避设计总体方向和回避设计方向关联表失败，新增回避设计方案失败(数据已回滚)，服务器忙请稍后再次尝试";
            log.info("{}", message);
            throw new XiaoShiException(message);
        }

        log.info("新增回避设计方案完成");

    }

    @Override
    public AvoidDesignWholeVO getAvoidDesignDirection(Integer reportId) {
        log.info("开始处理【查询回避设计方案】的业务，参数为：{}", reportId);
        String signPatentNo = avoidDesignLittleDirectionMapper.selectSignPatentNoByReportId(reportId);
        //从pas获得权要信息
        String resBody = null;
        try {
            resBody = outInterfaceService.getPatentRightFromPAS(signPatentNo);
        } catch (IOException e) {
            log.info("发生IO异常");
        }
        JSONObject jsonObject = JSONObject.parseObject(resBody);
        //解析jason获得标的专利的权要
        List<PatentRight> patentRightsOrgin = JSON.parseArray(jsonObject.getString("data"), PatentRight.class);
        //给权要进行格式更改
        List<PatentRight> patentRights = featureService.FormatPatentRights(patentRightsOrgin,signPatentNo);

        ArrayList<AvoidDesignRightVO> rights = new ArrayList<>();
        for (PatentRight patentRight : patentRights) {
            Integer rightId = patentRight.getSort();
            //根据当前权要id和报告id关联查询当前权要的所有特征和特征对应的回避设计方向
            List<AvoidFeaturesVO> features = avoidDesignLittleDirectionMapper.selectWholeByRightIdAndReportId(rightId, reportId);
            AvoidDesignRightVO right = new AvoidDesignRightVO()
                    .setFeatures(features)
                    .setSort(rightId)
                    .setRightName(patentRight.getRightName())
                    .setContent(patentRight.getContent())
                    .setContentOut(patentRight.getContentOut())
                    .setPatentId(patentRight.getPatentId())
                    .setType(patentRight.getType());
            rights.add(right);
        }
        AvoidDesignWholeVO avoidDesignWholeVO = new AvoidDesignWholeVO().setRights(rights);
        String wholeDirection = avoidDesignWholeDirectionMapper.selectWholeDirectionByReportId(reportId);
        avoidDesignWholeVO.setWholeDirection(wholeDirection);
        return avoidDesignWholeVO;
    }

    @Override
    public void deleteAvoidDesignDirection(Integer reportId) {
        log.info("开始处理【删除回避设计方案】的业务，参数为：{}", reportId);
        String wholeDirection = avoidDesignWholeDirectionMapper.selectWholeDirectionByReportId(reportId);
        if (wholeDirection != null) {
            avoidFeatureMapper.deleteByReportId(reportId);
            avoidDesignWholeDirectionMapper.deleteByReportId(reportId);
            avoidDesignLittleDirectionMapper.deleteByReportId(reportId);
            assoAvoidDesignWholeLittleDirectionMapper.deleteByReportId(reportId);
            log.info("删除回避设计方案完成");
        } else {
            log.info("删除回避设计方案失败，回避设计方案不存在");
        }

    }


}
