package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.dao.ComProjectTaskDAO;
import com.yiboshi.science.entity.*;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.*;
import com.yiboshi.science.param.query.ComProjectTaskQueryVO;
import com.yiboshi.science.service.*;
import com.yiboshi.science.utils.SystemSetKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 任务书表 Service 实现类
 *
 * @author lkl
 * @version 2021-08-26
 */
@Service
public class ComProjectTaskServiceImpl extends BaseServiceImpl<ComProjectTaskDAO, ComProjectTaskQueryVO, ComProjectTaskDTO, ComProjectTask> implements ComProjectTaskService {
    @Autowired
    private ComProjectTaskDAO ComProjectTaskDAO;
    @Autowired
    private ComProjectMembersService comProjectMembersService;
    @Autowired
    private ComProjectBudgetService comProjectBudgetService;
    @Autowired
    private ComTaskTargetService ComTaskTargetService;
    @Autowired
    private ComProjectStageGoalService ComProjectStageGoalService;
    @Autowired
    private ComProjectService ComProjectService;
    @Autowired
    private ComPersonService comPersonService;
    @Autowired
    private ComUnitService comUnitService;
    @Autowired
    private ComProjectCooperativeUnitsService ComProjectCooperativeUnitsService;
    @Autowired
    private ComProjectAuditService comProjectAuditService;
    @Autowired
    private ComProjectAuditNoteService comProjectAuditNoteService;
    @Autowired
    private ComProjectCheckService comProjectCheckService;
    @Autowired
    private ComDownloadService comDownloadService;
    @Autowired
    private ComFileService comFileService;

    @Override
    protected void setCriteriaForQuery(ComProjectTaskQueryVO vo, QueryWrapper<ComProjectTaskQueryVO> criteria) {
        if (Objects.nonNull(vo.getProjId())) {
            criteria.eq("proj_id", vo.getProjId());
        }
        if (Objects.nonNull(vo.getReportYear())) {
            criteria.eq("c.report_year", vo.getReportYear());
        }
        if (Objects.nonNull(vo.getTestState())) {
            switch (vo.getTestState()) {
                case 1://未上报任务书
                    criteria.and(qw -> qw.in("test_state", CommonEnum.taskState.draft.getCode(),
                            CommonEnum.taskState.waitSubmit.getCode()).or().isNull("test_state"));
                    //criteria.or(qw->qw.eq("test_state", "-10").isNull("test_state"));
                    break;
                case 2://返回修改任务书
                    criteria.eq("test_state", CommonEnum.taskState.returnModify.getCode());
                    break;
                case 3://已上报任务书
                    criteria.in("test_state",
                            CommonEnum.taskState.review.getCode(),
                            CommonEnum.taskState.failed.getCode(),
                            CommonEnum.taskState.pass.getCode());
                    break;
                case 4://所有任务书
                    break;
                case 5://任务书
                    criteria.and(qw -> qw.in("test_state", CommonEnum.taskState.review.getCode()).or().isNull("test_state"));
                    break;
            }
        }
        if (Objects.nonNull(vo.getAppUnitId())) {
            criteria.eq("app_unit_id", vo.getAppUnitId());
        }
        if (Objects.nonNull(vo.getAppPersonId())) {
            criteria.eq("app_person_id", vo.getAppPersonId());
        }
        if (Objects.nonNull(vo.getTestContent())) {
            criteria.eq("test_content", vo.getTestContent());
        }
        if (Objects.nonNull(vo.getBudgetCount())) {
            criteria.eq("budget_count", vo.getBudgetCount());
        }
        if (Objects.nonNull(vo.getBudgetGovCount())) {
            criteria.eq("budget_gov_count", vo.getBudgetGovCount());
        }
        if (Objects.nonNull(vo.getStartDate())) {
            criteria.eq("start_date", vo.getStartDate());
        }
        if (Objects.nonNull(vo.getEndDate())) {
            criteria.eq("end_date", vo.getEndDate());
        }
        if (Objects.nonNull(vo.getProjState())) {
            criteria.eq("proj_state", vo.getProjState());
        }
        if (Objects.nonNull(vo.getProjName())) {
            criteria.like("proj_name", vo.getProjName());
        }
        if (Objects.nonNull(vo.getProjNo())) {
            criteria.like("proj_no", vo.getProjNo());
        }
        if (Objects.nonNull(vo.getProjClass())) {
            criteria.eq("proj_class", vo.getProjClass());
        }
        if (Objects.nonNull(vo.getAppUnitName())) {
            criteria.like("unit_name", vo.getAppUnitName());
        }
        if (Objects.nonNull(vo.getTreeCode())) {
            criteria.likeRight("tree_code", vo.getTreeCode());
        }
        if (Objects.nonNull(vo.getAppPersonName())) {
            criteria.like("person_name", vo.getAppPersonName());
        }
    }

