package cn.cslg.pas.service;

import cn.cslg.pas.common.model.BaseEntity;
import cn.cslg.pas.common.model.vo.PatentReadVO;
import cn.cslg.pas.common.utils.JsonUtils;
import cn.cslg.pas.common.utils.StringUtils;
import cn.cslg.pas.domain.Patent;
import cn.cslg.pas.domain.ProjectFolderPatentLink;
import cn.cslg.pas.domain.ProjectPatentLink;
import cn.cslg.pas.mapper.ProjectPatentLinkMapper;
import cn.cslg.pas.common.utils.CacheUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 专题库关联专利信息表 服务实现类
 * </p>
 *
 * @author 王岩
 * @since 2022-01-24
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class ProjectPatentLinkService extends ServiceImpl<ProjectPatentLinkMapper, ProjectPatentLink> {

    private final ProjectFolderPatentLinkService projectFolderPatentLinkService;
    private final CacheUtils cacheUtils;
    private final PatentService patentService;

    public List<ProjectPatentLink> getProjectPatentsByProjectId(Integer projectId) {
        LambdaQueryWrapper<ProjectPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectPatentLink::getProjectId, projectId);
        return this.list(queryWrapper);
    }

    public ProjectPatentLink getProjectPatentByProIdAndPatentId(Integer projectId, Integer patentId) {
        LambdaQueryWrapper<ProjectPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectPatentLink::getProjectId, projectId);
        queryWrapper.eq(ProjectPatentLink::getPatentId, patentId);
        return this.getOne(queryWrapper);
    }

    public List<ProjectPatentLink> getProjectPatentByProIdAndPatentIds(Integer projectId, List<Integer> patentIds) {
        if (patentIds == null || patentIds.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ProjectPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectPatentLink::getProjectId, projectId);
        queryWrapper.in(ProjectPatentLink::getPatentId, patentIds);
        return this.list(queryWrapper);
    }

    public void updateProjectPatent(Integer projectId, Integer patentId) {
        ProjectPatentLink temp = this.getProjectPatentByProIdAndPatentId(projectId, patentId);
        if (temp == null) {
            temp = new ProjectPatentLink();
            temp.setPatentId(patentId);
            temp.setProjectId(projectId);
            temp.insert();
        }
    }

    public List<ProjectPatentLink> getProjectPatentLinkByProjectAndFolder(Integer projectId, String folder) {
        List<ProjectPatentLink> linkList = this.getProjectPatentsByProjectId(projectId);
        if (StringUtils.isNotEmpty(folder)) {
            List<Integer> folders = StringUtils.changeStringToInteger(folder, ",");
            List<ProjectFolderPatentLink> folderLinks = projectFolderPatentLinkService.getProjectFolderLinkByProjectIdAndFolder(projectId, folders);
            linkList = linkList.stream().filter(item -> folderLinks.stream().map(ProjectFolderPatentLink::getPatentId).collect(Collectors.toList()).contains(item.getPatentId())).collect(Collectors.toList());
        }
        return linkList;
    }

    public Map<String, Object> getPatentReadTotal(PatentReadVO params) {
        List<ProjectPatentLink> linkList = new ArrayList<>();
        //当文件id不为null时
        if (StringUtils.isNotEmpty(params.getFolder())) {
            //从文件夹专利关联表里获得数据
            linkList = projectFolderPatentLinkService.getProjectFolderLinkByProjectIdAndFolder(params.getProjectId(), Integer.parseInt(params.getFolder())).stream().map(item -> {
                ProjectPatentLink projectPatentLink = new ProjectPatentLink();
                projectPatentLink.setLook(item.getLook());
                projectPatentLink.setProjectId(item.getProjectId());
                projectPatentLink.setPatentId(item.getPatentId());
                projectPatentLink.setId(item.getId());
                return projectPatentLink;
            }).collect(Collectors.toList());
        } else {
            //从专题库专利关联表里获得数据
            linkList = this.getProjectPatentsByProjectId(params.getProjectId());
        }
        //根据获得的关联信息装载所有，已读，未读数据
        Map<String, Object> result = new ConcurrentHashMap<>();
        result.put("all", linkList.size());
        result.put("read", linkList.stream().filter(item -> item.getLook().equals(1)).count());
        result.put("unread", linkList.stream().filter(item -> item.getLook().equals(0)).count());
        return result;
    }

    public Boolean updatePatentReadStatus(PatentReadVO params) {
        //当文件夹id不为null时更新文件夹专利关联表里的阅读状态
        if (StringUtils.isNotEmpty(params.getFolder())) {
            List<ProjectFolderPatentLink> projectFolderPatentLinkList = projectFolderPatentLinkService.getProjectFolderLinkByProjectIdAndFolderAndPatentIds(params.getProjectId(), Integer.parseInt(params.getFolder()), params.getPatentIds());
            projectFolderPatentLinkList.forEach(item -> item.setLook(params.getStatus()));
            return projectFolderPatentLinkService.saveOrUpdateBatch(projectFolderPatentLinkList);
        } //当文件夹id为null时更新专题库专利关联表里的阅读状态
        else {
            List<ProjectPatentLink> projectPatentLinkList = this.getProjectPatentByProIdAndPatentIds(params.getProjectId(), params.getPatentIds());
            projectPatentLinkList.forEach(item -> item.setLook(params.getStatus()));
            return this.saveOrUpdateBatch(projectPatentLinkList);
        }
    }

    public void deleteByProjectId(Integer projectId) {
        this.remove(Wrappers.<ProjectPatentLink>lambdaQuery().eq(ProjectPatentLink::getProjectId, projectId));
    }

    @Transactional
    public void deleteByProjectIdAndPatentIds(Integer projectId, List<Integer> patentIds) {
        this.remove(Wrappers.<ProjectPatentLink>lambdaQuery().eq(ProjectPatentLink::getProjectId, projectId).in(ProjectPatentLink::getPatentId, patentIds));
        projectFolderPatentLinkService.deleteByProjectIdAndPatentIds(projectId, patentIds);
    }

    public void importProjectPatentLink(Integer projectId, String patentIdPatentNoJson) {
        List<Patent> importPatentList = JsonUtils.jsonToList(patentIdPatentNoJson, Patent.class);
        List<String> importPatentNos = importPatentList.stream().map(Patent::getPatentNo).collect(Collectors.toList());
        List<Patent> localPatentList = patentService.getPatentListByPatentNo(importPatentNos);
        List<ProjectPatentLink> localProjectPatentLinkList = this.getProjectPatentByProIdAndPatentIds(projectId, localPatentList.stream().map(Patent::getId).collect(Collectors.toList()));
        for (String patentNo : importPatentNos) {
            Patent localPatent = localPatentList.stream().filter(item -> item.getPatentNo().equals(patentNo)).findFirst().orElse(null);
            if (localPatent == null) {
                continue;
            }
            ProjectPatentLink localProjectPatentLink = localProjectPatentLinkList.stream().filter(item -> item.getPatentId().equals(localPatent.getId())).findFirst().orElse(null);
            if (localProjectPatentLink == null) {
                localProjectPatentLink = new ProjectPatentLink();
                localProjectPatentLink.setProjectId(projectId);
                localProjectPatentLink.setPatentId(localPatent.getId());
                localProjectPatentLink.setLook(0);
                localProjectPatentLink.insert();
            }
        }
    }
}
