package com.ho.flow.service.impl;

import cn.hutool.core.lang.Snowflake;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ho.business.entity.Station;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.util.PageResult;
import com.ho.common.tools.util.PageUtils;
import com.ho.flow.constant.WorkOrderConstant;
import com.ho.flow.feignclient.BusinessFeignClient;
import com.ho.flow.feignclient.UserFeignClient;
import com.ho.flow.mapper.WorkOrderCirculationMapper;
import com.ho.flow.mapper.WorkOrderHisMapper;
import com.ho.flow.service.FlowWorkOrderService;
import com.ho.flow.service.WorkOrderHisService;
import com.ho.flow.vo.WorkOrderOld;
import com.ho.flow.vo.WorkOrderCirculation;
import com.ho.flow.vo.req.workorder.*;
import com.ho.flow.vo.resp.workorder.WorkOrderOldPageRespVO;
import com.ho.user.api.entity.SysUser;
import com.ho.user.api.vo.req.QueryUserReqVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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 java.util.*;

/**
 * @Description 工单管理
 * Author yule
 * Date 2022/10/14 10:43
 */
@Service
@Slf4j
public class WorkOrderHisServiceImpl implements WorkOrderHisService {

    @Autowired
    WorkOrderHisMapper workOrderHisMapper;

    @Autowired
    Snowflake snowflake;

    @Autowired
    WorkOrderCirculationMapper workOrderCirculationMapper;

    @Autowired
    BusinessFeignClient businessFeignClient;

    @Autowired
    UserFeignClient userFeignClient;

    //工作流
    @Autowired
    FlowWorkOrderService flowWorkOrderService;

    //流程定义key
    @Value("${flow.workOrder.procDefKey}")
    String procDefKey;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertStation(WorkOrderAddReq vo, SimpleUser simpleUser, String workOrderId) {
        //工单表,工单流转表分别新增一个数据
        WorkOrderOld workOrderOld = new WorkOrderOld();
        //工单id
        workOrderOld.setId(snowflake.nextId());
        workOrderOld.setOrderId(workOrderId);
        //station所属dept会发生变化,deptId不再记录,只记录stationId
        //workOrder.setDeptId(simpleUser.getDeptId());
        workOrderOld.setGroupId(simpleUser.getGroupId());
        workOrderOld.setStationId(vo.getStationId());
        workOrderOld.setFromId(simpleUser.getUserId());
        workOrderOld.setDesc(vo.getDesc());
        workOrderOld.setWorkOrderType(vo.getWorkOrderType());
        workOrderOld.setWorkOrderStatus(WorkOrderConstant.WorkOrderStatus.toBeAllocate);
        workOrderHisMapper.insertSelective(workOrderOld);
        WorkOrderCirculation workOrderCirculation = new WorkOrderCirculation();
        BeanUtils.copyProperties(workOrderOld, workOrderCirculation);
        workOrderCirculation.setWorkOrderAction(WorkOrderConstant.WorkOrderAction.workOrderCreate);
        workOrderCirculationMapper.insert(workOrderCirculation);
        //启动一个工作流, 传入 流程定义key ,租户id, businessKey, 变量
        Map<String,Object> variables = new HashMap<>();
        variables.put("stationId", vo.getStationId().toString());
        //给分配的assignee 和 验收的assignee赋值
        //variables.put(WorkOrderConstant.canDistributeOrder, WorkOrderConstant.canDistributeOrder);
        //variables.put(WorkOrderConstant.canCheckOrder, WorkOrderConstant.canCheckOrder);
        flowWorkOrderService.startProcess(procDefKey ,workOrderId ,variables, simpleUser.getGroupId().toString());
    }

    @Override
    public void updateWorkOrder(WorkOrderUpdateReq vo, SimpleUser simpleUser) {
        WorkOrderOld workOrderOld = new WorkOrderOld();
        workOrderOld.setOrderId(vo.getOrderId());
        workOrderOld.setPhone(vo.getPhone());
        workOrderOld.setStationId(vo.getStationId());
        workOrderOld.setToId(vo.getToId());
        workOrderOld.setDesc(vo.getDesc());
        workOrderHisMapper.updateByPrimaryKeySelective(workOrderOld);
    }

