package com.prolog.upcloud.base.wh.operate.controller;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSONObject;
import com.prolog.common.RestMsgHelper;
import com.prolog.cs.biz.outbound.model.dto.InfTaskOutBackDTO;
import com.prolog.entity.vo.*;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.inte.EisHandler;
import com.prolog.inte.WmsHandler;
import com.prolog.upcloud.base.wh.operate.service.InterfacePlatform;
import com.prolog.upcloud.base.wh.operate.service.InvCheckService;
import com.prolog.upcloud.base.wh.operate.service.MoveService;
import com.prolog.upcloud.base.wh.operate.utils.EisLogHelper;
import com.prolog.upcloud.base.wh.operate.vo.WmsInvCheckUpdateVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.prolog.constant.EisInterfaceConstant.COMPLETE_TASK;
import static com.prolog.framework.common.message.RestMessage.doSuccess;

@Api(tags = "提供外部接口调用API")
@RestController
@RequestMapping("/wms/v1.0")
public class ExternalController {

    @Resource
    private MoveService moveService;
    @Resource
    private InvCheckService invCheckService;

    @Resource
    private WmsHandler wmsHandler;
    @Resource
    private EisHandler eisHandler;
    @Resource
    private EisLogHelper eisLogHelper;
    @Resource
    private InterfacePlatform ip;
    @Resource
    private StringRedisTemplate template;

    /**
     * agv移库上架回传
     */
    @ApiOperation("agv移库上架回传")
    @PostMapping("/agv/inReceive")
    public RestMessage<Object> inReceive(Map<String, Object> map) {
        return RestMessage.newInstance(true, "inReceive", moveService.inReceive(map));
    }

    /**
     * agv移库下架回传
     */
    @ApiOperation("agv移库下架回传")
    @PostMapping("/agv/outReceive")
    public RestMessage<Object> outReceive(Map<String, Object> map) {
        return RestMessage.newInstance(true, "outReceive", moveService.outReceive(map));
    }

    /**
     * agv盘点单回传
     */
    @ApiOperation("agv盘点单回传")
    @PostMapping("/agv/countSheetReceive")
    public RestMessage<Object> countSheetReceive(Map<String, Object> map) {
        return RestMessage.newInstance(true, "countSheetReceive", invCheckService.countSheetReceive(map));
    }

    @ApiOperation("EIS出库任务推送")
    @PostMapping("/eis/outBoundRequest")
    public RestMessage<Object> outBoundRequest(@RequestBody List<OutBoundRequestVO> list) {
        return RestMsgHelper.run(() -> eisHandler.outBoundRequest(list));
    }

    @ApiOperation("WMS作业完成确认接口")
    @PostMapping("/eis/operationComplete")
    public RestMessage<Object> operationComplete(@RequestBody List<OperationCompleteVO> list) {
        return RestMsgHelper.run(() -> eisHandler.operationComplete(list));
    }

    @ApiOperation(value = "出库任务回告")
    @PostMapping("/eis/outboundTaskCallback")
    public RestMessage<Object> outboundTaskCallback(@RequestBody List<OutboundTaskCallbackVO> list) {
        return RestMsgHelper.run(() -> wmsHandler.outboundTaskCallback(list));
    }

    @ApiOperation(value = "出库复核结果回传")
    @PostMapping("/eis/outboundCheckResultCallback")
    public RestMessage<Object> outboundCheckResultCallback(@RequestBody OutboundCheckResultCallbackVO vo) {
        return RestMsgHelper.run(() -> wmsHandler.outboundCheckResultCallback(vo));
    }

    @ApiOperation(value = "EIS作业完成回告")
    @PostMapping("/eis/completeTask")
    public RestMessage<Object> completeTask(@RequestBody List<CompleteTaskVO> list) {
        return RestMsgHelper.runAndGet(() -> eisLogHelper.handleAndSaveLog(() -> {
            Map<String, Object> map = wmsHandler.completeTask(list);
            return map;
        }, JSONObject.toJSONString(list), COMPLETE_TASK));
    }

