package cn.cslg.pas.service;

import cn.cslg.pas.common.model.PersonnelVO;
import cn.cslg.pas.common.model.dto.PatentDTO;
import cn.cslg.pas.common.model.vo.ProjectFieldVO;
import cn.cslg.pas.common.model.vo.UploadSettingVO;
import cn.cslg.pas.common.utils.*;
import cn.cslg.pas.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.pas.domain.*;
import cn.cslg.pas.mapper.ProjectFieldMapper;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.tree.Tree;
import com.alibaba.fastjson.JSONObject;
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 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.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 专利信息自定义字段表 服务类
 * </p>
 *
 * @author 王岩
 * @since 2021-12-16
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class ProjectFieldService extends ServiceImpl<ProjectFieldMapper, ProjectField> {
    private final ProjectFieldOptionService projectFieldOptionService;
    private final ProjectFieldTreeService projectFieldTreeService;
    private final ProjectFolderService projectFolderService;
    private final ProjectFieldTextService projectFieldTextService;
    private final ProjectFieldPatentLinkService projectFieldPatentLinkService;
    private final PatentService patentService;
    private final FileUtils fileUtils;
    private final LoginUtils loginUtils;
    private final OutInterfaceService outInterfaceService;
    private final CacheUtils cacheUtils;

    public List<PatentDTO.Field> getPatentFieldByPatentIdAndProjectId(Integer projectId, Integer patentId) {
        List<PatentDTO.Field> dataList = new ArrayList<>();
        List<ProjectFieldPatentLink> linkList = projectFieldPatentLinkService.getProjectPatentLinkByPatentAndProId(patentId, projectId);
        List<Integer> fieldIds = linkList.stream().map(ProjectFieldPatentLink::getFieldId).distinct().collect(Collectors.toList());
        List<Integer> optionIds = linkList.stream().map(ProjectFieldPatentLink::getOptionId).distinct().collect(Collectors.toList());
        List<ProjectField> fieldList = this.getFieldListByIds(fieldIds);
        List<ProjectFieldText> textList = projectFieldTextService.getProjectFieldTextByFieldIds(fieldIds);
        List<ProjectFieldOption> optionList = projectFieldOptionService.getFieldOptionList(fieldIds);
        List<ProjectFieldTree> treeList = projectFieldTreeService.getProjectFieldTreeOptionByFieldIds(fieldIds);
        fieldList.forEach(field -> {
            PatentDTO.Field data = new PatentDTO.Field();
            data.setId(field.getId());
            data.setName(field.getName());
            data.setType(field.getType());
            switch (field.getType()) {
                case 0:
                case 1:
                case 2:
                    data.setSelected(textList.stream().filter(item -> item.getFieldId().equals(field.getId()) && optionIds.contains(item.getId())).map(ProjectFieldText::getText).distinct().collect(Collectors.toList()));
                    break;
                case 3:
                case 4:
                case 5:
                    data.setSelected(optionList.stream().filter(item -> item.getFieldId().equals(field.getId()) && optionIds.contains(item.getId())).map(ProjectFieldOption::getName).distinct().collect(Collectors.toList()));
                    break;
                case 6:
                    List<ProjectFieldTree> trees = treeList.stream().filter(item -> item.getFieldId().equals(field.getId())).collect(Collectors.toList());
                    List<ProjectFieldTree> optionTree = trees.stream().filter(item -> optionIds.contains(item.getId())).collect(Collectors.toList());
                    List<String> selected = new ArrayList<>();
                    optionTree.forEach(item -> selected.add(PatentUtils.getTreeNodeFullName(trees, item.getPath())));
                    data.setSelected(selected);
                    break;
            }
            dataList.add(data);
        });
        return dataList;
    }

    public Map<Integer, List<PatentDTO.Field>> getPatentFieldByPatentIdAndProjectId2(Integer projectId, List<Integer> patentIds) {
        Map<Integer, List<PatentDTO.Field>> map = new HashMap<>();
        List<ProjectFieldPatentLink> linkList = new ArrayList<>();
        //根据专利号和专题库id获得所有自定义字段关联数据
        if (patentIds.size() > 0) {
            LambdaQueryWrapper<ProjectFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(ProjectFieldPatentLink::getPatentId, patentIds);
            queryWrapper.eq(ProjectFieldPatentLink::getProjectId, projectId);
            linkList = projectFieldPatentLinkService.list(queryWrapper);
        }
        List<Integer> fieldIds = linkList.stream().map(ProjectFieldPatentLink::getFieldId).distinct().collect(Collectors.toList());
        List<ProjectField> fieldList = this.getFieldListByIds(fieldIds);
        List<ProjectFieldText> textList = projectFieldTextService.getProjectFieldTextByFieldIds(fieldIds);
        List<ProjectFieldOption> optionList = projectFieldOptionService.getFieldOptionList(fieldIds);
        List<ProjectFieldTree> treeList = projectFieldTreeService.getProjectFieldTreeOptionByFieldIds(fieldIds);
        //遍历专利
        for (Integer patentId : patentIds) {
            List<PatentDTO.Field> dataList = new ArrayList<>();
            //获得当前专利的关联信息
            List<ProjectFieldPatentLink> temLinkList = linkList.stream().filter(item -> item.getPatentId().equals(patentId)).collect(Collectors.toList());
            //过滤出当前专利的自定义栏位
            List<Integer> temFieldIds = linkList.stream().filter(item -> item.getPatentId().equals(patentId)).map(ProjectFieldPatentLink::getFieldId).distinct().collect(Collectors.toList());
            List<ProjectField> temFieldList = fieldList.stream().filter(item -> temFieldIds.contains(item.getId())).collect(Collectors.toList());
            temFieldList.forEach(field -> {
                List<Integer> valueIds = temLinkList.stream().filter(item -> item.getFieldId().equals(field.getId())).map(ProjectFieldPatentLink::getOptionId).collect(Collectors.toList());
                PatentDTO.Field data = new PatentDTO.Field();
                data.setId(field.getId());
                data.setName(field.getName());
                data.setType(field.getType());
                switch (field.getType()) {
                    case 0:
                    case 1:
                    case 2:
                        data.setSelected(textList.stream().filter(item -> item.getFieldId().equals(field.getId()) && valueIds.contains(item.getId())).map(ProjectFieldText::getText).distinct().collect(Collectors.toList()));
                        break;
                    case 3:
                    case 4:
                    case 5:
                        data.setSelected(optionList.stream().filter(item -> item.getFieldId().equals(field.getId()) && valueIds.contains(item.getId())).map(ProjectFieldOption::getName).distinct().collect(Collectors.toList()));
                        break;
                    case 6:
                        List<ProjectFieldTree> trees = treeList.stream().filter(item -> item.getFieldId().equals(field.getId())).collect(Collectors.toList());
                        List<ProjectFieldTree> optionTree = trees.stream().filter(item -> valueIds.contains(item.getId())).collect(Collectors.toList());
                        List<String> selected = new ArrayList<>();
                        optionTree.forEach(item -> selected.add(PatentUtils.getTreeNodeFullName(trees, item.getPath())));
                        data.setSelected(selected);
                        break;
                }
                dataList.add(data);
            });
            map.put(patentId, dataList);
        }
        return map;
    }

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

    public List<ProjectField> getSystemField(Integer projectId) {
        List<ProjectField> fieldList = new ArrayList<>();
        List<ProjectField> systemField = this.getProjectSystemField();
        List<ProjectField> customField = this.getProjectCustomField(projectId);
        List<ProjectFieldExpand> expandList = this.getProjectFieldExpand();
        List<ProjectFieldSystemExpand> systemExpands = this.getProjectFieldSystemExpand();
        for (ProjectField item : systemField) {
            if (!item.getType().equals(96)) {
                List<Integer> eid = systemExpands.stream().filter(e -> e.getFieldId().equals(item.getId())).map(ProjectFieldSystemExpand::getExpandId).collect(Collectors.toList());
                if (eid.size() != 0) {
                    item.setExpand(expandList.stream().filter(expand -> eid.contains(expand.getId())).collect(Collectors.toList()));
                }
                fieldList.add(item);
            } else {
                customField.add(item);
            }
        }
        for (ProjectField item : customField) {
            ProjectField field = new ProjectField();
            field.setName(item.getName());
            field.setId(item.getId());
            field.setType(item.getType());
            field.setPtype(this.getCustomFieldPtype(item, field, expandList));
            fieldList.add(field);
        }
        return fieldList;
    }

    public Integer getCustomFieldPtype(ProjectField item, ProjectField field, List<ProjectFieldExpand> expandList) {
        switch (item.getType()) {
            case 0:
                return 3;
            case 1:
                field.setExpand(expandList.stream().filter(e -> e.getPtype().equals(2) || e.getPtype().equals(4)).collect(Collectors.toList()));
                return 0;
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
                return 1;
        }
        return item.getPtype();
    }

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

    public List<ProjectField> getTreeOptionList(Integer projectId) {
        LambdaQueryWrapper<ProjectField> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectField::getProjectId, projectId);
        queryWrapper.eq(ProjectField::getType, 6);
        List<ProjectField> fieldList = this.list(queryWrapper);
        for (ProjectField field : fieldList) {
            List<Tree<Integer>> treeList = projectFieldTreeService.getProjectFieldTreeNodeByFieldId(field.getId());
            field.setOption(JsonUtils.jsonToList(JsonUtils.objectToJson(treeList), ProjectFieldOption.class));
        }
        return fieldList;
    }

    public List<ProjectField> getProjectCustomField(Integer projectId) {
        List<ProjectField> fieldList = this.getProjectFieldByProjectId(projectId);
        List<ProjectFieldOption> optionList = projectFieldOptionService.getFieldOptionList(fieldList.stream().map(ProjectField::getId).collect(Collectors.toList()));
        for (ProjectField item : fieldList) {
            if (item.getType() != 6) {
                item.setOption(optionList.stream().filter(option -> option.getFieldId().equals(item.getId())).collect(Collectors.toList()));
            } else {
                item.setOption(JsonUtils.jsonToList(JsonUtils.objectToJson(projectFieldTreeService.getProjectFieldTreeNodeByFieldId(item.getId())), ProjectFieldOption.class));
            }
        }
        return fieldList;
    }

    public Map<String, Object> getCustomField(Integer projectId) {
        //创建map用于装载：1.自定义字段（标引/非树类型字段、分类/树类型字段）  2.文件夹  3.数据来源，和返回结果
        Map<String, Object> result = new HashMap<>();

        //创建非树类型字段集合
        List<ProjectField> indexs = new ArrayList<>();
        //创建树类型字段集合
        List<Object> classifys = new ArrayList<>();

        //1、自定义字段（标引和分类）：根据专题库projectId查询自定义字段表“os_patent_field”列表
        List<ProjectField> fieldList = this.getProjectFieldByProjectId(projectId);
        //根据自定义字段ids（自定义字段列表fieldList过滤出ids集合）查询自定义字段多选关联表“os_patent_field_multiple”列表
        List<ProjectFieldOption> optionList = projectFieldOptionService.getFieldOptionList(fieldList.stream().map(ProjectField::getId).collect(Collectors.toList()));
        //遍历自定义字段列表fieldList，给每个自定义字段装载选项 ↓
        fieldList.forEach(item -> {
            //标引（非树类型字段） -> 装载当前自定义字段id对应的选项（遍历自定义字段多选关联表列表optionList，根据多选的自定义字段id与当前遍历的自定义字段id相同过滤出选项）
            if (item.getType() != 6) {
                item.setOption(optionList.stream().filter(option -> option.getFieldId().equals(item.getId())).collect(Collectors.toList()));
                indexs.add(item);
                //分类（树类型字段） -> 装载当前自定义字段id对应的树（使用装载树方法）
            } else {
                item.setOption(JsonUtils.jsonToList(JsonUtils.objectToJson(projectFieldTreeService.getProjectFieldTreeNodeByFieldId(item.getId())), ProjectFieldOption.class));
                classifys.add(item);
            }
        });

        //2、文件夹：根据专题库projectId查询文件夹主表“os_portfolio”列表
        List<ProjectFolder> folderList = projectFolderService.getProjectFolderOptionByProjectId(projectId);
        result.put("index", indexs);
        result.put("classify", classifys);
        result.put("folder", projectFolderService.getProjectFolderTreeNode(projectId, folderList));

        //3、数据来源（analysisJsonFile()方法 -> 拿到uploadSetting.json文件并按行读取文件字符流，返回整个文件字符串）
        String getSettingJson = fileUtils.analysisJsonFile();
        //将文件字符串转换为数据来源对象UploadSettingVO集合
        List<UploadSettingVO> settingJsonList = JsonUtils.jsonToList(getSettingJson, UploadSettingVO.class);

        //手动创建数据来源对象集合dataTypesLst，装载数据
        List<ProjectField.dataType> dataTypesLst = new ArrayList<>();
        Objects.requireNonNull(settingJsonList).forEach(item -> {
            ProjectField.dataType dataType = new ProjectField.dataType();
            dataType.setId(item.getSourceId());
            dataType.setName(item.getName());
            dataTypesLst.add(dataType);
        });
        result.put("dataType", dataTypesLst);

        //返回结果（包含1.自定义字段（标引/非树类型字段、分类/树类型字段）  2.文件夹  3.数据来源）
        return result;
    }

    public ProjectField getProjectFieldById(Integer id) {
        ProjectField projectField = this.getById(id);
        switch (projectField.getType()) {
            case 0:
            case 1:
            case 2:
                break;
            case 3:
            case 4:
            case 5:
                projectField.setOption(projectFieldOptionService.getListByFieldId(projectField.getId()));
                break;
            case 6:
                projectField.setOption(JsonUtils.jsonToList(JsonUtils.objectToJson(projectFieldTreeService.getProjectFieldTreeNodeByFieldId(projectField.getId())), ProjectFieldOption.class));
                break;
        }
        return projectField;
    }

    public ProjectField getProjectFieldByNameAndType(String name, Integer type, Integer projectId, Integer userId) {
        ProjectField projectField = this.getByProjectIdAndNameAndType(name, type, projectId);
        if (projectField == null) {
            projectField = new ProjectField();
            projectField.setType(type);
            projectField.setName(name);
            projectField.setCreateBy(userId);
            projectField.setCreateTime(DateUtils.getDateTime());
            projectField.setPtype(projectField.getType() == 6 ? 2 : 1);
            projectField.setStatus(1);
            projectField.setProjectId(projectId);
            projectField.insert();
        }
        switch (projectField.getType()) {
            case 0:
            case 1:
            case 2:
                projectField.setOption(projectFieldTextService.getProjectFieldTextByFieldId(projectField.getId()).stream().map(item -> {
                    ProjectFieldOption projectFieldOption = new ProjectFieldOption();
                    projectFieldOption.setId(item.getId());
                    projectFieldOption.setName(item.getText());
                    projectFieldOption.setFieldId(item.getFieldId());
                    return projectFieldOption;
                }).collect(Collectors.toList()));
                break;
            case 3:
            case 4:
            case 5:
                projectField.setOption(projectFieldOptionService.getListByFieldId(projectField.getId()));
                break;
            case 6:
                projectField.setOption(JsonUtils.jsonToList(JsonUtils.objectToJson(projectFieldTreeService.getProjectFieldTreeNodeByFieldId(projectField.getId())), ProjectFieldOption.class));
                break;
        }
        return projectField;
    }

    public IPage<ProjectField> getPageList(ProjectFieldVO params) throws IOException {
        PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
        //分页查询列表
        params.setTenantId(personnelVO.getTenantId());
        IPage<ProjectField> pageList = baseMapper.getPageList(new Page<>(params.getCurrent(), params.getSize()), params);
        //从分页信息中获取列表
        List<ProjectField> projectFields = pageList.getRecords();
        ArrayList<Integer> personnelIds = new ArrayList<>();
        for (ProjectField projectField : projectFields) {
            personnelIds.add(projectField.getCreateBy());
        }
        //调用权限系统根据人员ids获得人员列表的接口
        String res = outInterfaceService.getPersonnelByIdsFromPCS(personnelIds);
        JSONObject jsonObject = JSONObject.parseObject(res);
        List<Personnel> personnels = JSONObject.parseArray(jsonObject.getString("data"), Personnel.class);
        //遍历人员列表和列表，给列表装载人员名称
        for (ProjectField projectField : projectFields) {
            for (Personnel personnel : personnels) {
                if (personnel.getId().equals(projectField.getCreateBy())) {
                    projectField.setCreateName(personnel.getPersonnelName());
                }
            }
        }
        pageList.setRecords(projectFields);

        return pageList;
    }

    public ProjectField getByProjectIdAndNameAndType(String name, Integer type, Integer projectId) {
        LambdaQueryWrapper<ProjectField> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectField::getName, name);
        queryWrapper.eq(ProjectField::getType, type);
        queryWrapper.eq(ProjectField::getProjectId, projectId);
        return this.getOne(queryWrapper);
    }

    public ProjectField getProjectFieldByName(String name, Integer projectId) {
        LambdaQueryWrapper<ProjectField> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectField::getName, name);
        queryWrapper.eq(ProjectField::getProjectId, projectId);
        return this.getOne(queryWrapper);
    }

    public String add(ProjectField projectField) {
        ProjectField temp = this.getProjectFieldByName(projectField.getName(), projectField.getProjectId());
        if (temp != null) {
            return Response.error("字段名称已存在");
        }
        projectField.setPtype(projectField.getType() == 6 ? 2 : 1);
        projectField.setCreateBy(loginUtils.getId());
        projectField.setCreateTime(DateUtils.getDateTime());
        projectField.setProjectId(projectField.getProjectId());
        projectField.insert();
        return Response.success(projectField.getId());
    }

    public String edit(ProjectField projectField) {
        ProjectField temp = this.getProjectFieldByName(projectField.getName(), projectField.getProjectId());
        if (temp != null && !temp.getId().equals(projectField.getId())) {
            return Response.error("字段名称已存在");
        }
        projectField.setPtype(projectField.getType() == 6 ? 2 : 1);
        projectField.updateById();
        return Response.success(true);
    }

    @Transactional
    public String delete(Integer id) {
        this.removeById(id);
        projectFieldTextService.deleteByFieldId(id);
        projectFieldOptionService.deleteByFieldId(id);
        projectFieldTreeService.deleteByFieldId(id);
        projectFieldPatentLinkService.deleteByFieldId(id);
        return Response.success(true);
    }

    @Transactional
    public void deleteByProjectId(Integer projectId) {
        List<Integer> ids = this.getProjectFieldByProjectId(projectId).stream().map(ProjectField::getId).collect(Collectors.toList());
        for (Integer id : ids) {
            this.delete(id);
        }
    }

    public void importProjectField(Integer projectId, Integer userId, String patentIdPatentNoJson, String projectFieldJson, String projectFieldTextJson, String projectFieldOptionJson, String projectFieldTreeJson, String projectFieldPatentLink) {
        List<Patent> importPatentList = JsonUtils.jsonToList(patentIdPatentNoJson, Patent.class);
        List<Patent> localPatentList = patentService.getPatentListByPatentNo(importPatentList.stream().map(Patent::getPatentNo).collect(Collectors.toList()));
        List<Integer> localPatentIds = localPatentList.stream().map(Patent::getId).collect(Collectors.toList());
        List<ProjectField> importProjectFieldList = JsonUtils.jsonToList(projectFieldJson, ProjectField.class);
        List<ProjectField> localProjectFieldList = this.getProjectFieldByProjectId(projectId);
        List<ProjectFieldText> projectFieldTextList = JsonUtils.jsonToList(projectFieldTextJson, ProjectFieldText.class);
        List<ProjectFieldOption> projectFieldOptionList = JsonUtils.jsonToList(projectFieldOptionJson, ProjectFieldOption.class);
        List<ProjectFieldTree> projectFieldTreeList = JsonUtils.jsonToList(projectFieldTreeJson, ProjectFieldTree.class);
        List<ProjectFieldPatentLink> projectFieldPatentLinkList = JsonUtils.jsonToList(projectFieldPatentLink, ProjectFieldPatentLink.class);
        for (ProjectField projectField : importProjectFieldList) {
            ProjectField localProjectField = localProjectFieldList.stream().filter(item -> item.getName().equals(projectField.getName())).findFirst().orElse(null);
            if (localProjectField != null && !localProjectField.getType().equals(projectField.getType())) {
                continue;
            }
            if (localProjectField == null) {
                localProjectField = new ProjectField();
                localProjectField.setCreateBy(userId);
                localProjectField.setCreateTime(DateUtils.getDateTime());
                localProjectField.setProjectId(projectId);
                localProjectField.setName(projectField.getName());
                localProjectField.setType(projectField.getType());
                localProjectField.setPtype(projectField.getPtype());
                localProjectField.insert();
            }
            projectFieldPatentLinkService.deleteByPatentIdsAndProjectIdAndFieldId(localPatentIds, projectId, localProjectField.getId());
            List<ProjectFieldPatentLink> importProjectPatentLinkList = projectFieldPatentLinkList.stream().filter(item -> item.getFieldId().equals(projectField.getId())).collect(Collectors.toList());
            switch (projectField.getType()) {
                case 0:
                case 1:
                case 2:
                    List<ProjectFieldText> importProjectFieldTextList = projectFieldTextList.stream().filter(item -> item.getFieldId().equals(projectField.getId())).collect(Collectors.toList());
                    List<ProjectFieldText> localProjectFieldTextList = projectFieldTextService.getProjectFieldTextByFieldId(localProjectField.getId());
                    for (ProjectFieldText projectFieldText : importProjectFieldTextList) {
                        ProjectFieldText localProjectFieldText = localProjectFieldTextList.stream().filter(item -> item.getText().equals(projectFieldText.getText())).findFirst().orElse(null);
                        if (localProjectFieldText == null) {
                            localProjectFieldText = new ProjectFieldText();
                            localProjectFieldText.setText(projectFieldText.getText());
                            localProjectFieldText.setFieldId(localProjectField.getId());
                            localProjectFieldText.insert();
                        }
                        projectFieldPatentLinkService.importProjectFieldPatentLink(importPatentList, localPatentList, importProjectPatentLinkList, projectId, userId, projectFieldText.getFieldId(), projectFieldText.getId(), localProjectFieldText.getFieldId(), localProjectFieldText.getId());
                    }
                    break;
                case 3:
                case 4:
                case 5:
                    List<ProjectFieldOption> importProjectFieldOptionList = projectFieldOptionList.stream().filter(item -> item.getFieldId().equals(projectField.getId())).collect(Collectors.toList());
                    List<ProjectFieldOption> localProjectFieldOptionList = projectFieldOptionService.getListByFieldId(localProjectField.getId());
                    for (ProjectFieldOption projectFieldOption : importProjectFieldOptionList) {
                        ProjectFieldOption localProjectFieldOption = localProjectFieldOptionList.stream().filter(item -> item.getName().equals(projectFieldOption.getName())).findFirst().orElse(null);
                        if (localProjectFieldOption == null) {
                            localProjectFieldOption = new ProjectFieldOption();
                            localProjectFieldOption.setName(projectFieldOption.getName());
                            localProjectFieldOption.setFieldId(localProjectField.getId());
                            localProjectFieldOption.insert();
                        }
                        projectFieldPatentLinkService.importProjectFieldPatentLink(importPatentList, localPatentList, importProjectPatentLinkList, projectId, userId, projectFieldOption.getFieldId(), projectFieldOption.getId(), localProjectFieldOption.getFieldId(), localProjectFieldOption.getId());
                    }
                    break;
                case 6:
                    List<ProjectFieldTree> importProjectFieldTreeList = projectFieldTreeList.stream().filter(item -> item.getFieldId().equals(projectField.getId())).sorted(Comparator.comparing(ProjectFieldTree::getLevel)).collect(Collectors.toList());
                    for (ProjectFieldTree projectFieldTree : importProjectFieldTreeList) {
                        ProjectFieldTree localProjectFieldTree = projectFieldTreeService.getProjectFieldTreeOptionByFieldIdAndNameAndLevel(localProjectField.getId(), projectFieldTree.getName(), projectFieldTree.getLevel());
                        if (localProjectFieldTree == null) {
                            localProjectFieldTree = new ProjectFieldTree();
                            localProjectFieldTree.setFieldId(localProjectField.getId());
                            if (projectFieldTree.getLevel().equals(1)) {
                                localProjectFieldTree.setParentId(0);
                            } else {
                                ProjectFieldTree importProjectFieldTreeParent = importProjectFieldTreeList.stream().filter(item -> item.getId().equals(projectFieldTree.getParentId())).findFirst().orElse(new ProjectFieldTree());
                                ProjectFieldTree localProjectFieldTreeParent = projectFieldTreeService.getProjectFieldTreeOptionByFieldIdAndNameAndLevel(localProjectField.getId(), importProjectFieldTreeParent.getName(), importProjectFieldTreeParent.getLevel());
                                localProjectFieldTree.setParentId(localProjectFieldTreeParent.getId());
                            }
                            localProjectFieldTree.setOrder(-1);
                            localProjectFieldTree.setName(projectFieldTree.getName());
                            localProjectFieldTree.insert();
                            projectFieldTreeService.edit(localProjectFieldTree);
                        }
                        projectFieldPatentLinkService.importProjectFieldPatentLink(importPatentList, localPatentList, importProjectPatentLinkList, projectId, userId, projectFieldTree.getFieldId(), projectFieldTree.getId(), localProjectFieldTree.getFieldId(), localProjectFieldTree.getId());
                    }
                    break;
            }
        }
    }

    @Transactional
    public void importProjectField(List<Integer> ids, Integer projectId) {
        for (Integer id : ids) {
            ProjectField temp = this.getProjectFieldById(id);
            temp.setProjectId(projectId);
            temp.setId(null);
            switch (temp.getType()) {
                case 0:
                case 1:
                case 2:
                    break;
                case 3:
                case 4:
                case 5:
                    temp.getOption().forEach(item -> item.setId(null));
                    break;
                case 6:
                    this.setImportTreeNodeIdToNull(temp.getOption());
                    break;
            }
            this.add(temp);
        }
    }

    @Transactional
    public void copyProjectField(Integer id, List<Integer> projectIds) {
        ProjectField temp = this.getProjectFieldById(id);
        for (Integer projectId : projectIds) {
            temp.setProjectId(projectId);
            temp.setId(null);
            switch (temp.getType()) {
                case 0:
                case 1:
                case 2:
                    break;
                case 3:
                case 4:
                case 5:
                    temp.getOption().forEach(item -> item.setId(null));
                    break;
                case 6:
                    this.setImportTreeNodeIdToNull(temp.getOption());
                    break;
            }
            this.add(temp);
        }
    }

    private void setImportTreeNodeIdToNull(List<ProjectFieldOption> treeList) {
        treeList.forEach(tree -> {
            tree.setId(null);
            tree.setPath(null);
            tree.setParentId(null);
            tree.setLevel(null);
            tree.setOrder(null);
            if (tree.getChildren() != null && tree.getChildren().size() != 0) {
                this.setImportTreeNodeIdToNull(tree.getChildren());
            }
        });
    }

    public List<ProjectField> getProjectSystemField() {
        List<ProjectField> projectFieldList = new ArrayList<>();
        projectFieldList.add(this.buildProjectFieldEntity(13, "IPC分类号", 90, 0));
        projectFieldList.add(this.buildProjectFieldEntity(14, "IPC主分类号", 90, 0));
        projectFieldList.add(this.buildProjectFieldEntity(15, "CPC分类号", 90, 0));
        projectFieldList.add(this.buildProjectFieldEntity(16, "LOC分类号", 90, 0));
        projectFieldList.add(this.buildProjectFieldEntity(17, "UPC分类号", 90, 0));
        projectFieldList.add(this.buildProjectFieldEntity(18, "申请人", 91, 0));
        projectFieldList.add(this.buildProjectFieldEntity(19, "权利人", 91, 0));
        projectFieldList.add(this.buildProjectFieldEntity(20, "发明人", 91, 1));
        projectFieldList.add(this.buildProjectFieldEntity(21, "代理机构", 91, 1));
        projectFieldList.add(this.buildProjectFieldEntity(22, "代理人", 91, 1));
        projectFieldList.add(this.buildProjectFieldEntity(23, "第一申请人", 91, 0));
        projectFieldList.add(this.buildProjectFieldEntity(24, "第一权利人", 91, 0));
        projectFieldList.add(this.buildProjectFieldEntity(25, "申请日", 92, 0));
        projectFieldList.add(this.buildProjectFieldEntity(26, "公开日", 92, 0));
        projectFieldList.add(this.buildProjectFieldEntity(27, "授权日", 92, 0));
        projectFieldList.add(this.buildProjectFieldEntity(28, "受理局", 93, 1));
        projectFieldList.add(this.buildProjectFieldEntity(29, "申请人", 93, 0));
        projectFieldList.add(this.buildProjectFieldEntity(30, "权利人", 93, 0));
        projectFieldList.add(this.buildProjectFieldEntity(31, "优先权国家", 93, 1));
        projectFieldList.add(this.buildProjectFieldEntity(32, "引用专利数量", 94, 3));
        projectFieldList.add(this.buildProjectFieldEntity(33, "被引用专利数量", 94, 3));
        projectFieldList.add(this.buildProjectFieldEntity(34, "inpadoc同族数量", 94, 3));
        projectFieldList.add(this.buildProjectFieldEntity(35, "简单同族数量", 94, 3));
        projectFieldList.add(this.buildProjectFieldEntity(55, "扩展同族数量", 94, 3));
        projectFieldList.add(this.buildProjectFieldEntity(36, "法律状态", 95, 1));
        projectFieldList.add(this.buildProjectFieldEntity(37, "专利类型", 95, 1));
        projectFieldList.add(this.buildProjectFieldEntity(38, "权利要求数量", 95, 3));
        projectFieldList.add(this.buildProjectFieldEntity(39, "独立权利要求数量", 95, 3));
        projectFieldList.add(this.buildProjectFieldEntity(54, "标签", 96, 1));
        return projectFieldList;
    }

    public List<ProjectFieldExpand> getProjectFieldExpand() {
        List<ProjectFieldExpand> projectFieldExpandList = new ArrayList<>();
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(1, "部", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(2, "大类", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(3, "小类", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(4, "大组", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(5, "小组", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(6, "当前", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(7, "标准", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(8, "合并后", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(9, "月", 2));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(10, "季", 2));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(11, "半年", 2));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(12, "年", 2));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(13, "2年", 2));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(14, "3年", 2));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(15, "5年", 2));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(16, "自定义", 4));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(17, "国家", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(18, "省", 1));
        projectFieldExpandList.add(this.buildProjectFieldExpandEntity(19, "市", 1));
        return projectFieldExpandList;
    }

    public List<ProjectFieldSystemExpand> getProjectFieldSystemExpand() {
        List<ProjectFieldSystemExpand> projectFieldSystemExpandList = new ArrayList<>();
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(13, 1));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(13, 2));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(13, 3));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(13, 4));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(13, 5));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(14, 1));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(14, 2));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(14, 3));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(14, 4));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(14, 5));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(15, 1));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(15, 2));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(15, 3));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(15, 4));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(15, 5));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(16, 2));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(16, 3));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(17, 2));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(17, 3));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(18, 6));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(18, 7));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(18, 8));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(19, 6));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(19, 7));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(19, 8));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(23, 6));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(23, 7));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(23, 8));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(24, 6));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(24, 7));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(24, 8));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 9));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 10));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 11));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 12));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 13));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 14));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 15));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(25, 16));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 9));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 10));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 11));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 12));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 13));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 14));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 15));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(26, 16));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 9));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 10));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 11));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 12));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 13));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 14));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 15));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(27, 16));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(29, 17));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(29, 18));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(29, 19));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(30, 17));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(30, 18));
        projectFieldSystemExpandList.add(this.buildProjectFieldSystemExpandEntity(30, 19));
        return projectFieldSystemExpandList;
    }

    public ProjectField buildProjectFieldEntity(Integer id, String name, Integer type, Integer ptype) {
        ProjectField projectField = new ProjectField();
        projectField.setId(id);
        projectField.setName(name);
        projectField.setType(type);
        projectField.setPtype(ptype);
        return projectField;
    }

    public ProjectFieldExpand buildProjectFieldExpandEntity(Integer id, String name, Integer ptype) {
        ProjectFieldExpand projectFieldExpand = new ProjectFieldExpand();
        projectFieldExpand.setId(id);
        projectFieldExpand.setName(name);
        projectFieldExpand.setPtype(ptype);
        return projectFieldExpand;
    }

    public ProjectFieldSystemExpand buildProjectFieldSystemExpandEntity(Integer fieldId, Integer expandId) {
        ProjectFieldSystemExpand projectFieldSystemExpand = new ProjectFieldSystemExpand();
        projectFieldSystemExpand.setFieldId(fieldId);
        projectFieldSystemExpand.setExpandId(expandId);
        return projectFieldSystemExpand;
    }
}
