package com.prolog.cs.biz.outbound.controller;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import com.prolog.common.RestMsgHelper;
import com.prolog.cs.basic.common.model.print.PrintParam;
import com.prolog.cs.biz.outbound.dao.BarcodeHMapper;
import com.prolog.cs.biz.outbound.model.dto.WavesCreateDTO;
import com.prolog.cs.biz.outbound.model.dto.check.OuterCheckBarcodeDetailDTO;
import com.prolog.cs.biz.outbound.model.dto.check.OuterTaskV2DTO;
import com.prolog.cs.biz.outbound.model.entity.BarcodeHDO;
import com.prolog.cs.biz.outbound.model.entity.WmsFaceOrder;
import com.prolog.cs.biz.outbound.model.vo.check.OutCheckSupervisionCodeVO;
import com.prolog.cs.biz.outbound.model.vo.check.OuterTaskVO;
import com.prolog.cs.biz.outbound.service.PickTaskAppService;
import com.prolog.cs.biz.outbound.service.PrintLogService;
import com.prolog.cs.biz.outbound.service.impl.PickTaskAppServiceImpl;
import com.prolog.cs.biz.outbound.service.impl.WorkStageServiceImpl;
import com.prolog.cs.biz.outbound.service.impl.faceorder.EmsFaceOrderHandler;
import com.prolog.cs.biz.outbound.service.impl.faceorder.JdFaceOrderHandler;
import com.prolog.cs.biz.outbound.service.impl.faceorder.JdKyFaceOrderHandler;
import com.prolog.cs.biz.outbound.service.impl.faceorder.YdFaceOrderHandler;
import com.prolog.cs.biz.outbound.utils.HttpClientUtils;
import com.prolog.entity.vo.ApplyForPackageWeighVO;
import com.prolog.framework.authority.util.HystrixVarUtil;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.log.aop.annotation.UserLog;
import com.prolog.framework.utils.MapUtils;
import com.prolog.framework.utils.StringUtils;
import com.prolog.upcloud.base.inventory.vo.StockWaveResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author zzz
 * @desc
 * @date 2021/4/27
 */
@Slf4j
@Api(tags = "app-拣选任务")
@RestController
@RequestMapping("/rf/outcheck")
public class RFOutCheckController {

    @Autowired
    private PickTaskAppService pickTaskAppService;

    @Autowired
    private PickTaskAppServiceImpl pickTaskAppServiceImpl;

    @Autowired
    private BarcodeHMapper barcodeHMapper;

    @Autowired
    com.prolog.cs.biz.outbound.service.impl.WorkStageServiceImpl WorkStageServiceImpl;
    @Autowired
    private JdFaceOrderHandler jdFaceOrderHandler;
    @Autowired
    private EmsFaceOrderHandler emsFaceOrderHandler;
    @Autowired
    private JdKyFaceOrderHandler jdKyFaceOrderHandler;
    @Autowired
    private PrintLogService printLogService;

