package com.junmp.jyzb.listener;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.junmp.junmpProcess.dto.json.ChildNode;
import com.junmp.junmpProcess.dto.json.UserInfo;
import com.junmp.junmpProcess.utils.RabbitMQUtils2;
//import com.rabbitmq.client.Channel;
//import com.rabbitmq.client.Connection;
import com.junmp.jyzb.api.bean.dto.MQDto;
import com.junmp.jyzb.api.bean.dto.OrderDto;
import com.junmp.jyzb.api.bean.query.BussinessOrderDetialReq;
import com.junmp.jyzb.api.bean.query.OrderMainReq;
import com.junmp.jyzb.api.bean.req.UpdateBusFormReq;
import com.junmp.jyzb.api.bean.req.UpdateOrderDetailReq;
import com.junmp.jyzb.api.bean.req.UpdateOrderReq;
import com.junmp.jyzb.api.bean.req.UpdateReassignmentReq;
import com.junmp.jyzb.api.exception.enums.InventoryExceptionEnum;
import com.junmp.jyzb.api.exception.enums.OrderExceptionEnum;
import com.junmp.jyzb.entity.*;
import com.junmp.jyzb.service.*;
import com.junmp.jyzb.utils.DateTimeUtil;
import com.junmp.jyzb.utils.RabbitMQSendMsg;
import com.junmp.v2.common.exception.base.ServiceException;
import com.junmp.v2.common.util.BeanPlusUtil;
import com.junmp.v2.message.api.MessageApi;
import com.junmp.v2.message.api.bean.req.MessageReq;
import com.junmp.v2.message.api.bean.req.MessageSendReq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.MessageProperties;
import lombok.SneakyThrows;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.impl.event.FlowableEntityEventImpl;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.beans.Transient;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.junmp.junmpProcess.common.CommonConstants.*;