    //分配工单
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void allocateOrder(WorkOrderApplyReqVO applyReqVO, SimpleUser simpleUser) {
        //判断工单
        WorkOrderOld workOrderOld = findByOrderId(applyReqVO.getOrderId());
        if (workOrderOld == null) {
            //没找到数据
            throw new BusinessException(BaseResponseCode.DATA_NOT_EXISTS);
        }
        //工单状态必须是待分配
        if (!WorkOrderConstant.WorkOrderStatus.toBeAllocate.equals(workOrderOld.getWorkOrderStatus())) {
            throw new BusinessException(BaseResponseCode.WORK_ORDER_STATUS_MUST_BE_NOT_ALLOCATED);
        }
        //todo 判断taskId 和 orderId(businessKey)是否对应,不对应报错
        //修改工单状态
        WorkOrderOld workOrderOldAllocate = new WorkOrderOld();
        workOrderOldAllocate.setOrderId(applyReqVO.getOrderId());
        //fromId已经在流程发起时设置了
        // workOrderAllocate.setFromId(simpleUser.getUserId());
        workOrderOldAllocate.setToId(applyReqVO.getToId());
        workOrderOldAllocate.setPhone(applyReqVO.getPhone());
        //工单改为已分配
        workOrderOldAllocate.setWorkOrderStatus(WorkOrderConstant.WorkOrderStatus.allocated);
        workOrderHisMapper.updateByPrimaryKeySelective(workOrderOldAllocate);
        //生成流转记录
        WorkOrderCirculation circulation = new WorkOrderCirculation();
        circulation.setId(snowflake.nextId());
        circulation.setOrderId(applyReqVO.getOrderId());
        circulation.setFromId(simpleUser.getUserId());
        circulation.setToId(applyReqVO.getToId());
        circulation.setDesc(applyReqVO.getDistributionDesc());
        //动作是:分配工单
        circulation.setWorkOrderAction(WorkOrderConstant.WorkOrderAction.workOrderApply);
        workOrderCirculationMapper.insert(circulation);
        //增加下一节点参数
        OrderReq orderReq = new OrderReq();
        //下一个代办人
        orderReq.setWorkerId(applyReqVO.getToId());
        Map<String,Object> variables = new HashMap<>();
        variables.put("orderReq", orderReq);
        flowWorkOrderService.completeTask(applyReqVO.getTaskId(), variables);

    }

