package cn.cslg.pas.service;

import cn.cslg.pas.common.model.vo.PatentInventorVO;
import cn.cslg.pas.common.model.params.PatentInventorAddressParams;
import cn.cslg.pas.common.utils.DateUtils;
import cn.cslg.pas.common.utils.Response;
import cn.cslg.pas.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.pas.common.utils.StringUtils;
import cn.cslg.pas.domain.*;
import cn.cslg.pas.mapper.PatentInventorMapper;
import cn.cslg.pas.common.model.params.PatentInventorParams;
import cn.cslg.pas.common.utils.PatentUtils;
import cn.dev33.satoken.stp.StpUtil;
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.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 专利信息发明人表 服务类
 * </p>
 *
 * @author 王岩
 * @since 2022-02-24
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class PatentInventorService extends ServiceImpl<PatentInventorMapper, PatentInventor> {

    private final ProjectPatentLinkService projectPatentLinkService;
    private final PatentInventorLinkService patentInventorLinkService;
    private final PatentService patentService;
    private final PatentInventorMergeService patentInventorMergeService;
    private final LoginUtils loginUtils;
    public List<Integer> getInventorIdsByProjectId(Integer projectId) {
        List<ProjectPatentLink> projectPatentLinkList = projectPatentLinkService.getProjectPatentsByProjectId(projectId);
        List<PatentInventorLink> patentInventorLinkList = patentInventorLinkService.getPatentInventorLinkByPatentIds(projectPatentLinkList.stream().map(ProjectPatentLink::getPatentId).collect(Collectors.toList()));
        return patentInventorLinkList.stream().map(PatentInventorLink::getInventorId).collect(Collectors.toList());
    }

    public IPage<PatentInventor> getPageList(PatentInventorVO params) {
        LambdaQueryWrapper<PatentInventor> queryWrapper = new LambdaQueryWrapper<>();
        if (params.getProjectId() != null && !params.getMerge()) {
            List<Integer> ids = this.getInventorIdsByProjectId(params.getProjectId());
            if (ids.size() == 0) {
                queryWrapper.eq(PatentInventor::getId, 0);
            } else {
                queryWrapper.in(PatentInventor::getId, ids);
            }
        }
        if (params.getMerge()) {
            queryWrapper.eq(PatentInventor::getProjectId, params.getProjectId());
        }
        if (StringUtils.isNotEmpty(params.getName())) {
            queryWrapper.like(PatentInventor::getName, params.getName());
        }
        queryWrapper.eq(PatentInventor::getMerge, params.getMerge());
        if (StringUtils.isNotEmpty(params.getIds())) {
            queryWrapper.last(String.format("order by id not in (%s)", params.getIds()));
        }
        IPage<PatentInventor> pageList = this.page(new Page<>(params.getCurrent(), params.getSize()), queryWrapper);
        List<PatentInventorMerge> patentInventorMergeList = patentInventorMergeService.getPatentInventorMergeByProjectId(params.getProjectId());
        pageList.getRecords().forEach(item -> item.setInventorIds(patentInventorMergeList.stream().filter(patentInventorMerge -> patentInventorMerge.getMergeId().equals(item.getId())).map(PatentInventorMerge::getInventorId).collect(Collectors.toList())));
        return pageList;
    }

    @Transactional
    public String add(PatentInventor patentInventor) {
        PatentInventor temp = this.getPatentInventorByName(patentInventor.getName());
        if (temp != null) {
            return Response.error("名称已存在");
        }
        patentInventor.setUpdateTime(DateUtils.getDateTime());
        patentInventor.setCreateBy(loginUtils.getId());
        patentInventor.insert();
        if (patentInventor.getMerge()) {
            patentInventorMergeService.updatePatentInventorMergeLink(patentInventor.getId(), patentInventor.getProjectId(), patentInventor.getInventorIds());
        }
        return Response.success(true);
    }

    @Transactional
    public String edit(PatentInventor patentInventor) {
        PatentInventor temp = this.getPatentInventorByName(patentInventor.getName());
        if (temp != null && !temp.getId().equals(patentInventor.getId())) {
            return Response.error("名称已存在");
        }
        patentInventor.setUpdateTime(DateUtils.getDateTime());
        patentInventor.updateById();
        if (patentInventor.getMerge()) {
            patentInventorMergeService.updatePatentInventorMergeLink(patentInventor.getId(), patentInventor.getProjectId(), patentInventor.getInventorIds());
        }
        return Response.success(true);
    }

    public String delete(Integer id) {
        this.removeById(id);
        patentInventorMergeService.deleteByMergeId(id);
        return Response.success(true);
    }

    public PatentInventor getPatentInventorByName(String name) {
        LambdaQueryWrapper<PatentInventor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PatentInventor::getName, name);
        return this.getOne(queryWrapper);
    }

    public List<PatentInventor> getPatentInventorByNameList(List<String> nameList) {
        if (nameList == null || nameList.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<PatentInventor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(PatentInventor::getName, nameList);
        return this.list(queryWrapper);
    }

    public List<PatentInventor> getPatentInventorByIds(List<Integer> ids) {
        if (ids == null || ids.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<PatentInventor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(PatentInventor::getId, ids);
        return this.list(queryWrapper);
    }

    public List<PatentInventor> getPatentInventorByPatentId(Integer patentId) {
        List<PatentInventorLink> patentInventorLinkList = patentInventorLinkService.getPatentInventorLinkByPatentId(patentId);
        List<PatentInventor> dataList = this.getPatentInventorByIds(patentInventorLinkList.stream().map(PatentInventorLink::getInventorId).collect(Collectors.toList()));
        dataList.forEach(data -> {
            PatentInventorLink patentInventorLink = patentInventorLinkList.stream().filter(item -> item.getInventorId().equals(data.getId()) && item.getFirst().equals(1)).findFirst().orElse(null);
            data.setFirst(patentInventorLink != null);
        });
        return dataList;
    }

    public List<PatentInventor> getPatentInventorByPatentIds(List<Integer> patentIds) {
        List<PatentInventorLink> patentInventorLinkList = patentInventorLinkService.getPatentInventorLinkByPatentIds(patentIds);
        List<PatentInventor> patentInventorList = this.getPatentInventorByIds(patentInventorLinkList.stream().map(PatentInventorLink::getInventorId).collect(Collectors.toList()));
        List<PatentInventor> dataList = new ArrayList<>();
        patentInventorLinkList.forEach(patentInventorLink -> {
            PatentInventor temp = patentInventorList.stream().filter(item -> item.getId().equals(patentInventorLink.getInventorId())).findFirst().orElse(null);
            if (temp != null) {
                PatentInventor patentInventor = new PatentInventor();
                patentInventor.setPatentId(patentInventorLink.getPatentId());
                patentInventor.setId(patentInventorLink.getInventorId());
                patentInventor.setName(temp.getName());
                dataList.add(patentInventor);
            }
        });
        return dataList;
    }

    public void importPatentInventor(Integer localPatentId, Integer importPatentId, List<PatentInventor> importPatentInventorList, List<PatentInventorLink> importPatentInventorLinkList) {
        patentInventorLinkService.deleteByPatentId(localPatentId);
        List<PatentInventorLink> importPatentInventorLinks = importPatentInventorLinkList.stream().filter(item -> item.getPatentId().equals(importPatentId)).collect(Collectors.toList());
        List<Integer> inventorIds = importPatentInventorLinks.stream().map(PatentInventorLink::getInventorId).collect(Collectors.toList());
        List<PatentInventor> importPatentInventors = importPatentInventorList.stream().filter(item -> inventorIds.contains(item.getId())).collect(Collectors.toList());
        List<PatentInventor> localPatentInventors = this.getPatentInventorByNameList(importPatentInventors.stream().map(PatentInventor::getName).collect(Collectors.toList()));
        for (PatentInventor importPatentInventor : importPatentInventors) {
            PatentInventor localPatentInventor = localPatentInventors.stream().filter(item -> item.getName().equals(importPatentInventor.getName())).findFirst().orElse(null);
            List<PatentInventorLink> importPatentInventorLink = importPatentInventorLinks.stream().filter(item -> item.getInventorId().equals(importPatentInventor.getId())).collect(Collectors.toList());
            Integer patentInventorId;
            if (localPatentInventor == null) {
                localPatentInventor = new PatentInventor();
                patentInventorId = null;
            } else {
                patentInventorId = localPatentInventor.getId();
            }
            BeanUtils.copyProperties(importPatentInventor, localPatentInventor);
            localPatentInventor.setId(patentInventorId);
            localPatentInventor.insertOrUpdate();
            for (PatentInventorLink patentInventorLink : importPatentInventorLink) {
                patentInventorLink.setId(null);
                patentInventorLink.setInventorId(localPatentInventor.getId());
                patentInventorLink.setPatentId(localPatentId);
            }
            patentInventorLinkService.saveOrUpdateBatch(importPatentInventorLink);
        }
    }

    public void updatePatentInventor(PatentInventorParams params) {
        if (params.getNameList() != null && params.getNameList().size() != 0) {
            //创建发明人表"os_patent_inventor"实体类集合，准备批量插入数据
            List<PatentInventor> dataList = new ArrayList<>();
            //遍历发明人名称
            for (int i = 0; i < params.getNameList().size(); i++) {
                //根据名称查询发明人表"os_patent_inventor"数据
                PatentInventor patentInventor = this.getPatentInventorByName(params.getNameList().get(i));
                //判断若没有该发明人，则发明人实体类装载数据新增发明人（若已有，则更新已有数据）
                if (patentInventor == null) {
                    patentInventor = new PatentInventor();
                }
                patentInventor.setName(params.getNameList().get(i));
                patentInventor.setMerge(false);
                if (params.getAddressList().size() > i) {
                    patentInventor.setAddress(params.getAddressList().get(i));
                    if (params.getAddressList().get(i).substring(params.getAddressList().get(i).lastIndexOf(",") + 1).replaceAll(" ", "").length() == 2) {
                        patentInventor.setCountry(params.getAddressList().get(i).substring(params.getAddressList().get(i).lastIndexOf(",") + 1).replaceAll(" ", ""));
                    }
                } else {
                    if (patentInventor.getAddress() == null || patentInventor.getAddress().equals("")) {
                        patentInventor.setAddress("");
                        patentInventor.setCountry("");
                    }
                }
                dataList.add(patentInventor);
            }
            //批量插入或更新专利发明人表"os_patent_inventor"数据
            this.saveOrUpdateBatch(dataList);
            PatentInventor first = dataList.stream().filter(item -> item.getName().equals(params.getFirstName())).findFirst().orElse(null);
            //准备将专利与发明人关联数据插入专利与发明人关联表"os_patent_inventor_relation"
            patentInventorLinkService.updatePatentInventLink(dataList.stream().map(PatentInventor::getId).collect(Collectors.toList()), params.getPatentId(), first == null ? 0 : first.getId());
        }
    }

    public void updatePatentInventorAddress(PatentInventorAddressParams params) {
        List<PatentInventor> patentInventorList = this.getPatentInventorByPatentId(params.getPatentId());

        for (int i = 0; i < params.getAddress().size(); i++) {
            if (StringUtils.isNotEmpty(params.getAddress().get(i))) {
                patentInventorList.get(i).setAddress(params.getAddress().get(i));
                if (params.getAddress().get(i).substring(params.getAddress().get(i).lastIndexOf(",") + 1).length() == 2) {
                    patentInventorList.get(i).setCountry(params.getAddress().get(i).substring(params.getAddress().get(i).lastIndexOf(",") + 1).replaceAll(" ", ""));
                } else {
                    patentInventorList.get(i).setCountry("");
                }

            }
        }
        this.saveOrUpdateBatch(patentInventorList);
        if (StringUtils.isNotEmpty(params.getFirstAddress())) {
            PatentInventor patentInventor = patentInventorList.stream().filter(PatentInventor::getFirst).findFirst().orElse(null);
            if (patentInventor != null) {
                patentInventor.setAddress(params.getFirstAddress().replaceAll(" ", ""));
                patentInventor.setCountry(params.getFirstAddress().substring(params.getFirstAddress().lastIndexOf(",") + 1).replaceAll(" ", ""));
                patentInventor.updateById();
            }
        }
    }

}
