package com.youchain.businessdata.rest;

import com.youchain.annotation.Log;
import com.youchain.annotation.AnonymousAccess;
import com.youchain.appupdate.inputJson.MissionStateCallback;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.repository.PointRepository;
import com.youchain.businessdata.domain.AgvTask;
import com.youchain.businessdata.domain.Inventory;
import com.youchain.businessdata.domain.ItemKey;
import com.youchain.businessdata.domain.Task;
import com.youchain.businessdata.inputJson.ReturnIssueInfo;
import com.youchain.businessdata.inputJson.ReturnIssueInfoParams;
import com.youchain.businessdata.inputJson.ReturnMoInfo;
import com.youchain.businessdata.inputJson.ReturnMoParams;
import com.youchain.businessdata.repository.AgvTaskRepository;
import com.youchain.businessdata.repository.InventoryRepository;
import com.youchain.businessdata.repository.TaskRepository;
import com.youchain.businessdata.service.AgvTaskService;
import com.youchain.businessdata.service.MlsService;
import com.youchain.businessdata.service.OrderService;
import com.youchain.businessdata.service.TaskService;
import com.youchain.businessdata.service.dto.AgvTaskDto;
import com.youchain.businessdata.service.dto.OrderDto;
import com.youchain.exception.handler.ApiResult;
import com.youchain.service.LogService;
import com.youchain.utils.BaseStatus;
import com.youchain.utils.BizStatus;
import com.youchain.utils.UrlApi;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.CompletableFuture;


@RestController
@RequiredArgsConstructor
@Api(tags = "KMReS")
@RequestMapping("/interfaces/api/amr")
@Slf4j
public class KMReSController {

    private final AgvTaskService agvTaskService;
    private final AgvTaskRepository agvTaskRepository;
    private final PointRepository pointRepository;
    private final TaskRepository taskRepository;
    private final InventoryRepository inventoryRepository;
    private final TaskService taskService;
    private final OrderService orderService;
    private final MlsService mlsService;
    private final LogService logService;

    @PostMapping("/missionStateCallback")
    @Log("KMReS接口回调")
    @ApiOperation("KMReS接口回调")
    @AnonymousAccess
    public ResponseEntity<Object> missionStateCallback(@RequestBody MissionStateCallback missionStateCallback) {
        System.out.println("接口任务回调:"+missionStateCallback.toString());
        missionStateCallbackChild(missionStateCallback);
        return ResponseEntity.ok(ApiResult.success(HttpStatus.OK.value(), "", ""));
    }

    public void missionStateCallbackChild(MissionStateCallback missionStateCallback) {
        String missionCode = missionStateCallback.getMissionCode(); // 作业 id
        String containerCode = missionStateCallback.getContainerCode(); // 容器编号
        String missionStatus = missionStateCallback.getMissionStatus(); // 作业当前状态
        String slotCode = missionStateCallback.getSlotCode(); // 作业当前状态
        AgvTask agvTask = agvTaskRepository.findByJobForce(missionCode,containerCode);
        if (agvTask!=null) {
            String id=agvTask.getId()+"";
            if (agvTask.getType().equals(BizStatus.PICK)) {
                //出库
                pickTask(id, containerCode, missionStatus);
            } else if (agvTask.getType().equals(BizStatus.ASN)) {
                //入库
                asnTask(id, missionStatus,slotCode);
            } else if (agvTask.getType().equals(BizStatus.INV)) {
                invTask(id, missionStatus,slotCode);
            } else if (agvTask.getType().equals(BizStatus.INV_BACK)) {
                invBackTask(id, missionStatus,slotCode);
            }
        }
    }

    /* 验货 返空任务完成*/
    private void invBackTask(String id, String missionStatus, String slotCode) {
        if (missionStatus.equals(BizStatus.PICKER_RECEIVE)) {
            /* 清空起点*/
            Point point=pointRepository.findByCode(slotCode);
            point.setStatus(BaseStatus.FREE);
            pointRepository.save(point);
        }else
        if (missionStatus.equals(BizStatus.PICKER_SEND)) {
            AgvTask agvTask=agvTaskRepository.getById(Integer.valueOf(id));
            Point point=pointRepository.findByCode(slotCode);
            if (point!=null){
                /* 修改任务状态*/
                Task task = getFirstTask(agvTask.getId());
                task.setTaskStatus(BizStatus.FINISH);
                taskRepository.save(task);
                /* 清除库存占用*/
                Inventory inventory=inventoryRepository.getById(task.getInvId());
                inventory.setQueuedQty(0d);
                inventoryRepository.save(inventory);
            }
            agvTask.setStatus(BizStatus.FINISH);
            agvTaskRepository.save(agvTask);
        }
    }

    private void invTask(String id, String missionStatus, String slotCode) {
        if (missionStatus.equals(BizStatus.PICKER_SEND)) {
            AgvTask agvTask=agvTaskRepository.getById(Integer.valueOf(id));
            Point point=pointRepository.findByCode(slotCode);
            if (point!=null){
                Task task = getFirstTask(agvTask.getId());
                task.setTaskStatus(BizStatus.INSPECT);
                task.setMoveQty(task.getPlanQty());
                taskRepository.save(task);
            }
            agvTask.setStatus(BizStatus.FINISH);
            agvTaskRepository.save(agvTask);
        }
    }

