package cn.cslg.report.service.business;

import cn.cslg.report.common.utils.Response;
import cn.cslg.report.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.report.entity.CompareFiles;
import cn.cslg.report.entity.CompareRecords;
import cn.cslg.report.entity.Features;
import cn.cslg.report.entity.asso.AssoRecordsFeature;
import cn.cslg.report.mapper.CompareRecordsMapper;
import cn.cslg.report.mapper.FeatureMapper;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class CompareRecordsService extends ServiceImpl<CompareRecordsMapper, CompareRecords> {
    public final CompareRecordsMapper compareRecordsMapper;
    public final FeatureMapper featureMapper;
    public final LoginUtils loginUtils;
    public final FeatureService featureService;
    public final AssoRecordsFeatureService assoRecordsFeatureService;
    public final CompareFilesService compareFilesService;

    @Transactional(rollbackFor = Exception.class)
    public String addCompareRecord(CompareRecords compareRecord) throws IOException {
        compareRecord.insert();
        List<AssoRecordsFeature> assoRecordsFeatures = compareRecord.getAssoRecordsFeatures();
        assoRecordsFeatures.forEach(item -> item.setRecordsId(compareRecord.getId()));
        assoRecordsFeatureService.saveBatch(assoRecordsFeatures);
        return Response.success();

    }

    public String deleCompareRecords(int id) throws IOException {
        this.removeById(id);
        return Response.success();
    }

    @Transactional(rollbackFor = Exception.class)
    public String updateCompareRecords(CompareRecords compareRecord) throws IOException {
        LambdaQueryWrapper<AssoRecordsFeature> queryWrapper =new LambdaQueryWrapper<>();
        queryWrapper.eq(AssoRecordsFeature::getRecordsId,compareRecord.getId());
        assoRecordsFeatureService.remove(queryWrapper);
        List<AssoRecordsFeature> assoRecordsFeatures = compareRecord.getAssoRecordsFeatures();
        assoRecordsFeatures.forEach(item -> item.setRecordsId(compareRecord.getId()));
        assoRecordsFeatureService.saveBatch(assoRecordsFeatures);
        return Response.success();
    }

    public String getCompareRecords(CompareRecords compareRecord) throws IOException {
        LambdaQueryWrapper<CompareRecords> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompareRecords::getReportId, compareRecord.getReportId());
        if (compareRecord.getPatentNo() != null) {
            wrapper.eq(CompareRecords::getPatentNo, compareRecord.getPatentNo());
        }
        if(compareRecord.getTaskId()!=null){
           wrapper.eq(CompareRecords::getTaskId,compareRecord.getTaskId());
        }
        List<CompareRecords> list = new ArrayList<>();
        List<CompareRecords> compareRecords = this.list(wrapper);
        if (compareRecords.size() == 0 || compareRecords == null) {
            return Response.success(list);
        }
        List<Integer> ids = compareRecords.stream().map(CompareRecords::getId).collect(Collectors.toList());
        if (ids.size() == 0) {
            return Response.success(compareRecords);
        }
        LambdaQueryWrapper<AssoRecordsFeature> assoWrapper = new LambdaQueryWrapper<>();
        assoWrapper.in(AssoRecordsFeature::getRecordsId, ids);
        List<AssoRecordsFeature> assoRecordsFeatures = assoRecordsFeatureService.list(assoWrapper);
        List<Integer> featureIds = assoRecordsFeatures.stream().map(AssoRecordsFeature::getFeatureId).collect(Collectors.toList());
        List<Features> features = new ArrayList<>();
        if (featureIds.size() != 0 && featureIds != null) {
            LambdaQueryWrapper<Features> featuresLambdaQueryWrapper = new LambdaQueryWrapper<>();
            featuresLambdaQueryWrapper.in(Features::getId, featureIds);
            features = featureService.list(featuresLambdaQueryWrapper);

        }
        List<String> headerPatentNos = new ArrayList<>();
        for (CompareRecords records : compareRecords) {
            List<AssoRecordsFeature> assoRecordsFeatures1 = assoRecordsFeatures.stream().filter(item -> item.getRecordsId().equals(records.getId())).collect(Collectors.toList());
            List<Integer> featureId = assoRecordsFeatures1.stream().map(AssoRecordsFeature::getFeatureId).collect(Collectors.toList());
            records.setAssoRecordsFeatures(assoRecordsFeatures1);
            List<Features> featuresList = features.stream().filter(item -> featureId.contains(item.getId())).collect(Collectors.toList());
            records.setFeaturesIdList(featureId);
            records.setFeatures(featuresList);
            if(!headerPatentNos.contains(records.getPatentNo())){
            headerPatentNos.add(records.getPatentNo());}
}
        List<CompareFiles> compareFiles =new ArrayList<>();
        if(headerPatentNos.size()!=0){
            LambdaQueryWrapper<CompareFiles> lambdaQueryWrapper =new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(CompareFiles::getPatentNo,headerPatentNos).eq(CompareFiles::getReportId,compareRecord.getReportId());
             compareFiles =compareFilesService.list(lambdaQueryWrapper);

        }

        Map<String,Object> map =new HashMap<>();
        map.put("tableHeader",compareFiles);
        map.put("records",compareRecords);
        return Response.success(map);
    }
    public CompareRecords get(int id){
        LambdaQueryWrapper<CompareRecords> lambdaQueryWrapper =new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(CompareRecords::getId,id);
        List<CompareRecords> list = this.list(lambdaQueryWrapper);
        if(list.size()==0){
            return null;
        }
        return list.get(0);

    }


}
