package com.ruoyi.system.service.task.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.grid.GridRegion;
import com.ruoyi.system.domain.grid.GridRegionUser;
import com.ruoyi.system.domain.task.*;
import com.ruoyi.system.domain.task.request.TaskAssignedRequest;
import com.ruoyi.system.domain.task.utils.WorkMSGUtils;
import com.ruoyi.system.listener.MyBaseService;
import com.ruoyi.system.mapper.task.TkCommonAssignedMapper;
import com.ruoyi.system.service.BaseServiceImpl;
import com.ruoyi.system.service.grid.GridRegionService;
import com.ruoyi.system.service.grid.GridRegionUserService;
import com.ruoyi.system.service.system.ISysDeptService;
import com.ruoyi.system.service.system.ISysUserService;
import com.ruoyi.system.service.task.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Cesar
* @date  ${cTime}
* @desc TkCommonAssignedService实现
*/
@Slf4j
@Service
@MyBaseService
public class TkCommonAssignedServiceImpl extends BaseServiceImpl<TkCommonAssignedMapper, TkCommonAssigned, TkCommonAssignedExample> implements TkCommonAssignedService {
    @Value("${app.sms.enable}")
    private boolean smsEnable;
    @Value("${app.sms.switch}")
    private boolean smsswitch;
    @Resource
    private WorkMSGUtils workMSGUtils;
    @Resource
    private TkWorkService tkWorkService;
    @Resource
    private TkCommonTaskService tkCommonTaskService;
    @Resource
    private TkCommonTaskDynamicService tkCommonTaskDynamicService;
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private TkCommonAssignedMapper tkCommonAssignedMapper;
    @Resource
    private TaskService taskService;
    @Autowired
    private GridRegionUserService gridRegionUserService;
    @Resource
    private GridRegionService gridRegionService;
    @Resource
    private ISysDeptService deptService;

    @Override
    @Transactional
    public int assigned(TaskAssignedRequest request) {
        List<TaskAssignedRequest.Assigned> tkCommonAssigneds = this.toAssigned(request);
        TkCommonTask tkCommonTask = tkCommonTaskService.selectByPrimaryKey(request.getId());
        //清空指派数据
        taskService.resetAfterAssigned(tkCommonTask);
        //更改日常任务（任务指派数据保存）
        tkCommonTask.setAssignedEndTime(request.getAssignedEndTime());
        tkCommonTask.setAssignedNode(request.getAssignedNode());
        tkCommonTask.setTkStatus(12);//任务指派
        tkCommonTask.setAssignedUserId(request.getLoginUserId());//指派人id
        tkCommonTask.setAssignedUserName(request.getLoginUserName());//指派人姓名
        tkCommonTask.setPerformUserType(request.getPerformUserType());
        tkCommonTask.setPerformUserId(request.getPerformUserList().stream().map(TaskAssignedRequest.PerformUser::getPerformUserId).collect(Collectors.joining(",")));
        tkCommonTask.setPerformUserName(request.getPerformUserList().stream().map(TaskAssignedRequest.PerformUser::getPerformUserName).collect(Collectors.joining(",")));
        tkCommonTaskService.updateByPrimaryKey(tkCommonTask);
        //保存指派表数据
        for (TkCommonAssigned tkCommonAssigned : tkCommonAssigneds) {
            tkCommonAssignedMapper.insert(tkCommonAssigned);
        }
        if (CollectionUtils.isNotEmpty(request.getLeaders())) {
            String node = tkCommonTaskService.saveReceiveAndBackNode(tkCommonTask.getId(), null, 3, request.getLeaders(), "");
            //保存操作记录
            tkCommonTaskService.saveDynamicByType(tkCommonTask.getId(), request.getLoginUserName(), request.getLoginUserBelongGrid(), null, node, null);
        }

        if (smsEnable) {
            //--------------------修改待办任务状态------------------------
            //不管接受还是拒绝 都要改变下待办任务的状态
            TkWorkExample tkWorkExample = new TkWorkExample();
            TkWorkExample.Criteria criteria2 = tkWorkExample.createCriteria();
            criteria2.andCommonTaskIdEqualTo(tkCommonTask.getId());
            tkWorkExample.setOrderByClause("create_time desc");
            List<TkWork> tkWorks = tkWorkService.selectByExample(tkWorkExample);
            if (!tkWorks.isEmpty()) {
                workMSGUtils.updateWork(request.getLoginUserId(), tkWorks.get(0).getWorkId(), 1);
            }
            //--------------------修改待办任务状态-------------------

            List<String> beassignedUserIds = tkCommonAssigneds.stream().map(TkCommonAssigned::getBeassignedUserId).collect(Collectors.toList());
            String body = tkCommonTask.getTkName() + "已被指派";
            workMSGUtils.sendMsg(
                    request.getLoginUserId(),
                    tkCommonTask.getAssignedUserName(),
                    beassignedUserIds, body,
                    tkCommonTask.getMatterType(),
                    tkCommonTask.getId()
            );

            //创建待办任务---------------
            String workName = tkCommonTask.getTkName() + "待接收";
            String ret = workMSGUtils.createWork(tkCommonTask, request.getLoginUserId(), beassignedUserIds, workName);
            if (ret != null) {
                JSONObject jo = JSONObject.parseObject(ret);
                System.out.println("-------" + jo);
                if (jo.get("msg").equals("success")) {//接口访问成功
                    JSONObject data = JSONObject.parseObject(jo.get("data").toString());
                    TkWork tkWork = new TkWork();
                    tkWork.setId(UUID.randomUUID().toString());
                    tkWork.setCommonTaskId(tkCommonTask.getId());
                    tkWork.setWorkId(data.get("workId").toString());
                    tkWork.setCreateTime(new Date());
                    if (tkWorkService.insert(tkWork) == 0) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚
                        return 0;
                    }
                }
            }
        }
        //操作记录表
        for (TaskAssignedRequest.Assigned tkCommonAssigned : tkCommonAssigneds) {
            TkCommonTaskDynamic tkCommonTaskDynamic = tkCommonTaskService.getTkCommonTaskDynamic(
                    tkCommonTask.getId(), request.getLoginUserName(), request.getLoginUserBelongGrid(),
                    tkCommonAssigned.getBeassignedUserName(), tkCommonAssigned.getPerformUserGrid()
            );
            tkCommonTaskDynamicService.insert(tkCommonTaskDynamic);
        }