    public void asnTask(String id, String missionStatus, String slotCode) {
        //执行第一个任务后 可以继续执行第二个任务 并携带第一个任务的返回值 第二个任务执行完没有返回值
        AgvTaskDto agvTaskDto = agvTaskService.findById(Integer.parseInt(id));
        AgvTask agvTask = agvTaskService.toEntity(agvTaskDto);
        Task task = getFirstTask(agvTask.getId());
        agvTaskService.agvTaskCallback(agvTask, task, missionStatus);

        if (missionStatus.equals(BizStatus.PICKER_SEND)) {
            CompletableFuture.runAsync(() -> {
//                returnMo(task.getBillCode());// 回传MO信息
            });
        }
    }

    public void pickTask(String id, String containerCode, String missionStatus) {
        if (BizStatus.CANCEL.equals(missionStatus)) {
            cancelAgvTasks(id);
        } else if (BizStatus.PICKER_SEND.equals(missionStatus)){
            AgvTask agvTask = agvTaskRepository.getById(Integer.valueOf(id));
            Task task = getFirstTask(agvTask.getId());
            agvTaskService.agvTaskCallback(agvTask, missionStatus, containerCode);
            Point endPoint=task.getDstPoint();
            endPoint.setStatus(BaseStatus.FREE);
            pointRepository.save(endPoint);
            // 解绑容器（MO票，库位）
            CompletableFuture.runAsync(() -> {

//                returnIssue(task);// 叫料结果回传
            });
        }
    }

    public void cancelAgvTasks(String id) {
        AgvTask agvTask = agvTaskRepository.getById(Integer.valueOf(id));
        if (!agvTask.getStatus().equals(BizStatus.FINISH)) {
            agvTask.setStatus(BizStatus.CANCEL);
            agvTask.setEndTime(new Timestamp(new Date().getTime()));
            agvTaskService.update(agvTask);
            /* 取消Task*//*
            List<Task> taskList=taskRepository.getAgvTaskList(agvTask.getId());
            for (Task task:taskList){
                task.setTaskStatus(BizStatus.CANCEL);
                taskRepository.save(task);
                if (task.getInvId()!=null) {
                    *//* 退回库存*//*
                    Inventory inventory = inventoryRepository.getById(task.getInvId());
                    inventory.setQueuedQty(0d);
                    inventoryRepository.save(inventory);
                }
            }*/
        }
    }

    public Task getFirstTask(Integer agvTaskId) {
        List<Task> taskList = taskRepository.getAgvTaskList(agvTaskId);
        return taskList.isEmpty() ? null : taskList.get(0);
    }


    /**
     * 回传MO信息
     *
     * @param billCode
     */
    public void returnMo(String billCode) {

        OrderDto orderDto = orderService.findByBarcodeNumber(billCode);
        if (orderDto == null) {
            throw new RuntimeException("系统无此送货单号: " + billCode);
        }
        double receivedQty = agvTaskService.queryBillCodeSum(billCode);
        if (receivedQty == orderDto.getDeliveryQty()) {
            List<Task> tasks = taskService.findByBillCode(billCode);
            ReturnMoInfo returnMoInfo = getReturnMoInfo(tasks);
            long startTime = System.currentTimeMillis();
            //调用接口
            String resultJson = mlsService.returnMo(returnMoInfo);
            long endTime = System.currentTimeMillis();
            long time = endTime - startTime;
            // 保存日志
            logService.saveLogInfo(returnMoInfo, UrlApi.publicApi, resultJson, "按MO票入库", time, "INFO");
        }


    }

    /**
     * 叫料结果回传
     *
     * @param task
     */
    public void returnIssue(@RequestBody Task task) {

        ReturnIssueInfo returnIssueInfo = getReturnIssueInfo(task);
        long startTime = System.currentTimeMillis();
        String resultJson = mlsService.returnIssue(returnIssueInfo);
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        // 保存日志
        logService.saveLogInfo(returnIssueInfo, UrlApi.publicApi, resultJson, "叫料结果回传", time, "INFO");
    }


    public static ReturnMoInfo getReturnMoInfo(List<Task> tasks) {
        ReturnMoParams params = new ReturnMoParams();
        params.setOrgId(808);
        params.setInvCode("MA2111");
        Set<String> labelNos = new HashSet<>();
        for (Task task : tasks) {
            ItemKey itemKey = task.getItemKey();
            labelNos.add(itemKey.getPropC1());
        }
        params.setLabelNos(labelNos);
        ReturnMoInfo returnMoInfo = new ReturnMoInfo();
        returnMoInfo.setIfaceCode("MLS-WQ-004");
        returnMoInfo.setSourceSystem("WQ");
        returnMoInfo.setParams(params);
        return returnMoInfo;
    }

    public static ReturnIssueInfo getReturnIssueInfo(Task task) {
        ReturnIssueInfoParams params = new ReturnIssueInfoParams();
        params.setOrgId(808);
        params.setTaskNumber(task.getPickDetail().getPropC2());
        Set<String> labelNos = new HashSet<>();
        labelNos.add(task.getItemKey().getPropC1());
        params.setLabelNo(labelNos);
        ReturnIssueInfo returnIssueInfo = new ReturnIssueInfo();
        returnIssueInfo.setIfaceCode("WMS-MLS-035");

        returnIssueInfo.setSourceSystem("WMS");
        returnIssueInfo.setParams(params);
        return returnIssueInfo;
    }


}
