package cn.cslg.report.service.business;

import cn.cslg.report.common.model.BaseVO;
import cn.cslg.report.common.model.vo.*;
import cn.cslg.report.common.utils.CacheUtils;
import cn.cslg.report.common.utils.DataUtils;
import cn.cslg.report.common.utils.LogExceptionUtil;
import cn.cslg.report.common.utils.Response;
import cn.cslg.report.entity.*;
import cn.cslg.report.entity.asso.AssoTaskPersonel;
import cn.cslg.report.mapper.TaskMapper;
import cn.cslg.report.service.OutInterfaceService;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class TaskService extends ServiceImpl<TaskMapper, Task> {
    private final ReportService reportService;
    private final OutInterfaceService outInterfaceService;
    private final CacheUtils cacheUtils;
    private final CompareFilesService compareFilesService;
    private final AssoTaskPersonelService assoTaskPersonelService;
    private final ReportFieldService reportFieldService;

    @Transactional(rollbackFor = Exception.class)
    public String deleteTask(Integer id) {
        try {
            this.removeById(id);
            return Response.success();
        } catch (Exception e) {
            log.error("删除任务异常,异常信息:" + LogExceptionUtil.getMessage(e));
            log.info("删除任务异常，开始回滚! 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.info("回滚完毕! 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            return Response.error();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public String updateTask(Task task) {
        try {
            this.updateById(task);
            return Response.success();
        } catch (Exception e) {
            log.error("修改任务异常,异常信息:" + LogExceptionUtil.getMessage(e));
            log.info("修改任务异常，开始回滚! 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.info("回滚完毕! 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            return Response.error();
        }
    }

    public String queryPageList(TaskVO taskVO) {
        //获得登录人的信息
        PersonnelVO personnelVO = cacheUtils.getLoginUser(StpUtil.getLoginIdAsInt());
        LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (taskVO.getType() != null) {
            lambdaQueryWrapper.eq(Task::getType, taskVO.getType());
        }
        if (taskVO.getTaskStatus() != null) {
            lambdaQueryWrapper.eq(Task::getTaskStatus, taskVO.getTaskStatus());
        }

        if (taskVO.getRoleInTask() != null) {
            if (taskVO.getRoleInTask() == 0) {
                lambdaQueryWrapper.eq(Task::getCreateID, personnelVO.getId());

            } else if (taskVO.getRoleInTask() == 1) {
                lambdaQueryWrapper.eq(Task::getHandlePersonId, personnelVO.getId());
            }
        }

        lambdaQueryWrapper.orderByDesc(Task::getId);
        List<Task> taskList;
        Long count = this.count(lambdaQueryWrapper);
        if (taskVO.getCurrent() != null && taskVO.getSize() != null) {
            taskList = this.page(new Page<>(taskVO.getCurrent(), taskVO.getSize()), lambdaQueryWrapper).getRecords();
            return Response.success(taskList, DataUtils.setPageColumn(taskVO.getSize(), taskVO.getCurrent(), Math.toIntExact(count)));
        } else {
            taskList = this.list(lambdaQueryWrapper);
            return Response.success(taskList);
        }

    }

    public String getAllTask() {
        List<Task> taskList = this.list();
        return Response.success(taskList);
    }

    //添加审核任务
    @Transactional(rollbackFor = Exception.class)
    public String addTask(TaskVO taskVO,List<MultipartFile> file) throws ParseException, IOException {
        //先添加一个报告
        Integer reportId = reportService.addReport(taskVO.getReport(),file);
        //数据库导入task

        //任务人员关联表导入数据
        if (taskVO.getPersonIds() != null) {
            List<Task> tasks = new ArrayList<>();
            List<Integer> ids = taskVO.getPersonIds();
            String resBody = outInterfaceService.getPersonnelByIdsFromPCS(ids);
            JSONObject jsonObject = JSONObject.parseObject(resBody);
            //解析jason获得标的专利的权要
            List<Personnel> personnels = JSON.parseArray(jsonObject.getString("data"), Personnel.class);
            //获得登录人的信息
            PersonnelVO personnelVO = cacheUtils.getLoginUser(StpUtil.getLoginIdAsInt());
            for (int i = 0; i < ids.size(); i++) {
                Integer handlePersonId = ids.get(i);
                Personnel personnel = new Personnel();
                personnel = personnels.stream().filter(item -> item.getId().equals(handlePersonId)).findFirst().orElse(new Personnel());
                Task task = new Task();
                task.setReportId(reportId);
                task.setTaskName(taskVO.getTaskName());
                task.setBeginTime(taskVO.getBeginTime());
                task.setEndTime(taskVO.getEndTime());
                task.setHandlePersonId(handlePersonId);
                task.setHandlePersonName(personnel.getPersonnelName());
                task.setType(taskVO.getType());
                task.setCreateID(personnelVO.getId());
                task.setCreateName(personnelVO.getName());
                task.setTaskStatus(0);
                tasks.add(task);
            }
            this.saveBatch(tasks);
        }
        return Response.success();
    }

    //审核任务
    public String auditTask(AuditTaskVO auditTaskVO) {
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getId, auditTaskVO.getTaskId());
        List<Task> tasks = this.list(queryWrapper);
        if (tasks.size() == 0 || tasks == null) {
            return Response.error("未查到任务");
        }
        Task task = tasks.get(0);
        LambdaQueryWrapper<Report> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Report::getId, task.getReportId());
        List<Report> reports = reportService.list(queryWrapper1);
        if (reports.size() == 0 || reports == null) {
            return Response.error("未查到报告");
        }
        Report report = reports.get(0);
        task.setTaskStatus(1);
        task.setResult(auditTaskVO.getResult());
        task.setRemark(auditTaskVO.getRemark());
        Date date = new Date();
        task.setFinishTime(date);
        task.updateById();
        report.setStatus(auditTaskVO.getReportStatus());
        report.updateById();

        return Response.success();
    }


    //添加分配任务
    @Transactional(rollbackFor = Exception.class)
    public String addAssTask(AssignTaskVO assignTaskVO) throws ParseException, IOException {
         LambdaQueryWrapper<Report> wrapper1 =new LambdaQueryWrapper<>();
         wrapper1.select(Report::getSignPatentNo);
         wrapper1.eq(Report::getId,assignTaskVO.getReportId());
        String signPatentNO = reportService.list(wrapper1).get(0).getSignPatentNo();
        //遍历assignTaskVO的分配人员信息assigns，在任务表里插入分配任务
        List<String> selectedNos = new ArrayList<>();
        //记录所有人的id
        List<Integer> personIds =new ArrayList<>();

        //记录总共专利号数量
        int num = 0;
        List<AssignTaskVO.assignPatents> personPatents = assignTaskVO.getAssigns();
        for (int i = 0; i < personPatents.size(); i++) {
            selectedNos.addAll(personPatents.get(i).getPatentNos());
            num += personPatents.get(i).getAssignCount();
            personIds.add(personPatents.get(i).getPersonId());
        }
        String resBody = outInterfaceService.getPersonnelByIdsFromPCS(personIds);
        JSONObject jsonObject = JSONObject.parseObject(resBody);
        //解析jason获得标的专利的权要
        List<Personnel> personnels = JSON.parseArray(jsonObject.getString("data"), Personnel.class);
        //获得登录人的信息
        PersonnelVO personnelVO = cacheUtils.getLoginUser(StpUtil.getLoginIdAsInt());

        num += selectedNos.size();
        // 根据报告Id获得待分配的专利号
        LambdaQueryWrapper<CompareFiles> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(CompareFiles::getPatentNo)
                .eq(CompareFiles::getReportId, assignTaskVO.getReportId())
        .eq(CompareFiles::getState,0);
        List<CompareFiles> compareFiles = compareFilesService.list(wrapper);
        List<String> patentNos = compareFiles.stream().map(CompareFiles::getPatentNo).collect(Collectors.toList());
        if (patentNos.size() > num) {
            return Response.error("分配数量超过未分配总数");
        }
        //待分配的专利号列表剔除分配信息中已经存在的专利号
        patentNos.removeAll(selectedNos);
        List<AssoTaskPersonel> assoTaskPersonels = new ArrayList<>();
        //记录分配的位置
        int flag = 0;
        //遍历assignTaskVO的分配人员信息assigns，装配人员所被分配的专利信息
        for (int i = 0; i < personPatents.size(); i++) {
            Integer handlePersonId = personIds.get(i);
            Personnel   personnel = personnels.stream().filter(item -> item.getId().equals(handlePersonId)).findFirst().orElse(new Personnel());
            Task task = new Task();
            task.setTaskName(assignTaskVO.getTaskName());
            task.setReportId(assignTaskVO.getReportId());
            task.setType(2);
            task.setTaskStatus(0);
            task.setProgress(0.0);
            task.setEndTime(assignTaskVO.getEndTime());
            task.setRemark(assignTaskVO.getRemark());
            task.setHandlePersonId(handlePersonId);
            task.setHandlePersonName(personnel.getPersonnelName());
            task.setCreateID(personnelVO.getId());
            task.setCreateName(personnelVO.getName());
            task.setSignPatentNo(signPatentNO);
            task.insert();
            //根据数量从分配的专利号列表中截取该数量的专利号，加上分配信息的专利号进行装配
            List<String> partNos = patentNos.subList(flag, flag+personPatents.get(i).getAssignCount()-1);
            flag += personPatents.get(i).getAssignCount();
            partNos.addAll(personPatents.get(i).getPatentNos());
            for (int t = 0; t < partNos.size(); t++) {
                AssoTaskPersonel assoTaskPersonel = new AssoTaskPersonel();
                assoTaskPersonel.setTaskId(task.getId());
                assoTaskPersonel.setTaskType(2);
                assoTaskPersonel.setPatentNo(partNos.get(t));
                assoTaskPersonel.setPersonelId(personPatents.get(i).getPersonId());
                assoTaskPersonel.setPersonelType(1);
                assoTaskPersonel.setReportId(assignTaskVO.getReportId());
                assoTaskPersonels.add(assoTaskPersonel);
            }
        }
        // 分配信息入库
        assoTaskPersonelService.saveBatch(assoTaskPersonels);
        return Response.success();
    }

    //返回任务专利清单
    @Transactional(rollbackFor = Exception.class)
    public String  reTaskPatents(TaskVO taskVo) throws ParseException, IOException {
        //根据任务Id和类型获得任务的清单
        LambdaQueryWrapper<AssoTaskPersonel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AssoTaskPersonel::getTaskId, taskVo.getTaskId());
        queryWrapper.eq(AssoTaskPersonel::getState,taskVo.getTaskStatus());
        List<AssoTaskPersonel> assoTaskPersonels = assoTaskPersonelService.list(queryWrapper);
        List<String> PatentNos =assoTaskPersonels.stream().filter(item->item.getState()==taskVo.getTaskStatus()).map(AssoTaskPersonel::getPatentNo).collect(Collectors.toList());
        //根据清单获得获得专利详情
        PatentVO patentVO =new PatentVO();
        patentVO.setPatentNos(PatentNos);
        patentVO.setSize(taskVo.getSize());
        patentVO.setCurrent(taskVo.getCurrent());
        String res = outInterfaceService.getPatentFromPAS(patentVO, 1);
        JSONObject jsonObject = JSONObject.parseObject(res);
        JSONObject jsonObject1= JSONObject.parseObject(jsonObject.get("data").toString()) ;
        List<JSONObject> jsonObjects = JSONArray.parseArray(jsonObject1.get("records").toString(), JSONObject.class);
        for (int i =0;i<jsonObjects.size();i++)
        { jsonObjects.get(i).put("field", reportFieldService.getPatentFieldByPatentIdAndProjectId(taskVo.getReportId(), jsonObjects.get(i).getString("patentNo")));
        }
        jsonObject1.put("records",jsonObjects);
        jsonObject.put("data",jsonObject1);


        return jsonObject.toString();
    }
}
