package com.youchain.businessdata.rest;

import com.youchain.annotation.Log;
import com.youchain.annotation.AnonymousAccess;
import com.youchain.appupdate.inputJson.MissionStateCallback;
import com.youchain.businessdata.domain.AgvTask;
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.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.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 TaskRepository taskRepository;
    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());
        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);
            }
        }
        return ResponseEntity.ok(ApiResult.success(HttpStatus.OK.value(), "", ""));
    }

    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());
        /*if (agvTask.getEndSlotCode().equals(slotCode)){
            missionStatus="PICKER_SEND";
        }*/
        agvTaskService.agvTaskCallback(agvTask, task, missionStatus);

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

    public void pickTask(String id, String containerCode, String missionStatus) {
        if ("CANCELED".equals(missionStatus)) {
            cancelAgvTasks(id);
        } else if ("PICKER_SEND".equals(missionStatus)){
            AgvTask agvTask = agvTaskRepository.getById(Integer.valueOf(id));
            Task task = getFirstTask(agvTask.getId());
            agvTaskService.agvTaskCallback(agvTask, missionStatus, containerCode);

            CompletableFuture.runAsync(() -> {

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

    public void cancelAgvTasks(String id) {
        List<AgvTask> agvTaskList = agvTaskService.findByjobCode(id);
        for (AgvTask agvTask : agvTaskList) {
            if (!agvTask.getStatus().equals(BizStatus.FINISH)) {
                agvTask.setStatus(BizStatus.CANCEL);
                agvTask.setEndTime(new Timestamp(new Date().getTime()));
                agvTaskService.update(agvTask);
            }
        }
    }

    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;
    }


}