    @Override
    public Pagination<ComProjectTaskDTO> getListByPage(ComProjectTaskQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectTaskQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectTaskDTO> dtoList = ComProjectTaskDAO.getListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    @Override
    public void updateState(String id, Integer state) {
        ComProjectTask ComProjectTask = new ComProjectTask();
        ComProjectTask.setId(id);
        ComProjectTask.setTestState(state);
        this.update(ComProjectTask);
    }

    public ComProjectTaskDTO getTestInfoById(String projectId) {
        ComProjectTaskDTO test = getByProjectId(projectId);
        if (null == test)
            test = new ComProjectTaskDTO();
        ComProjectDTO comProject = ComProjectService.dtoById(projectId);
        if (null == comProject)
            throw new BusinessException("项目不存在");
        test.setProjName(comProject.getProjName());
        test.setProjId(comProject.getId());
        test.setReportYear(comProject.getReportYear());
        test.setStartDate(comProject.getStartDate());
        test.setEndDate(comProject.getEndDate());
        if (null == test.getBudgetCount())
            test.setBudgetCount(comProject.getTotalFunding());
        if (null == test.getBudgetGovCount())
            test.setBudgetGovCount(comProject.getTotalFunding());
        //合作单位
        List<ComProjectCooperativeUnitsDTO> together = ComProjectCooperativeUnitsService.getListByObjectId(comProject.getId());
        test.setTogether(together);
        //申报单位
        ComUnitDTO comUnit = comUnitService.getUnitById(comProject.getAppUnitId());
        if (null != comUnit) {
            test.setAppUnitName(comUnit.getUnitName());
            test.setLinkEmail(comUnit.getLinkEmail());
            test.setLinkTel(comUnit.getLinkTel());
            test.setLinkAddress(comUnit.getUnitAddress());
            test.setPostcode(comUnit.getPostcode());
            test.setAuthority(comUnit.getUpUnitName());
        }
        //项目组成员
        if (null != test.getId()) {
            //项目组成员
            ComProjectMembersDTO comProjectMembersDTO=comProjectMembersService.getMemCountById(test.getId());
            test.setMemCount(comProjectMembersDTO.getMemCount());
            test.setMemHighCount(comProjectMembersDTO.getMemHighCount());
            test.setMemMiddleCount(comProjectMembersDTO.getMemMiddleCount());
            test.setMemLowCount(comProjectMembersDTO.getMemLowCount());
            test.setMemSsCount(comProjectMembersDTO.getMemSsCount());
            test.setMemBsCount(comProjectMembersDTO.getMemBsCount());
            test.setMemOtherCount(comProjectMembersDTO.getMemOtherCount());
            List<ComProjectMembersDTO> memList1 = comProjectMembersService.getListByObjectId(test.getId());
            if (null == memList1 || memList1.size() == 0) {
                List<ComProjectMembersDTO> memList2 = comProjectMembersService.getListByObjectId(comProject.getId());
                test.setMembers(memList2);
            } else
                test.setMembers(memList1);
            //经费表
            List<ComProjectBudgetDTO> budgetList1 = comProjectBudgetService.getListByObjectId(test.getId());
            if (null == budgetList1 || budgetList1.size() == 0) {
                List<ComProjectBudgetDTO> budgetList2 = comProjectBudgetService.getListByObjectId(comProject.getId());
//                budgetList2 = comProjectBudgetService.budgetControlInit(budgetList2);
                test.setBudget(budgetList2);
            } else {
//                budgetList1 = comProjectBudgetService.budgetControlInit(budgetList1);
                test.setBudget(budgetList1);
            }
            // 预期成果
            List<ComTaskTargetDTO> target = ComTaskTargetService.getListByObjectId(test.getId());
            target.forEach(item -> {
                if ("False".equals(item.getResult()))
                    item.setChecked(false);
                else
                    item.setChecked(true);
            });
            test.setTarget(target);
            // 主要研发内容
            List<ComProjectStageGoalDTO> content = ComProjectStageGoalService.getListByObjectId(test.getId());
            List<ComProjectStageGoalDTO> cont1 = content.stream().filter(e -> SystemSetKey.taskCont1.equals(e.getContentType())).collect(Collectors.toList());
            List<ComProjectStageGoalDTO> cont2 = content.stream().filter(e -> SystemSetKey.taskCont2.equals(e.getContentType())).collect(Collectors.toList());
            List<ComProjectStageGoalDTO> cont3 = content.stream().filter(e -> SystemSetKey.taskCont3.equals(e.getContentType())).collect(Collectors.toList());
            List<ComProjectStageGoalDTO> cont4 = content.stream().filter(e -> SystemSetKey.taskCont4.equals(e.getContentType())).collect(Collectors.toList());
            List<ComProjectStageGoalDTO> cont5 = content.stream().filter(e -> SystemSetKey.taskCont5.equals(e.getContentType())).collect(Collectors.toList());
            List<ComProjectStageGoalDTO> cont6 = content.stream().filter(e -> SystemSetKey.taskCont6.equals(e.getContentType())).collect(Collectors.toList());
            test.setCont1(cont1);
            test.setCont2(cont2);
            test.setCont3(cont3);
            test.setCont4(cont4);
            test.setCont5(cont5);
            test.setCont6(cont6);
        } else {
            //项目组成员
            List<ComProjectMembersDTO> memList2 = comProjectMembersService.getListByObjectId(comProject.getId());
            test.setMembers(memList2);
            //经费表
            List<ComProjectBudgetDTO> budgetList2 = comProjectBudgetService.getListByObjectId(comProject.getId());
            test.setBudget(budgetList2);
            test.setTarget(ComTaskTargetService.getList());
        }

        //审核记录列表
        if (null != test.getId()) {
            List<ComProjectAuditNoteDTO> auditList = comProjectAuditNoteService.getListByObjectId(test.getId());
            test.setAuditList(auditList);
        }

        return test;
    }

    @Override
    public String save(ComProjectTaskDTO dto) {
        ComProjectTaskDTO test = getByProjectId(dto.getProjId());
        List<ComProjectStageGoalDTO> contentList = new ArrayList<>();
        if (null != dto.getCont1() && dto.getCont1().size() > 0)
            resetTaskContent(contentList, dto.getCont1());
        if (null != dto.getCont2() && dto.getCont2().size() > 0)
            resetTaskContent(contentList, dto.getCont2());
        if (null != dto.getCont3() && dto.getCont3().size() > 0)
            resetTaskContent(contentList, dto.getCont3());
        if (null != dto.getCont4() && dto.getCont4().size() > 0)
            resetTaskContent(contentList, dto.getCont4());
        if (null != dto.getCont5() && dto.getCont5().size() > 0)
            resetTaskContent(contentList, dto.getCont5());
        if (null != dto.getCont6() && dto.getCont6().size() > 0)
            resetTaskContent(contentList, dto.getCont6());
        dto.setContent(contentList);
        if (null == test)
            dto.setId(testInsert(dto));
        else
            testUpdate(dto);
        return dto.getId();
    }

    private List<ComProjectStageGoalDTO> resetTaskContent
            (List<ComProjectStageGoalDTO> list1, List<ComProjectStageGoalDTO> list2) {
        for (ComProjectStageGoalDTO p : list2)
            list1.add(p);
        return list1;
    }

    //插入
    @Transactional
    protected String testInsert(ComProjectTaskDTO ComProjectTaskDTO) {
        ComProjectTask ComProjectTask = convert2Entity(ComProjectTaskDTO);
        String id = this.insert(ComProjectTask);
        comProjectMembersService.insertList(ComProjectTaskDTO.getMembers(), id);
        comProjectBudgetService.insertBudgetList(ComProjectTaskDTO.getBudget(), id);
        ComTaskTargetService.insertTestTargetList(ComProjectTaskDTO.getTarget(), id);
        ComProjectStageGoalService.insertList(ComProjectTaskDTO.getContent(), id);
        return id;
    }

    //更新
    @Transactional
    protected String testUpdate(ComProjectTaskDTO ComProjectTaskDTO) {
        ComProjectTask ComProjectTask = convert2Entity(ComProjectTaskDTO);
        String id = ComProjectTask.getId();
        comProjectMembersService.insertList(ComProjectTaskDTO.getMembers(), id);
        comProjectBudgetService.insertBudgetList(ComProjectTaskDTO.getBudget(), id);
        ComTaskTargetService.insertTestTargetList(ComProjectTaskDTO.getTarget(), id);
        ComProjectStageGoalService.insertList(ComProjectTaskDTO.getContent(), id);
        return this.update(ComProjectTask);
    }

    public ComProjectTaskDTO getByProjectId(String projId) {
        ComProjectTask ComProjectTask = new ComProjectTask();
        ComProjectTask.setProjId(projId);
        return this.getDto(ComProjectTask);
    }

    @Transactional
    @Override
    public void report(ComProjectAudit model, String unitId, String treeCode) {
        ComProjectTask ComProjectTask = this.entityById(model.getAuditObjectId());
        if (null == ComProjectTask)
            throw new BusinessException("任务书不存在或已上报");
        if (!ComProjectTask.getTestState().equals(CommonEnum.taskState.waitSubmit.getCode()) && !ComProjectTask.getTestState().equals(CommonEnum.taskState.returnModify.getCode()))
            throw new BusinessException("任务书不存在或已上报");
        comProjectAuditService.report(ComProjectTask.getReportYear(), model.getAuditObjectId(), model.getAuditType(), unitId, treeCode);
        // 更新任务书状态
        this.updateState(model.getAuditObjectId(), CommonEnum.taskState.review.getCode());
    }

    @Transactional
    @Override
    public void audit(ComProjectAudit comProjectAudit, String unitId, String treeCode) {
        // false 报上级或返回下一级  true报到最高级或返回个人
        int state = 0;
        ComProjectTask test = new ComProjectTask();
        test.setId(comProjectAudit.getAuditObjectId());
        if (comProjectAudit.getAuditResult().equals(CommonEnum.auditResult.pass.getCode())) {
            if (state==0) {
                test.setTestState(CommonEnum.taskState.pass.getCode());
                comProjectCheckService.insertCheckListByTestId(test.getId());
            }
        } else if (comProjectAudit.getAuditResult().equals(CommonEnum.auditResult.returnModify.getCode())) {
            if (state==0)
                test.setTestState(CommonEnum.taskState.returnModify.getCode());
        } else {
            test.setTestState(CommonEnum.taskState.failed.getCode());
        }
        if (null != test.getTestState())
            this.update(test);
    }

    @Override
    public DataStatisticsDTO getCount(ComProjectTaskQueryVO e) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(e, criteria);
        return ComProjectTaskDAO.getCount(criteria);
    }