    @Override
    public PageResult<WorkOrderOldPageRespVO> selectPage(WorkOrderPageReq vo, SimpleUser simpleUser) {
        //根据执行人查询
        /*QueryUserReqVO userReqVO = new QueryUserReqVO();
        userReqVO.setGroupId(simpleUser.getGroupId());
        userReqVO.setUserName(vo.getToName());
        DataResult<List<SysUser>> sysUserDataResult = userFeignClient.getUserByNameConcat(userReqVO);
        List<SysUser> users = sysUserDataResult.getData();

        if (!users.isEmpty()) {
            users.stream().forEach(u -> toIdList.add(u.getId()));
        }
        List<String> toIdList = new ArrayList<>();*/
        // d设置为list
        //vo.setToIds(toIdList);
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<WorkOrderOldPageRespVO> workOrders = workOrderHisMapper.selectByPageInfo(vo);
        //发起人id集合
        List<QueryUserReqVO> fromIds = new ArrayList<>();
        //执行人id集合
        List<QueryUserReqVO> toIds = new ArrayList<>();
        //电站id集合
        //List<Integer> stationIds = new ArrayList<>();
        //遍历集合给发起人id 执行人id 电站id 增加元素
        for (WorkOrderOldPageRespVO workOrderPageRespVO : workOrders) {
            if (workOrderPageRespVO.getFromId() != null) {
                QueryUserReqVO queryFrom = new QueryUserReqVO();
                queryFrom.setUserId(workOrderPageRespVO.getFromId());
                fromIds.add(queryFrom);
            }
            if (workOrderPageRespVO.getToId() != null) {
                QueryUserReqVO queryTo = new QueryUserReqVO();
                queryTo.setUserId(workOrderPageRespVO.getToId());
                toIds.add(queryTo);
            }
            //没有再加入
            /*if (!stationIds.contains(workOrderPageRespVO.getStationId())) {
                stationIds.add(workOrderPageRespVO.getStationId());
            }*/
        }

        //查询发起人用户集合
        List<SysUser> fromUsers = new ArrayList<>();
        if (!fromIds.isEmpty()) {
            DataResult<List<SysUser>> fromResult = userFeignClient.queryUser(fromIds);
            fromUsers = fromResult.getData();
        }
        //查询执行人用户集合
        List<SysUser> toUsers = new ArrayList<>();
        if (!toIds.isEmpty()) {
            DataResult<List<SysUser>> toResult = userFeignClient.queryUser(toIds);
            toUsers = toResult.getData();
        }
        //查询电站集合
        List<Station> stations = new ArrayList<>();
        if (!vo.getStationIds().isEmpty()) {
            DataResult<List<Station>> listDataResult = businessFeignClient.selectByStationIds(vo.getStationIds());
            if (listDataResult.isSuccess()) {
                stations = listDataResult.getData();
            }
        }
        for (int i = 0; i < workOrders.size(); i++) {
            //遍历发起人用户集合获取到发起人名字,给工单的发起人名字赋值
            if ((workOrders.get(i).getFromId() != null)) {
                for (SysUser fromUser : fromUsers) {
                    if (workOrders.get(i).getFromId().equals(fromUser.getId())) {
                        workOrders.get(i).setFromName(fromUser.getUsername());
                        break;
                    }
                }
            }
            if (workOrders.get(i).getToId() != null) {
                for (SysUser toUser : toUsers) {
                    if (workOrders.get(i).getToId().equals(toUser.getId())) {
                        workOrders.get(i).setToName(toUser.getUsername());
                        break;
                    }
                }
            }
            //电站名称
            for (Station station : stations) {
                if (workOrders.get(i).getStationId().equals(station.getId())) {
                    workOrders.get(i).setStationName(station.getName());
                    break;
                }
            }
        }
        for (WorkOrderOldPageRespVO workOrder : workOrders) {
            //判断工单是否为新建并且发起人是登录人
            if (WorkOrderConstant.WorkOrderStatus.toBeAllocate.equals(workOrder.getWorkOrderStatus())
                    && workOrder.getFromId().equals(simpleUser.getUserId())) {
                workOrder.setEdit(1);
            } else {
                workOrder.setEdit(0);
            }
            //判断执行人是否为登录人
            String toId = workOrder.getToId();
            if (toId != null && toId.equals(simpleUser.getUserId())) {
                //分配人是登陆人, 工单可操作, 否则不可以操作
                workOrder.setOperation(1);
            } else {
                workOrder.setOperation(0);
            }
            //接收人为空,如果, todo 这个地方的逻辑还需要再核对一下, 有权限的人可以操作工单,应该和发起人是不是自己没关系
            if (toId == null && workOrder.getFromId().equals(simpleUser.getUserId()) && vo.getRoleLeader() != null) {
                workOrder.setOperation(1);
            }
            //判断是否能退回
            //新建工单不能退回
            if (WorkOrderConstant.WorkOrderStatus.toBeAllocate.equals(workOrder.getWorkOrderStatus())) {
                workOrder.setReturnFlag(0);
            }
            //执行人不是登录人,不能退回
            else if (toId != null && !toId.equals(simpleUser.getUserId())) {
                workOrder.setReturnFlag(0);
            } else {
                workOrder.setReturnFlag(1);
            }
        }
        PageResult pageResult = PageUtils.getPageResult(new PageInfo<>(workOrders));
        return pageResult;
    }

