package com.prolog.eis.controller.pda;

import cn.hutool.core.util.StrUtil;
import com.prolog.eis.dto.outbound.GirdScanReqDto;
import com.prolog.eis.dto.outbound.GirdScanRespDto;
import com.prolog.eis.dto.page.*;
import com.prolog.eis.service.out.ParcelRecordService;
import com.prolog.eis.service.page.PdaService;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.utils.AssertUtils;
import com.prolog.fx.inf.core.InterfaceType;
import com.prolog.fx.inf.core.annotation.InterfaceMethod;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

@Slf4j
@RestController
@Validated
@RequestMapping("/api/v1/pda")
@RequiredArgsConstructor
@Api(tags = "PDA接口服务")
public class PdaController {

    private final PdaService pdaService;

    private final ParcelRecordService parcelRecordService;


    @GetMapping(value = "/dismantlePickingList")
    @ApiOperation(value = "拆零总拣列表", notes = "拆零总拣列表")
    @InterfaceMethod(key = "dismantlePickingList", name = "拆零总拣列表", type = InterfaceType.Receive)
    public RestMessage<List<DismantlePickingListDto>> dismantlePickingList(@RequestParam("containerNo") String containerNo) {
        try {
            return RestMessage.newInstance(true, "200", "查询成功", pdaService.dismantlePickingTaskList(containerNo));
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "查询失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/dismantlePickingDetail")
    @ApiOperation(value = "拆零总拣详情", notes = "拆零总拣详情")
    @InterfaceMethod(key = "dismantlePickingDetail", name = "拆零总拣详情", type = InterfaceType.Receive)
    public RestMessage<DismantlePickingDetailDto> dismantlePickingDetail(@RequestParam("containerSubNo") String containerSubNo, @RequestParam("eisWaveNo") String eisWaveNo) {
        try {
            return RestMessage.newInstance(true, "200", "查询成功", pdaService.dismantlePickingTaskDetail(containerSubNo, eisWaveNo));
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "查询失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/dismantlePickingConfirm")
    @ApiOperation(value = "拆零总拣确认", notes = "拆零总拣确认")
    @InterfaceMethod(key = "dismantlePickingConfirm", name = "拆零总拣确认", type = InterfaceType.Receive)
    public RestMessage dismantlePickingConfirm(@RequestBody @Valid DismantleConfirmReqDto req) {
        try {
            pdaService.dismantlePickingConfirm(req);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            e.printStackTrace();
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }


    @GetMapping(value = "/dismantleFullDetail")
    @ApiOperation(value = "拆零零发整详情", notes = "拆零零发整详情")
    @InterfaceMethod(key = "dismantleFullDetail", name = "拆零零发整详情", type = InterfaceType.Receive)
    public RestMessage<List<DismantleFullDetailDto>> dismantleFullDetail(@RequestParam("containerNo") String containerNo) {
        try {
            return RestMessage.newInstance(true, "200", "查询成功", pdaService.dismantleFullDetail(containerNo));
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "查询失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/dismantleFullConfirm")
    @ApiOperation(value = "拆零零发整确认", notes = "拆零零发整确认")
    @InterfaceMethod(key = "dismantleFullConfirm", name = "拆零零发整确认", type = InterfaceType.Receive)
    public RestMessage dismantleFullConfirm(@RequestBody @Valid DismantleConfirmReqDto req) {
        try {
            pdaService.dismantleFullConfirm(req);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            e.printStackTrace();
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/packOrder")
    @ApiOperation(value = "理货打包扫描", notes = "理货打包扫描")
    @InterfaceMethod(key = "packOrder", name = "理货打包扫描", type = InterfaceType.Receive)
    public RestMessage<PackOrderInfoDto> packOrder(@RequestParam("gridNo") String gridNo) {
        try {
            return RestMessage.newInstance(true, "200", "操作成功", pdaService.packOrder(gridNo));
        } catch (Exception e) {
            log.error("理货打包扫描失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/unpacking")
    @ApiOperation(value = "拆箱", notes = "拆箱")
    @InterfaceMethod(key = "unpacking", name = "拆箱", type = InterfaceType.Receive)
    public RestMessage unpacking(@RequestBody @Valid UnpackingDto req) {
        try {
            pdaService.unpacking(req);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            log.error("拆箱失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/tagPrint")
    @ApiOperation(value = "标签打印", notes = "标签打印")
    @InterfaceMethod(key = "tagPrint", name = "标签打印", type = InterfaceType.Receive)
    public RestMessage tagPrint(@RequestParam("id") Integer id, @RequestParam("gridNo") String gridNo) {
        try {
            if (Objects.isNull(id)) {
                return RestMessage.newInstance(false, "500", "操作失败：订单id不能为空", null);
            }
            if (StrUtil.isBlank(gridNo)) {
                return RestMessage.newInstance(false, "500", "操作失败：格口号不能为空", null);
            }
            pdaService.tagPrint(id, gridNo);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            log.error("标签打印失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/packOrderDetail")
    @ApiOperation(value = "理货打包详情", notes = "理货打包详情")
    @InterfaceMethod(key = "packOrderDetail", name = "理货打包详情", type = InterfaceType.Receive)
    public RestMessage<PackOrderRespDto> packOrderDetail(@RequestBody @Valid PackOrderDetailReqDto req) {
        try {
            return RestMessage.newInstance(true, "200", "操作成功", pdaService.packOrderDetail(req, 1));
        } catch (Exception e) {
            log.error("理货打包详情失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/handDetail")
    @ApiOperation(value = "人工复核详情", notes = "人工复核详情")
    @InterfaceMethod(key = "handDetail", name = "人工复核详情", type = InterfaceType.Receive)
    public RestMessage<PackOrderRespDto> handDetail(@RequestBody @Valid PackOrderDetailReqDto req) {
        try {
            return RestMessage.newInstance(true, "200", "操作成功", pdaService.packOrderDetail(req, 0));
        } catch (Exception e) {
            log.error("人工复核详情失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/handOfferScan")
    @ApiOperation(value = "人工复核扫描", notes = "人工复核扫描")
    @InterfaceMethod(key = "handOfferScan", name = "人工复核扫描", type = InterfaceType.Receive)
    public RestMessage handOfferScan(@RequestBody @Valid PackOrderDetailReqDto req) {
        try {
            AssertUtils.isNotNull(req.getCode(), "商品条码不能为空");
            pdaService.handOfferScan(req);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            log.error("人工复核扫描失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/packOrderFinish")
    @ApiOperation(value = "理货打包扫描完成", notes = "理货打包扫描完成")
    @InterfaceMethod(key = "packOrderFinish", name = "理货打包扫描完成", type = InterfaceType.Receive)
    public RestMessage packOrderFinish(@RequestParam("id") Integer id, @RequestParam("gridNo") String gridNo) {
        try {
            if (Objects.isNull(id)) {
                return RestMessage.newInstance(false, "500", "操作失败：订单id不能为空", null);
            }
            if (StrUtil.isBlank(gridNo)) {
                return RestMessage.newInstance(false, "500", "操作失败：格口号不能为空", null);
            }
            pdaService.packOrderFinish(id, gridNo);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            log.error("理货打包扫描完成失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/packOrderLack")
    @ApiOperation(value = "理货打包确认缺货", notes = "理货打包确认缺货")
    @InterfaceMethod(key = "packOrderLack", name = "理货打包确认缺货", type = InterfaceType.Receive)
    public RestMessage packOrderLack(@RequestParam("id") Integer id) {
        try {
            pdaService.packOrderLack(id);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            log.error("理货打包确认缺货失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/checkOrderGridFinish")
    @ApiOperation(value = "理货打包订单校验是否复核", notes = "理货打包订单校验是否复核")
    @InterfaceMethod(key = "checkOrderGridFinish", name = "理货打包订单校验是否复核", type = InterfaceType.Receive)
    public RestMessage<List<PackOrderCheckRespDto>> checkOrder(@RequestParam("id") Integer id, @RequestParam("gridNo") String gridNo) {
        try {
            if (Objects.isNull(id)) {
                return RestMessage.newInstance(false, "500", "操作失败：订单id不能为空", null);
            }
            if (StrUtil.isBlank(gridNo)) {
                return RestMessage.newInstance(false, "500", "操作失败：格口号不能为空", null);
            }
            return RestMessage.newInstance(true, "200", "操作成功", pdaService.checkOrder(id, gridNo));
        } catch (Exception e) {
            log.error("理货打包订单校验是否复核失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/itemSuperviseCheck")
    @ApiOperation(value = "理货打包药监码校验", notes = "理货打包药监码校验")
    @InterfaceMethod(key = "itemSuperviseCheck", name = "理货打包药监码校验", type = InterfaceType.Receive)
    public RestMessage<String> itemSuperviseCheck(@RequestBody PackOrderItemSuperviseDto req) {
        try {
            return RestMessage.newInstance(true, "200", "操作成功", pdaService.itemSuperviseCheck(req));
        } catch (Exception e) {
            log.error("理货打包药监码校验：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/itemSupervise")
    @ApiOperation(value = "理货打包药监码采集", notes = "理货打包药监码采集")
    @InterfaceMethod(key = "itemSupervise", name = "理货打包药监码采集", type = InterfaceType.Receive)
    public RestMessage itemSupervise(@RequestBody PackOrderItemSuperviseDto req) {
        try {
            pdaService.itemSupervise(req);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            log.error("理货打包药监码采集失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/packOrderGridFinish")
    @ApiOperation(value = "理货打包全部落格", notes = "理货打包全部落格")
    @InterfaceMethod(key = "packOrderGridFinish", name = "理货打包全部落格", type = InterfaceType.Receive)
    public RestMessage packOrderGridFinish(@RequestParam("id") Integer id, @RequestParam("gridNo") String gridNo) {
        try {
            if (Objects.isNull(id)) {
                return RestMessage.newInstance(false, "500", "操作失败：订单id不能为空", null);
            }
            if (StrUtil.isBlank(gridNo)) {
                return RestMessage.newInstance(false, "500", "操作失败：格口号不能为空", null);
            }
            pdaService.packOrderGridFinish(id, gridNo);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            log.error("理货打包全部落格失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/sourceMergeContainerScan")
    @ApiOperation(value = "原托盘合托任务扫码", notes = "原托盘合托任务扫码")
    @InterfaceMethod(key = "sourceMergeContainerScan", name = "原托盘合托任务扫码", type = InterfaceType.Receive)
    public RestMessage<MergeContainerListRespDto> sourceMergeContainerScan(@RequestParam("containerNo") String containerNo) {
        try {
            AssertUtils.isNotNull(containerNo, "请扫描容器");
            return RestMessage.newInstance(true, "200", "操作成功", pdaService.sourceMergeContainerScan(containerNo));
        } catch (Exception e) {
            log.error("原托盘合托任务扫码失败：{}", e.getMessage(), e);
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/targetMergeContainerScan")
    @ApiOperation(value = "目标盘合托任务扫码", notes = "目标盘合托任务扫码")
    @InterfaceMethod(key = "targetMergeContainerScan", name = "目标盘合托任务扫码", type = InterfaceType.Receive)
    public RestMessage targetMergeContainerScan(@RequestParam("sourceContainerNo") String sourceContainerNo, @RequestParam("targetContainerNo") String targetContainerNo) {
        try {
            AssertUtils.isNotNull(targetContainerNo, "请扫描容器");
            AssertUtils.isNotNull(sourceContainerNo, "原托盘号不能为空");
            pdaService.targetMergeContainerScan(sourceContainerNo, targetContainerNo);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/mergeContainerDetail")
    @ApiOperation(value = "合托任务详情", notes = "合托任务详情")
    @InterfaceMethod(key = "mergeContainerDetail", name = "合托任务详情", type = InterfaceType.Receive)
    public RestMessage<MergeContainerDetailDto> mergeContainerDetail(@RequestParam("containerNo") String containerNo) {
        try {
            AssertUtils.isNotNull(containerNo, "容器号不能为空");
            return RestMessage.newInstance(true, "200", "操作成功", pdaService.mergeContainerDetail(containerNo));
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @GetMapping(value = "/mergeContainerBack")
    @ApiOperation(value = "合托回库", notes = "合托回库")
    @InterfaceMethod(key = "mergeContainerBack", name = "合托回库", type = InterfaceType.Receive)
    public RestMessage<MergeContainerDetailDto> mergeContainerBack(@RequestParam("containerNo") String containerNo) {
        try {
            AssertUtils.isNotNull(containerNo, "容器号不能为空");
            pdaService.mergeContainerBack(containerNo);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/mergeContainerConfirm")
    @ApiOperation(value = "合托确认", notes = "合托确认")
    @InterfaceMethod(key = "mergeContainerConfirm", name = "合托确认", type = InterfaceType.Receive)
    public RestMessage mergeContainerConfirm(@RequestBody MergeContainerConfirmDto req) {
        try {
            pdaService.mergeContainerConfirm(req);
            return RestMessage.newInstance(true, "200", "操作成功", null);
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }

    @PostMapping(value = "/scanGrid")
    @ApiOperation(value = "扫描格口", notes = "扫描格口")
    @InterfaceMethod(key = "scanGrid", name = "扫描格口", type = InterfaceType.Receive)
    public RestMessage<GirdScanRespDto> scanGrid(@RequestBody GirdScanReqDto reqDto) {
        try {
            GirdScanRespDto girdScanRespDto;
            synchronized (reqDto.getGridNo().trim()) {
                girdScanRespDto = parcelRecordService.scanGrid(reqDto);
            }
            return RestMessage.newInstance(true, "200", "操作成功", girdScanRespDto);
        } catch (Exception e) {
            return RestMessage.newInstance(false, "500", "操作失败" + e.getMessage(), null);
        }
    }
}