    @ApiOperation(value = "EIS命中回告")
    @PostMapping("/eis/mark")
    public RestMessage<Object> markTask(@RequestBody MarkTaskVO vo) {
        try {
            MarkTaskVO result = wmsHandler.markTask(vo);
            return doSuccess(result);
        }catch (Exception e){
            e.printStackTrace();
            return RestMessage.doError(e.getMessage());
        }
    }

    @ApiOperation(value = "容器借道任务回告")
    @PostMapping("/eis/containerTailgatingFeedback")
    public RestMessage<Object> containerTailgatingFeedback(@RequestBody ContainerTailgatingFeedbackVO vo) {
        return RestMsgHelper.run(() -> wmsHandler.containerTailgatingFeedback(vo));
    }

    @ApiOperation(value = "订单绑定格口反馈")
    @PostMapping("/eis/orderBindingGridFeedback")
    public RestMessage<Object> orderBindingGridFeedback(@RequestBody OrderBindingGridFeedbackVO vo) {
        return RestMsgHelper.run(() -> wmsHandler.orderBindingGridFeedback(vo));
    }

    @ApiOperation(value = "申请面单打印")
    @PostMapping("/eis/applyForDocumentPrinting")
    public RestMessage<Object> applyForDocumentPrinting(@RequestBody ApplyForDocumentPrintingVO vo) {
        return RestMsgHelper.run(() -> wmsHandler.applyForDocumentPrinting(vo));
    }

    @ApiOperation(value = "包裹称重请求分配")
    @PostMapping("/eis/applyForPackageWeigh")
    public RestMessage<Object> applyForPackageWeigh(@RequestBody ApplyForPackageWeighVO vo) {
        return RestMsgHelper.runAndGet(() -> wmsHandler.applyForPackageWeigh(vo));
    }

    @ApiOperation(value = "鹰江盘点出库任务回告")
    @PostMapping("/eis/invCheckOutBack")
    public RestMessage<Object> invCheckOutBack(@RequestBody List<InfTaskOutBackDTO> backDTOList) {
        for (InfTaskOutBackDTO vo : backDTOList) {
            invCheckService.invCheckOutBack(vo);
            if (vo.getWmslocationCode().contains("AGVHJ")) {
                //货架库回传
                List<WmsInvCheckUpdateVO> list = new ArrayList<>();
                WmsInvCheckUpdateVO updateVO = new WmsInvCheckUpdateVO();
                updateVO.setCheckLineId(vo.getSeqNo());
                updateVO.setPieceQuantityFact(vo.getCountQty());
                updateVO.setPieceQuantityAccount(vo.getTotalInventoryQty());
                updateVO.setOddQuantityFact(vo.getCountQty());
                updateVO.setCaseQuantityFact(BigDecimal.ZERO);
                updateVO.setType("1");
                list.add(updateVO);
                //盘点单保存生成差异
                invCheckService.updateInvCheck(list);
            }
        }
        return doSuccess(null);
    }

    @ApiOperation(value = "获取ERP的TOKEN", notes = "isForce=1;(强制刷新)")
    @GetMapping("/erp/getToken")
    public RestMessage<Object> getToken(String isForce) {
        return RestMsgHelper.runAndGet(() -> {

            final String ERP_TOKEN = "ERP_TOKEN";

            ValueOperations<String, String> ops = template.opsForValue();

            if ("1".equals(isForce)) {
                return getTokenByIp(ops, ERP_TOKEN);
            }

            Object o = ops.get(ERP_TOKEN);
            if (o != null) {
                return o;
            }
            return getTokenByIp(ops, ERP_TOKEN);
        });
    }

    private String getTokenByIp(ValueOperations<String, String> ops, String ERP_TOKEN) {
        RestMessage msg = ip.call("/erp/getToken", null);
        Assert.notNull(msg, "获取ERP请求TOKEN失败，请稍候再试");
        if (!"1".equals(msg.getCode())) {
            throw new ParameterException(msg.getMessage());
        }
        JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(msg.getData()));
        String token = json.getString("access_token");
        Assert.notEmpty(token, "获取ERP请求TOKEN失败，token为空");

//        String expiresIn = json.getString("expires_in");
        ops.set(ERP_TOKEN, token, 1, TimeUnit.DAYS);
        return token;
    }

}