    @UserLog
    @ApiOperation(value = "外复核-待索取任务订单列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "barcode", value = "标签号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "bldgId", value = "建筑物id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "warehouseId", value = "仓id", required = true, dataType = "String")
    })
    @GetMapping("/outercheck-unask")
    public RestMessage<OuterTaskV2DTO> outerCheckUnAskV2(String barcode, String bldgId, String warehouseId){
        OuterTaskV2DTO result = pickTaskAppService.outerCheckUnAskV2(barcode,bldgId,warehouseId);
        return RestMessage.success("操作成功", result);
    }

    @UserLog
    @ApiOperation(value = "外复核-确认")
    @PostMapping("/outercheck-confirm")
    public RestMessage<Map<String, Object>> outerCheckConfirmV2(@RequestBody OuterTaskVO vo){
        Map<String, Object> map = pickTaskAppService.outerCheckConfirmV2(vo);
        Object o = map.get("printInvoiceData");
        if(o != null){
            ServletRequestAttributes reqa = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            new Thread(()-> {
                RequestContextHolder.setRequestAttributes(reqa, false);
                ServletRequestAttributes servletRequestAttributes =
                        (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
                String userkey = servletRequestAttributes.getRequest().getHeader("UserKey");

                if (!HystrixRequestContext.isCurrentThreadInitialized()) {
                    HystrixRequestContext.initializeContext();
                }
                HystrixVarUtil.setUserKey(userkey);
                try {
                    RestMessage<?> restMessage = pickTaskAppService.print((List<PrintParam>) (o));
                    //保存打印日志
                    printLogService.save(map.get("billNo").toString(),"invoice",restMessage.isSuccess());
                }catch (Exception e) {
                    log.error("打印发票失败：{}", e.getMessage());
                }finally {
                    RequestContextHolder.resetRequestAttributes();
                }
            }).start();

        }
        String message = "操作成功";
        Object msg = map.get("msg");
        if(msg != null){
            message = (String) msg;
        }
        log.info("outerCheckConfirmV2 end:{}",System.currentTimeMillis());
        return RestMessage.success(message, map);
    }

    @UserLog
    @ApiOperation(value = "外复核-扫描客户监管码")
    @PostMapping("/scanSupervisionCode")
    public RestMessage scanSupervisionCode(@RequestBody OutCheckSupervisionCodeVO vo){
        pickTaskAppService.scanSupervisionCode(vo);
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "包裹称重请求分配（MCS->WMS)")
    @PostMapping("/applyForPackageWeigh")
    public RestMessage<Map<String, Object>> applyForPackageWeigh(@RequestBody ApplyForPackageWeighVO vo) {
        return RestMsgHelper.runAndGet(() -> pickTaskAppService.applyForPackageWeigh(vo));
    }

    @UserLog
    @ApiOperation(value = "打印面单")
    @GetMapping("/printFaceOrder")
    public RestMessage printFaceOrder(@RequestParam("faceOrder") String faceOrder,@RequestParam("consignorId") String consignorId,@RequestParam("warehouseId") String warehouseId,@RequestParam("carrierCode") String carrierCode) {
        List<PrintParam> printParams =  pickTaskAppService.getPrintFaceOrder(faceOrder,consignorId,warehouseId,carrierCode);
        pickTaskAppService.print(printParams);
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "打印标签")
    @GetMapping("/printBarcode")
    public RestMessage printBarcode(@RequestParam("barCode") String barCode,@RequestParam("consignorId") String consignorId,@RequestParam("warehouseId") String warehouseId) {
        pickTaskAppServiceImpl.printBarcodes(CollUtil.toList(barCode),consignorId,warehouseId,"");
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "打印出库清单")
    @GetMapping("/printOubDetail")
    public RestMessage printOubDetail(@RequestParam("billId") String billId,@RequestParam("consignorId") String consignorId,@RequestParam("warehouseId") String warehouseId) {
        pickTaskAppServiceImpl.printOutDetailList(billId,consignorId,warehouseId,"1");
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "打印发票")
    @GetMapping("/printInvoice")
    public RestMessage printInvoice(@RequestParam("billId") String billId,@RequestParam("consignorId") String consignorId,@RequestParam("warehouseId") String warehouseId) {
        pickTaskAppServiceImpl.printInvoice(billId,consignorId,warehouseId);
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "打印质检报告单")
    @GetMapping("/printQrReport")
    public RestMessage printQrReport(@RequestParam("billId") String billId,@RequestParam("consignorId") String consignorId,@RequestParam("warehouseId") String warehouseId) {
        pickTaskAppServiceImpl.printQrReport(billId,consignorId,warehouseId);
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "打印首营资料")
    @GetMapping("/printSyInfo")
    public RestMessage printSyInfo(@RequestParam("billId") String billId,@RequestParam("consignorId") String consignorId,@RequestParam("warehouseId") String warehouseId) {
        pickTaskAppServiceImpl.printSyInfo(billId,consignorId,warehouseId);
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "测试组包")
    @PostMapping("/testWavesCreate")
    public void testWavesCreate(@RequestBody StockWaveResultVO waveResult) throws Exception {
        WorkStageServiceImpl.handle(waveResult,true);
    }

    @UserLog
    @ApiOperation(value = "测试获取京东面单")
    @PostMapping("/testJdFaceOrder")
    public List<WmsFaceOrder> testJdFaceOrder(@RequestBody Map<String,Object> map) throws Exception {
        String url = "http://integration.upcloud.prolog.org/api/shili/jdky/yyld-test";
        String param = JSON.toJSONString(map);
        JSONObject result = HttpClientUtils.postByJson(url, param);
        List<WmsFaceOrder> wmsFaceOrders = jdKyFaceOrderHandler.convertResult(result,null);
        return  wmsFaceOrders;
    }

    @UserLog
    @ApiOperation(value = "测试获取EMS面单")
    @PostMapping("/testEmsFaceOrder")
    public List<WmsFaceOrder> testEmsFaceOrder(@RequestBody Map<String,Object> map) throws Exception {
        String url = "http://integration.upcloud.prolog.org/api/shili/yzkd";
        String param = JSON.toJSONString(map);
        JSONObject result = HttpClientUtils.postByJson(url, param);
        return emsFaceOrderHandler.convertResult(result);

    }


    @UserLog
    @ApiOperation(value = "复核明细")
    @GetMapping("/getBarcodeDetail")
    public RestMessage<List<OuterCheckBarcodeDetailDTO>> getBarcodeDetail(@RequestParam("barCode") String barCode, @RequestParam("warehouseId") String warehouseId) {
        List<OuterCheckBarcodeDetailDTO> result =  pickTaskAppService.getBarcodeDetail(barCode,warehouseId);
        return RestMessage.success("操作成功", result);
    }

    @UserLog
    @ApiOperation(value = "回写回告erp中间表定时任务")
    @PostMapping("/retryCallbackToERPByTable")
    public void retryCallbackToERPByTable() {
        pickTaskAppService.retryCallbackToERPByTable();
    }


    @UserLog
    @ApiOperation(value = "自动外复核-确认")
    @PostMapping("/auto/outercheck-confirm")
    public RestMessage autoOuterCheckConfirm(){
        pickTaskAppService.autoOuterCheckConfirm();
        return RestMessage.success("操作成功", null);
    }

}