    @Override
    public PageResult<WorkOrderOldPageRespVO> selectHisPage(WorkOrderPageReq vo) {
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<WorkOrderOldPageRespVO> workOrders = workOrderHisMapper.selectByHisPageInfo(vo);

        //发起人id集合
        List<QueryUserReqVO> fromIds = new ArrayList<>();
        //执行人id集合
        List<QueryUserReqVO> toIds = new ArrayList<>();
        //电站id集合
        List<Integer> stationIds = vo.getStationIds();
        //遍历集合给发起人id 执行人id 电站id 增加元素
        for (WorkOrderOldPageRespVO workOrderPageRespVO : workOrders) {
            QueryUserReqVO queryFrom = new QueryUserReqVO();
            queryFrom.setUserId(workOrderPageRespVO.getFromId());
            fromIds.add(queryFrom);
            QueryUserReqVO queryTo = new QueryUserReqVO();
            queryTo.setUserId(workOrderPageRespVO.getToId());
            toIds.add(queryTo);
            //stationIds.add(workOrderPageRespVO.getStationId());
        }

        //查询发起人用户集合
        List<SysUser> fromUsers = new ArrayList<>();
        if (!fromIds.isEmpty()) {
            DataResult<List<SysUser>> fromResult = userFeignClient.queryUser(fromIds);
            fromUsers = fromResult.getData();
        }
        //查询执行人用户集合
        List<SysUser> toUsers = new ArrayList<>();
        if (!toIds.isEmpty()) {
            DataResult<List<SysUser>> toResult = userFeignClient.queryUser(toIds);
            toUsers = toResult.getData();
        }
        //查询电站集合
        List<Station> stations = new ArrayList<>();
        //电站List为空
        if (stationIds == null || stationIds.isEmpty()) {

            stationIds.add(vo.getStationId());
        }
        DataResult<List<Station>> listDataResult = businessFeignClient.selectByStationIds(stationIds);
        if (listDataResult.isSuccess()) {
            stations = listDataResult.getData();
        }
        for (int i = 0; i < workOrders.size(); i++) {
            //遍历发起人用户集合获取到发起人名字,给工单的发起人名字赋值
            if ((workOrders.get(i).getFromId() != null)) {
                for (SysUser fromUser : fromUsers) {
                    if (workOrders.get(i).getFromId().equals(fromUser.getId())) {
                        workOrders.get(i).setFromName(fromUser.getUsername());
                        break;
                    }
                }
            }
            if (workOrders.get(i).getToId() != null) {
                for (SysUser toUser : toUsers) {
                    if (workOrders.get(i).getToId().equals(toUser.getId())) {
                        workOrders.get(i).setToName(toUser.getUsername());
                        break;
                    }
                }
            }
            for (Station station : stations) {
                if (workOrders.get(i).getStationId().equals(station.getId())) {
                    workOrders.get(i).setStationName(station.getName());
                    break;
                }
            }
        }
        PageResult pageResult = PageUtils.getPageResult(new PageInfo<>(workOrders));
        return pageResult;

    }

    @Override
    public WorkOrderOld selectById(String orderId) {
        WorkOrderOld workOrderOld = workOrderHisMapper.selectByOrderId(orderId);
        return workOrderOld;
    }

    @Override
    public List<WorkOrderOld> selectByEventIds(List<Long> eventIds) {
        List<WorkOrderOld> workOrderOlds = workOrderHisMapper.selectByEventIds(eventIds);
        return workOrderOlds;
    }

    @Override
    public List<WorkOrderOld> selectByStationIds(List<Long> stationIds) {
        return null;
    }

    @Override
    public void deleteWorkOrder(List<String> orderIds) {
        workOrderHisMapper.deleteByPrimaryKey(orderIds);
    }

    @Override
    public void delete(String orderId) {
        workOrderHisMapper.delete(orderId);
    }

    @Override
    public WorkOrderOld findByOrderId(String orderId) {
        return workOrderHisMapper.selectByOrderId(orderId);
    }

    @Override
    public void acceptWorkOrder(WorkOrderOld workOrderOld, WorkOrderCirculation workOrderAllocate) {
        //修改工单数据
        workOrderOld.setReceiveTime(new Date());
        workOrderHisMapper.updateByPrimaryKeySelective(workOrderOld);
        // 新增工单流水
        workOrderCirculationMapper.insertSelective(workOrderAllocate);

    }


    @Override
    public void returnWorkOrder(WorkOrderOld workOrderOld, WorkOrderCirculation workOrderAllocate) {
        //修改工单数据--- 退回状态 清空（执行人id 电话 接收时间）
        workOrderHisMapper.updateReturnWorkOrder(workOrderOld);

        // 新增工单流水
        workOrderCirculationMapper.insertSelective(workOrderAllocate);
    }


    @Override
    public void closeWorkOrder(WorkOrderOld workOrderOld, WorkOrderCirculation workOrderAllocate) {
        //修改工单数据--- 完成状态
        workOrderOld.setCompleteTime(new Date());
        workOrderHisMapper.updateByPrimaryKeySelective(workOrderOld);
        // 新增工单流水
        workOrderCirculationMapper.insertSelective(workOrderAllocate);
    }


    @Override
    public int insertEventBatch(List<WorkOrderOld> workOrderOlds) {
        int i = workOrderHisMapper.insertBatch(workOrderOlds);
        return i;
    }
}