@Component
    public class GlobalEndListener extends AbstractFlowableEngineEventListener {
    @Resource
    public OrderMainService orderMainService;

    @Resource
    public OrderDetailService orderDetailService;
    @Resource
    private HistoryService historyService;

    @Resource
    private BusFormService busFormService;

    @Resource
    private PolicemanService policemanService;
    @Resource
    private ReassignmentService reassignmentService;

    @Resource
    private StocktakeService stocktakeService;

    @Resource
    private InventorySummaryService inventorySummaryService;

    @Resource
    private LogSummaryService logSummaryService;
    @Resource
    private LogDetailService logDetailService;

    @Resource
    private MessageApi messageApi;
    @Resource
    private BussinessInventoryService bussinessInventoryService;
    @Autowired
    private RabbitMQSendMsg MQ;
    @Resource
    private RepositoryService repositoryService;
        protected Logger logger = LoggerFactory.getLogger(this.getClass());

        @Transactional(rollbackFor = Exception.class)
        @SneakyThrows
        @Override
        public void processCompleted(FlowableEngineEntityEvent event) {


            if (event.getType() == FlowableEngineEventType.PROCESS_COMPLETED) {
                // 获取流程实例ID
                String processInstanceId = event.getProcessInstanceId();

                Process mainProcess = repositoryService.getBpmnModel(event.getProcessDefinitionId()).getMainProcess();
                HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                        .processInstanceId(processInstanceId)
                        .includeProcessVariables()
                        .singleResult();
                // 获取流程定义ID
                String processDefinitionId = event.getProcessDefinitionId();
                List<HistoricVariableInstance> typeOrder = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName("typeOrder").list();

                if(typeOrder.size()>0) {


                    String Type= typeOrder.get(0).getValue().toString();
                    if (Type.equals("workOrder") || Type.equals("quickOrder"))//出入库单据
                    {
                        OrderMain existOrder= orderMainService.getOne(new LambdaQueryWrapper<OrderMain>()
                                .eq(OrderMain::getProcessId, processInstanceId));
                        existOrder.setExamineState("finished");
                        existOrder.setOrderState("ready");
                        UpdateOrderReq updateOrderReq = new UpdateOrderReq();
                        BeanPlusUtil.copyProperties(existOrder,updateOrderReq);
                        List<OrderDetail> list = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                                .eq(OrderDetail::getOrderId, updateOrderReq.getId()));
                        updateOrderReq.setId(existOrder.getId());
                        existOrder.setActualQuantity(0);
                        orderMainService.updateById(existOrder);
//                        orderMainService.ChangeOrderState(updateOrderReq);
                        List<UpdateOrderDetailReq> collect = list.stream().map(orderDetail -> {
                            UpdateOrderDetailReq updateOrderDetailReq = new UpdateOrderDetailReq();
                            BeanPlusUtil.copyProperties(orderDetail, updateOrderDetailReq);
                            if (ObjectUtil.isNotNull(orderDetail.getProductionDate())){
                                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                                updateOrderDetailReq.setProductionDate(format.format(orderDetail.getProductionDate()));
                            }
                            orderDetail.setActualNum(0);
                            orderDetail.setModifyQuantity(0);
                            return updateOrderDetailReq;
                        }).collect(Collectors.toList());
                        orderDetailService.updateBatchById(list);
                        updateOrderReq.setDetailList(collect);
                        //将单据上传到rabbitmq
                        orderMainService.AddFinishOrder(updateOrderReq);
                    } else
                    //业务单据
                    if (Type.equals("bussinessOrder")){
                        BusForm busForm = busFormService.getOne(new LambdaQueryWrapper<BusForm>()
                                .eq(BusForm::getProcessId, processInstanceId));
                        busForm.setExamineState("finished");
                        if (busForm.getBussinessType().equals("remove")){
                            busFormService.updateBrokenResult(busForm);
                        }
                        busFormService.updateById(busForm);
                    } else
                    if (Type.equals("reassignment")){//调岗申请单
                        Reassignment one = reassignmentService.getOne(new LambdaQueryWrapper<Reassignment>()
                                .eq(Reassignment::getProcessId, processInstanceId));
                        UpdateReassignmentReq updateReassignmentReq = new UpdateReassignmentReq();
                        one.setExamineState("finished");
                        BeanPlusUtil.copyProperties(one,updateReassignmentReq);
                        //如果同意直接讲警员基础信息进行修改
                        policemanService.changePoliceOrg(updateReassignmentReq);
                        reassignmentService.updateById(one);
                    } else
                    if (Type.equals("stocktakeOrder")){//盘库申请单

                        String exchangeName="orderExchange";
                        //需要判断是入库单还是出库单，入库单传收物单位id，出库单传发物单位id
                        BussinessInventory BI = bussinessInventoryService.getOne(new LambdaQueryWrapper<BussinessInventory>()
                                .eq(BussinessInventory::getProcessId, processInstanceId));
                        BI.setExamineState("finished");
                        BI.setApi("BussinessInventory");
                        bussinessInventoryService.updateById(BI);
                        MQ.SendMsg(exchangeName,BI.getOrgId().toString(),BI);

                    } else
                    if (Type.equals("normalOrder")){
                        OrderMain existOrder= orderMainService.getOne(new LambdaQueryWrapper<OrderMain>()
                                .eq(OrderMain::getProcessId, processInstanceId));
                        existOrder.setExamineState("finished");
                        existOrder.setOrderState("finished");
                        existOrder.setManualState(1);
                        orderMainService.updateById(existOrder);
                        MQDto mqDto = new MQDto();
                        mqDto.setApi("NormalToOrder");
                        mqDto.setType(existOrder.getOrderType().equals("in")?0:1);
                        LogSummary one = logSummaryService.getOne(new LambdaQueryWrapper<LogSummary>()
                                .eq(LogSummary::getOrderMainId, existOrder.getId()));
                        List<String> collect = logDetailService.list(new LambdaQueryWrapper<LogDetail>()
                                .eq(LogDetail::getSummaryId, one.getId()))
                                .stream().map(LogDetail::getInventoryId)
                                .collect(Collectors.toList());
                        mqDto.setIdList(collect);
                        if(existOrder.getOrderType().equals("in")){
                            MQ.SendMsg("orderExchange",existOrder.getEndOrgId().toString(),mqDto);
                        }else {
                            MQ.SendMsg("orderExchange",existOrder.getStartOrgId().toString(),mqDto);
                        }
                        }
                    //消息推送
                    MessageSendReq sendReq = new MessageSendReq();
                    String startUser= MapUtil.getStr(historicProcessInstance.getProcessVariables(),START_USER_INFO);
                    UserInfo user=  JSONObject.parseObject(startUser, UserInfo.class);
                    String Types= MapUtil.getStr(historicProcessInstance.getProcessVariables(),TYPE_ORDER);
                    sendReq.setReceiveUserIds(String.valueOf(user.getUserId()));

                    sendReq.setBizType("pass/"+Types);
                    sendReq.setBizId(Long.valueOf(processInstanceId));
                    if (Type.equals("stocktakeOrder"))//整理需要下发的消息
                    {
                        sendReq.setMsgTitle("盘点提醒");
                        sendReq.setMsgContent("【盘库单】已下发");
                    }
                    else
                    {
                        sendReq.setMsgTitle("您的审批已通过");
                        sendReq.setMsgContent("您提交的审批【"+mainProcess.getName()+"】已经通过");
                    }
                    sendReq.setPriority("0");
                    sendReq.setSendTime(DateTime.now());
                    messageApi.sendMessage(sendReq);
                    messageApi.queryCount(new MessageReq());
                    /*推送发送未读数量*/
                    MessageReq req1 = new MessageReq();
                    req1.setReadFlag(0);
                    req1.setReceiveUserId(user.getUserId());
                    Integer count1 = messageApi.queryCount(req1);
                    messageApi.pushMsgToUser(startUser,count1);
                }

            }
        }


    }

