package com.youchain.businessdata.rest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.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.scheduling.annotation.Async;
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.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK;

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

    private final AgvTaskService agvTaskService;
    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) {
        String id = missionStateCallback.getMissionCode();//作业 id
        String containerCode = missionStateCallback.getContainerCode();//容器编号
        String missionStatus = missionStateCallback.getMissionStatus();//作业当前状态
        try {
            //料箱任务
            AgvTaskDto agvTaskDto = agvTaskService.findById(Integer.parseInt(id));
            AgvTask agvTask = agvTaskService.toEntity(agvTaskDto);//转实体
            List<Task> taskList = taskRepository.getAgvTaskList(agvTask.getId());
            if (taskList.isEmpty()) {
                return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "任务不存在!", ""), BAD_REQUEST);
            }
            Task task = taskList.get(0);
            agvTaskService.agvTaskCallback(agvTask, task, missionStatus);
            //回传
            if (agvTask.getType().equals(BizStatus.ASN)) {
                returnMo(task.getItemKey().getOrderNumber());
            } else if (agvTask.getType().equals(BizStatus.PICK)) {
                returnIssue(task);
            }
            return new ResponseEntity<>(ApiResult.success(OK.value(), "", ""), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), "KMReS接口回调异常", e.getMessage()), BAD_REQUEST);
        }

    }

    /**
     * 回传MO信息
     *
     * @param orderNumber
     */
    public void returnMo(String orderNumber) {
        OrderDto orderDto = orderService.findByBarcodeNumber(orderNumber);

        if (orderDto == null) {
            throw new RuntimeException("系统无此送货单号: " + orderNumber);
        }

        double receivedQty = agvTaskService.queryOrderNumberSum(orderNumber);
        if (receivedQty == orderDto.getReceivedQty()) {
            List<Task> tasks = taskService.findByOrderNumber(orderNumber);
            ReturnMoInfo returnMoInfo = getReturnMoInfo(tasks);
            long startTime = System.currentTimeMillis();
            //调用接口
            String resultJson = mlsService.returnMo(returnMoInfo);
            long endTime = System.currentTimeMillis();
            long time = endTime - startTime;

            JSONObject resulObject = JSON.parseObject(resultJson);
            if (resulObject == null) {
                throw new RuntimeException("按MO票入库接口返回数据为空!");
            }

            // 保存日志
            saveLogInfo(returnMoInfo, resultJson, "按MO票入库", time);
        }
    }

    /**
     * 叫料结果回传
     *
     * @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;
        JSONObject resulObject = JSON.parseObject(resultJson);
        if (resulObject == null) {
            throw new RuntimeException("叫料结果回传接口返回数据为空!");
        }
        // 保存日志
        saveLogInfo(returnIssueInfo, resultJson, "叫料结果回传", time);
    }


    public void saveLogInfo(Object object, String resultJson, String description, long time) {
        // 设置日志信息
        com.youchain.domain.Log newlogs = new com.youchain.domain.Log();
        newlogs.setDescription(description);
        newlogs.setLogType("INFO");
        newlogs.setMethod(UrlApi.publicApi);
        newlogs.setParams(JSON.toJSONString(object));
        newlogs.setReturnData(resultJson);
        newlogs.setRequestIp("127.0.0.1");
        newlogs.setTime(time);
        newlogs.setUsername("admin");
        newlogs.setAddress("内网IP");
        newlogs.setBrowser("Chrome 123");
        newlogs.setCreateTime(new Timestamp(new Date().getTime()));
        logService.saveLog(newlogs);
    }

    public static ReturnMoInfo getReturnMoInfo(List<Task> tasks) {
        ReturnMoParams params = new ReturnMoParams();
        params.setOrgId(100059);
        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.getBillCode());
        Set<String> labelNos = new HashSet<>();
        labelNos.add(task.getItemKey().getPropC1());
        params.setLabelNo(labelNos);
        ReturnIssueInfo returnIssueInfo = new ReturnIssueInfo();
        returnIssueInfo.setIfaceCode("MLS-YC-001");
        returnIssueInfo.setSourceSystem("WMS");
        returnIssueInfo.setParams(params);
        return returnIssueInfo;
    }


}
