package cn.cslg.pas.service.asso;

import cn.cslg.pas.common.core.base.Constants;
import cn.cslg.pas.common.model.QueryPatentVO;
import cn.cslg.pas.common.model.dto.PatentDTO;
import cn.cslg.pas.common.model.dto.ProductPatentDTO;
import cn.cslg.pas.common.utils.DateUtils;
import cn.cslg.pas.common.utils.StringUtils;
import cn.cslg.pas.domain.*;
import cn.cslg.pas.domain.asso.AssoStructurePatent;
import cn.cslg.pas.domain.asso.AssoProductPatent;
import cn.cslg.pas.mapper.asso.AssoProductPatentMapper;
import cn.cslg.pas.service.*;
import cn.cslg.pas.service.impl.StructurePatentServiceImpl;
import cn.cslg.pas.service.impl.StructureServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 后台部门表 服务类
 * </p>
 *
 * @author 王岩
 * @since 2022-03-25
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class AssoProductPatentService extends ServiceImpl<AssoProductPatentMapper, AssoProductPatent> {
    private final PatentApplicantService patentApplicantService;
    private final PatentAffairService patentAffairService;
    private final PatentLabelService patentLabelService;
    private final ProjectFieldService projectFieldService;
    private final PatentInventorService patentInventorService;
    private final PatentAgencyService patentAgencyService;
    private final PatentAgentService patentAgentService;
    private final PatentClassNumberLinkService patentClassNumberLinkService;
    private final SystemDictService systemDictService;
    private final PatentSimpleFamilyLinkService patentSimpleFamilyLinkService;
    private final StructurePatentServiceImpl assoStructurePatentService;
    private final StructureServiceImpl structureService;

    /**
     * 给产品添加相关专利
     */
    @Transactional
    public List<String> addPatents(ProductPatentDTO patentDTO) {
        List<String> orgPatentNos = new ArrayList<>();
        if (patentDTO.getPatentNo() != null) {
            patentDTO.setPatentNo(patentDTO.getPatentNo().replace(" ", ""));
            if (!patentDTO.getPatentNo().equals("")) {
                String[] strs = patentDTO.getPatentNo().split("\\|");
                patentDTO.setPatentNo("(^|,)(" + patentDTO.getPatentNo() + ")(,|$)");
                orgPatentNos = new ArrayList<>(Arrays.asList(strs));
                patentDTO.setIsIn(0);
                List<String> patentNos = this.baseMapper.getPatentNos(patentDTO);
                orgPatentNos.removeAll(patentNos);
                if (patentNos.size() > 0) {
                    this.baseMapper.insertBatch(patentNos, patentDTO.getProductId());
                }
            }
        }
        return orgPatentNos;
    }


    public int addPatents(List<String> patentNos, Integer productId) {
        LambdaQueryWrapper<AssoProductPatent> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AssoProductPatent::getPatentNo);
        wrapper.eq(AssoProductPatent::getProductId, productId);
        wrapper.in(AssoProductPatent::getPatentNo, patentNos);
        List<String> patentNo = this.listObjs(wrapper, Object::toString);
        ArrayList<String> list = new ArrayList<>();
        list.addAll(patentNos);
        list.removeAll(patentNo);
        if (patentNos.size() == 0) {
            return -1;
        }
        return this.baseMapper.insertBatch(patentNos, productId);
    }

    @Transactional(rollbackFor = Exception.class)
    public List<String> deletePatents(ProductPatentDTO patentDTO) {
        patentDTO.setIsIn(1);
        List<String> patentNos = new ArrayList<>();
        if (patentDTO.getStartNumber() != null && patentDTO.getEndNumber() != null && patentDTO.getEndNumber() >= patentDTO.getStartNumber()) {
            patentDTO.setStartNumber(patentDTO.getStartNumber() - 1);
            patentDTO.setEndNumber(patentDTO.getEndNumber() - patentDTO.getStartNumber());
            patentNos = this.baseMapper.getPatentNos(patentDTO);
        }
        if (patentDTO.getPatentNos() != null && patentDTO.getPatentNos().size() > 0) {
            for (String item : patentDTO.getPatentNos()) {
                if (!patentNos.contains(item)) {
                    patentNos.add(item);
                }
            }
        }
        if (patentDTO.getNotInPatentNos() != null) {
            patentNos.removeAll(patentDTO.getNotInPatentNos());
        }

        List<String> assoPatents = new ArrayList<>();
        if (patentNos.size() != 0) {
            LambdaQueryWrapper<AssoStructurePatent> assoWrapper = new LambdaQueryWrapper<>();
            assoWrapper.select(AssoStructurePatent::getPatentNo);
            assoWrapper.eq(AssoStructurePatent::getProjectId, patentDTO.getProductId())
                    .in(AssoStructurePatent::getPatentNo, patentNos);
            assoPatents = assoStructurePatentService.listObjs(assoWrapper, Object::toString);
            LambdaQueryWrapper<AssoProductPatent> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(AssoProductPatent::getProductId, patentDTO.getProductId());
            wrapper.in(AssoProductPatent::getPatentNo, patentNos);
            this.remove(wrapper);
            return assoPatents;
        }
        return patentNos;
    }

    public IPage<PatentDTO> getPageList(QueryPatentVO params) {
        IPage<PatentDTO> pageList = new Page<>();
        //当产品Id为null
//        if (params.getProductId() == null) {
//            //当架构id不为null时
//            if (params.getStructureId() != null) {
//                Structure structure = structureService.getById(params.getStructureId());
//                params.setProductId(structure.getProductId());
//            } else {
//                return pageList;
//            }
//
//        }
        IPage<Patent> dataPage = baseMapper.getPageList(new Page<>(params.getCurrent(), params.getSize()), params);

        List<PatentDTO> records = new ArrayList<>();
        List<Integer> patentIds = dataPage.getRecords().stream().map(Patent::getId).collect(Collectors.toList());
        List<PatentApplicant> patentApplicantList = patentApplicantService.getPatentApplicantByPatentIds(patentIds);
        List<PatentInventor> patentInventorList = patentInventorService.getPatentInventorByPatentIds(patentIds);
        List<PatentLabel> patentLabelList = patentLabelService.getPatentLabelByPatentIdsAndProjectId(patentIds, params.getProjectId());
        List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(patentIds);
        List<PatentAgent> patentAgentList = patentAgentService.getPatentAgentByPatentIds(patentIds);
        List<PatentAgency> patentAgencyList = patentAgencyService.getPatentAgencyByIds(dataPage.getRecords().stream().filter(item -> StringUtils.isNotEmpty(item.getAgencyId())).map(item -> Integer.parseInt(item.getAgencyId())).distinct().collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentSimpleFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getSimpleFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentInpadocFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getInpadocFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentPatSnapFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getPatSnapFamily).collect(Collectors.toList()));
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.PATENT_TYPE, Constants.PATENT_SIMPLE_STATUS));
        dataPage.getRecords().forEach(item -> {
            PatentDTO patentDTO = new PatentDTO();
            BeanUtils.copyProperties(item, patentDTO);
            patentDTO.setApplicationDate(DateUtils.formatDate(item.getApplicationDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPriorityDate(DateUtils.formatDate(item.getPriorityDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicDate(DateUtils.formatDate(item.getPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicAccreditDate(DateUtils.formatDate(item.getPublicAccreditDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setFirstPublicDate(DateUtils.formatDate(item.getFirstPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setSimpleStatus(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getValue().equals(String.valueOf(item.getSimpleStatus()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setType(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_TYPE) && systemDict.getValue().equals(String.valueOf(item.getType()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setApplicant(patentApplicantList.stream().filter(patentApplicant -> patentApplicant.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setInventor(patentInventorList.stream().filter(patentInventor -> patentInventor.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setLabel(patentLabelList.stream().filter(patentLabel -> patentLabel.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setIpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setCpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_CPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setUpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setLocList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_LOC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setAffair(patentAffairService.getPatentAffairByPatentId(item.getId()));
            if (StringUtils.isNotEmpty(item.getAgencyId())) {
                patentDTO.setAgency(patentAgencyList.stream().filter(patentAgency -> patentAgency.getId().equals(Integer.parseInt(item.getAgencyId()))).findFirst().orElse(null));
            }
            PatentDTO.PatentFamily patentFamily = new PatentDTO.PatentFamily();
            patentFamily.setSimple(patentSimpleFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getSimpleFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setInpadoc(patentInpadocFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getInpadocFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setPatSnap(patentPatSnapFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getPatSnapFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentDTO.setFamily(patentFamily);
            patentDTO.setAgent(patentAgentList.stream().filter(patentAgent -> patentAgent.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            // TODO 性能优化
            patentDTO.setField(projectFieldService.getPatentFieldByPatentIdAndProjectId(params.getProjectId(), item.getId()));
            records.add(patentDTO);
        });
        pageList.setTotal(dataPage.getTotal());
        pageList.setRecords(records);
        pageList.setPages(dataPage.getPages());
        pageList.setSize(dataPage.getSize());
        pageList.setCurrent(dataPage.getCurrent());
        Map<String, Object> map = new HashMap<>();
        return pageList;
    }


}