        //发送短信
        try {
            if (smsswitch) {
                for (TaskAssignedRequest.Assigned performUser : tkCommonAssigneds) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("name", performUser.getBeassignedUserName());
                    map.put("address", performUser.getPerformUserGrid());
                    map.put("taskId", tkCommonTask.getId());
                    map.put("type", "接收");
                    map.put("taskName", tkCommonTask.getTkName());
                    //根据用户id获取用户信息
                    SysUser userInfo = sysUserService.selectUserById(performUser.getBeassignedUserId());
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            workMSGUtils.sendDXSMS(userInfo, map);
                        }
                    }).start();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("指派短信发送失败");
        }
        return 1;
    }

    @Transactional
    @Override
    public void assignedDept(TaskAssignedDeptRequest request) {
        if (CollectionUtils.isEmpty(request.getPerformDeptList()) || StringUtils.isBlank(request.getId())){
            throw new ServiceException("参数错误");
        }
        TkCommonTask tkCommonTask = tkCommonTaskService.selectByPrimaryKey(request.getId());
        //重置
        taskService.resetAfterAssigned(tkCommonTask);
        List<GridRegionUser> gridRegionUser = gridRegionUserService.getPermissionWgCodes(request.getLoginUserId());
        Map<String,String> gridRegion = gridRegionService.getMapByWgCodes(gridRegionUser.stream().map(GridRegionUser::getWgId).collect(Collectors.toList()));
        tkCommonTask.setAssignedDeptIds(request.getPerformDeptList().stream().map(TaskAssignedDeptRequest.Dept::getPerformDeptId).map(String::valueOf).collect(Collectors.joining(",")));
        tkCommonTask.setAssignedDeptNames(request.getPerformDeptList().stream().map(TaskAssignedDeptRequest.Dept::getPerformDeptName).collect(Collectors.joining(",")));
        tkCommonTask.setQprId(request.getLoginUserId());
        tkCommonTask.setQprName(request.getLoginUserName());
        tkCommonTask.setQprTime(new Date());
        tkCommonTaskService.updateByPrimaryKey(tkCommonTask);
        //日志
        TkCommonTaskDynamic tkCommonTaskDynamic = new TkCommonTaskDynamic();
        tkCommonTaskDynamic.setId(UUID.randomUUID().toString());
        tkCommonTaskDynamic.setCommonTkId(request.getId());
        tkCommonTaskDynamic.setName(request.getLoginUserName());
        tkCommonTaskDynamic.setAddress(String.join(",", gridRegion.values()));
        tkCommonTaskDynamic.setTkTime(new Date());
        tkCommonTaskDynamic.setCreateTime(new Date());
        tkCommonTaskDynamic.setNote("指派了部门："+tkCommonTask.getAssignedDeptNames());
        tkCommonTaskDynamicService.insert(tkCommonTaskDynamic);
    }

    @Override
    public void deleteByTaskId(String taskId) {
        if (StringUtils.isBlank(taskId)){
            return;
        }
        TkCommonAssignedExample example = new TkCommonAssignedExample();
        example.createCriteria().andCommonTkIdEqualTo(taskId);
        this.deleteByExample(example);
    }

    private List<TaskAssignedRequest.Assigned> toAssigned(TaskAssignedRequest request){
        GridRegionUser gridRegionUser = gridRegionUserService.selectByUserId(request.getLoginUserId());
        GridRegion gridRegion = gridRegionService.loadDetailByCode(gridRegionUser.getWgId());
        List<TaskAssignedRequest.Assigned> tkCommonAssigneds = Lists.newArrayList();
        //查询有关联任务id 的数据
        TkCommonAssignedExample tkCommonAssignedExample = new TkCommonAssignedExample();
        TkCommonAssignedExample.Criteria criteria = tkCommonAssignedExample.createCriteria();
        criteria.andCommonTkIdEqualTo(request.getId());
        List<TkCommonAssigned> exists = this.selectByExample(tkCommonAssignedExample);
        List<TaskAssignedRequest.PerformUser> performUsers = request.getPerformUserList();
        for (TaskAssignedRequest.PerformUser performUser : performUsers) {
            TaskAssignedRequest.Assigned tkCommonAssigned = new TaskAssignedRequest.Assigned();//任务指派实体类
            tkCommonAssigned.setId(UUID.randomUUID().toString());
            tkCommonAssigned.setCommonTkId(request.getId());
            tkCommonAssigned.setPerformUserType(request.getPerformUserType());
            tkCommonAssigned.setAssignedUserId(request.getLoginUserId());//指派人id
            tkCommonAssigned.setAssignedUserName(request.getLoginUserName());//指派人姓名
            tkCommonAssigned.setAssignedEndTime(request.getAssignedEndTime());
            tkCommonAssigned.setAssignedNode(request.getAssignedNode());
            tkCommonAssigned.setAssignedRole(Integer.parseInt(gridRegion.getLevel()));//指派人角色等级
            tkCommonAssigned.setBeassignedUserId(performUser.getPerformUserId());//被指派人用户id
            tkCommonAssigned.setBeassignedUserName(performUser.getPerformUserName());//被指派人用户名
            //被指派人 网格
            GridRegion perFormGridRegion = gridRegionService.loadDetailByCode(gridRegionUser.getWgId());
            tkCommonAssigned.setPerformUserGrid(perFormGridRegion.getWgName());
            //被指派人角色等级
            tkCommonAssigned.setBeassignedRole(Integer.parseInt(perFormGridRegion.getLevel()));
            tkCommonAssigned.setCreateTime(new Date());
            if (exists.size() > 0) {
                int status = exists.stream().mapToInt(TkCommonAssigned::getAssignedStatus).max().getAsInt();
                tkCommonAssigned.setAssignedStatus(status + 1);//取出最后一条数据的状态+1
            } else {
                tkCommonAssigned.setAssignedStatus(1);//没数据就设为 1
            }
            tkCommonAssigneds.add(tkCommonAssigned);
        }
        return tkCommonAssigneds;
    }
}