    public List<ComFileDTO> getTaskFileList(String projId) {
        ComProject project = ComProjectService.getById(projId);
        if (null == project)
            return null;

        ComProjectTask task = new ComProjectTask();
        task.setProjId(projId);
        task = this.getEntity(task);
        if (null == task)
            return null;

        List<ComFileDTO> fileList = comFileService.getListByObjectId(task.getId(), CommonEnum.fileType.projectTask.getCode());

        return fileList;
    }

    @Transactional
    public ComDownloadDTO asyncUploadTaskFile(MultipartFile file, String projId) {
        ComDownload download = comDownloadService.asyncUpload(file);

        if (null == download)
            return null;

        ComDownloadDTO dto = comDownloadService.convertEntity2DTO(download);

        ComProject project = ComProjectService.getById(projId);

        ComProjectTask task = new ComProjectTask();
        task.setProjId(projId);
        task = this.getEntity(task);
        if (null == task) {
            task = new ComProjectTask();
            task.setTestState(1);
            task.setReportYear(project.getReportYear());
            task.setProjId(projId);
            task.setStartDate(project.getStartDate());
            task.setEndDate(project.getEndDate());
            String taskId = this.insert(task);
            task.setId(taskId);
        }

        ComFile taskFile = new ComFile();
        taskFile.setFileType(40);
        taskFile.setFileExplain("项目任务书");
        taskFile.setShowIndex(1);
        taskFile.setObjectId(task.getId());
        taskFile.setDownloadId(download.getId());
        comFileService.insert(taskFile);

        dto.setFileExplain(taskFile.getFileExplain());

        return dto;
    }

    @Transactional
    public String deleteTaskFile(String id) {
        comDownloadService.delete(id);

        ComFile taskFile = new ComFile();
        taskFile.setDownloadId(id);
        taskFile = comFileService.getEntity(taskFile);
        if (null != taskFile) {
            comFileService.delete(taskFile);
        }
        return id;
    }
}