package com.prolog.cs.biz.inbound.controller.rcv;

import java.math.BigDecimal;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.prolog.cs.biz.inbound.dto.rcv.*;
import com.prolog.cs.biz.inbound.model.rcv.RcvLines;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.core.exception.BizException;
import com.prolog.upcloud.base.strategy.model.BusinessControl;
import com.prolog.wms.base.util.JsonMapper;
import io.swagger.annotations.ApiImplicitParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.prolog.cs.biz.inbound.constant.ValidatorGroup.validAdd;
import com.prolog.cs.biz.inbound.dto.CargoChangeIn;
import com.prolog.cs.biz.inbound.dto.PageParam;
import com.prolog.cs.biz.inbound.model.rcv.WmsInRcvTempSave;
import com.prolog.cs.biz.inbound.remote.OmsASNRemoteCallerMock;
import com.prolog.cs.biz.inbound.remote.StrategyClient;
import com.prolog.cs.biz.inbound.remote.dto.OmsAsnBillDQueryVO;
import com.prolog.cs.biz.inbound.remote.dto.OmsAsnBillHQueryVO;
import com.prolog.cs.biz.inbound.service.rcv.RcvHeadersService;
import com.prolog.cs.biz.inbound.utils.ObjectUtils;
import com.prolog.cs.biz.inbound.utils.UserUtils;
import com.prolog.cs.biz.inbound.vo.RcvLineLotInfo;
import com.prolog.cs.biz.inbound.vo.RcvLineSpiltInfo;
import com.prolog.cs.biz.inbound.vo.RcvLinesQueryVO;
import com.prolog.cs.biz.inbound.vo.RcvQueryVO;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.log.aop.annotation.UserLog;
import com.prolog.framework.utils.AssertUtils;
import com.prolog.framework.utils.StringUtils;
import com.prolog.upcloud.base.inventory.vo.BatchNumberListVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description 收货主表 api
 * @Date 2021-03-24
 */
@Slf4j
@Api(tags = "收货(入库)RCV")
@RestController
@RequestMapping("/rcvHeaders/v1.0")
public class RcvHeadersController {

    @Resource
    private RcvHeadersService rcvHeadersService;

    @Resource
    private OmsASNRemoteCallerMock omsASNRemoteCallerMock;

    @Resource
    private UserUtils userUtils;

    @Resource
    private StrategyClient strategyClient;

    @UserLog("wms收货单极联新增")
    @ApiOperation("新增(级联关联表)")
    @PostMapping("/addWithRelated")
    public RestMessage<Object> addWithRelated(@Validated(value = {validAdd.class}) @RequestBody RcvDTO rcvDTO) {
        Object result = rcvHeadersService.addWithRelated(rcvDTO);
        //收货确认，保存到货数量到rcvlines表
        rcvHeadersService.saveItemLotArriveQty(rcvDTO);
        return RestMessage.newInstance(true, "addSuccess", result);
    }

    @UserLog("根据品批查询到货数量")
    @ApiOperation("根据品批查询到货数量")
    @PostMapping("/arriveQtyByItemLot")
    public RestMessage<RcvLines> arriveQtyByItemLot(@RequestBody RcvLinesDTO rcvLinesDTO) {
        return RestMessage.newInstance(true, "查询成功", rcvHeadersService.arriveQtyByItemLot(rcvLinesDTO));
    }


    @UserLog("wms收货暂存")
    @ApiOperation("wms收货暂存")
    @PostMapping("/addWithRelatedTemp")
    @Deprecated
    public RestMessage<Boolean> addWithRelatedTemp(@Validated(value = {validAdd.class}) @RequestBody RcvDTO rcvDTO) {
        return RestMessage.newInstance(true, "success", rcvHeadersService.addWithRelatedTemp(rcvDTO));
    }

    /**
     * 根据主键id查询
     */
    @UserLog("分页获取暂存列表")
    @ApiOperation("分页获取暂存列表")
    @GetMapping("/findWithRelatedTempPage")
    public RestMessage<Page<WmsInRcvTempSave>> findWithRelatedTempPage(WmsInRcvTempSave rcvQueryVO,
                                                                       PageParam pageParam) {
        return RestMessage.newInstance(true, "success",
                rcvHeadersService.findWithRelatedTempPage(rcvQueryVO, pageParam));
    }

    /**
     * 根据主键id查询
     */
    @UserLog("获取暂存明细列表")
    @ApiOperation("分页获取暂存明细列表，返回参数与正常提取明细完全一致")
    @GetMapping("/findItemWithRelatedTemp")
    public RestMessage<Object> findItemWithRelatedTemp(String tempSaveId) {
        return RestMessage.newInstance(true, "success", rcvHeadersService.findItemWithRelatedTemp(tempSaveId));
    }

    @UserLog("根据入库汇总单id查询暂存明细列表")
    @ApiOperation("根据入库汇总单id查询暂存明细列表")
    @GetMapping("/findTobeConfirmed")
    public RestMessage<RcvDTO> findTobeConfirmed(String billId) {
        return RestMessage.newInstance(true,"success",rcvHeadersService.findRcvDtoByBillId(billId));
    }

    @UserLog("删除暂存明细")
    @ApiOperation("删除暂存明细")
    @PostMapping("deleteTobeConfirmed")
    public RestMessage<Boolean> deleteTobeConfirmed(@RequestBody DeleteTobeConfirmed deleteTobeConfirmed){
        return RestMessage.newInstance(true,"success",rcvHeadersService.deleteRcvDByRcvLineId(deleteTobeConfirmed));
    }

    /**
     * 根据主键id查询
     */
    @Deprecated
    @UserLog("获取暂存")
    @ApiOperation("获取暂存")
    @GetMapping("/findWithRelatedTemp")
    public RestMessage<String> findWithRelatedTemp(@RequestParam String warehouseId) {
        return RestMessage.newInstance(true, "success", rcvHeadersService.findWithRelatedTemp(warehouseId));
    }

    /**
     * 根据主键id查询
     */
    @UserLog("获取暂存通过ID")
    @ApiOperation("获取暂存通过ID")
    @GetMapping("/findWithRelatedTempById")
    public RestMessage<String> findWithRelatedTempById(@RequestParam String id) {
        return RestMessage.newInstance(true, "success", rcvHeadersService.findWithRelatedTempById(id));
    }

    /**
     * 条件分页(单主表)
     */
    @UserLog("wms收货单条件分页(单主表)")
    @ApiOperation("条件分页(单主表)")
    @GetMapping("/page")
    public RestMessage<Page<RcvHeadersDTO>> list(RcvQueryVO rcvQueryVO, PageParam pageParam) throws Exception {
        return RestMessage.newInstance(true, "pageSuccess", rcvHeadersService.findList(rcvQueryVO, pageParam));
    }

    /**
     * 条件分页
     */
    @UserLog("wms收货单条件分页(级联附属表)")
    @ApiOperation("条件分页")
    @GetMapping("/pageWithProfile")
    public RestMessage<Page<RcvHDTO>> listWithProfile(RcvQueryVO rcvQueryVO, PageParam pageParam) throws Exception {
        return RestMessage.newInstance(true, "pageSuccess",
                rcvHeadersService.findListWithProfile(rcvQueryVO, pageParam));
    }

    /**
     * 根据主键id查询
     */
    @UserLog("wms收货单详情查看(主键ID查)")
    @ApiOperation("详情(主键ID)")
    @GetMapping("/findByPkId")
    public RestMessage<RcvDTO> findByPkId(@RequestParam(required = true) String pkId) {

        return RestMessage.newInstance(true, "findByPkIdSuccess", rcvHeadersService.findByPkId(pkId));
    }

    /**
     * ASN订单分页
     */
    @UserLog("wms提取Asn订单")
    @ApiOperation("ASN订单分页")
    @PostMapping("/pageASN")
    public RestMessage<Object> pageASN(@RequestBody OmsAsnBillHQueryVO vo) {
        // 需要过滤
        // 1. oms改状态 回调oms asn单改以收货状态
        // 2. oms提供查询id过滤
        // 3. 本身过滤
        return omsASNRemoteCallerMock.queryOmsAsnBillHAudit(vo);
    }

    /**
     * ASN订单明细分页
     */
    @UserLog("wms提取Asn订单明细")
    @ApiOperation("ASN订单明细分页")
    @PostMapping("/pageASNDetails")
    public RestMessage<Object> pageASNDetails(@RequestBody OmsAsnBillDQueryVO vo) {
        // 需要过滤
        // 1. oms改状态 回调oms asn单改以收货状态
        // 2. oms提供查询id过滤
        // 3. 本身过滤
        // 重新构建字段
        return omsASNRemoteCallerMock.queryOmsAsnBillD(vo);
    }

    /**
     * 入库通知单打印 TODO
     */
    @UserLog("入库通知单打印")
    @ApiOperation("入库通知单打印(单据数据不确定,暂未实现)")
    @PostMapping("/getRcvPrintData")
    public RestMessage<Object> getRcvPrintData(@RequestBody RcvLinesQueryVO queryVo) {
        return RestMessage.doSuccess(rcvHeadersService.getRcvPrintData(queryVo));
    }

    /**
     * 获取商品以往的批号
     */
    @UserLog("获取商品以往的批号")
    @ApiOperation(value = "获取商品以往的批号", response = BatchNumberListVO.class)
    @PostMapping("/getRcvItemLotNum")
    public RestMessage<Object> getRcvItemLotNum(@RequestBody RcvLinesQueryVO queryVo) {
        return RestMessage.doSuccess(rcvHeadersService.getRcvItemLotNum(queryVo));
    }

    /**
     * 校验批号,生产日期,有效期
     */
    @UserLog("校验批号,生产日期,有效期")
    @ApiOperation("校验批号,生产日期,有效期")
    @PostMapping("/vaildateRcvItemLotNum")
    public RestMessage<Object> vaildateRcvItemLotNum(@RequestBody List<RcvLineLotInfo> rcvLineLotInfoList) {
        return RestMessage.doSuccess(rcvHeadersService.vaildateRcvItemLotNum(rcvLineLotInfoList));
    }

    /**
     * 收货时拆分校验
     */
    @UserLog("收货时拆分校验")
    @ApiOperation("收货时拆分校验")
    @PostMapping("/vaildateRcvSplit")
    public RestMessage<Object> vaildateRcvSplit(@RequestBody List<RcvLineSpiltInfo> rcvLineSpiltInfoList) {
        return RestMessage.doSuccess(rcvHeadersService.vaildateRcvSplit(rcvLineSpiltInfoList));
    }

    /**
     * 测试获取rcvNo
     */
    @UserLog("测试获取rcvNo")
    @ApiOperation("测试获取rcvNo")
    @GetMapping("/testGetRcvNO")
    public RestMessage<Object> testGetRcvNO() {
        return RestMessage.doSuccess(rcvHeadersService.testGetRcvNO());
    }

    @UserLog("Pad-wms收货单极联新增")
    @ApiOperation("pad级联新增")
    @PostMapping("pad/addWithRelated")
    public RestMessage<Object> addWithRelatedByPad(@Validated(value = {validAdd.class}) @RequestBody RcvDTO rcvDTO) {
        RcvHeadersDTO rcvHeadersDTO = rcvDTO.getRcvHeadersDTO();
        AssertUtils.notNull(rcvHeadersDTO, "收货单主不可为空!");
        List<RcvLinesDTO> rcvLinesDTOList = rcvDTO.getRcvLinesDTOList();
        AssertUtils.notNull(rcvLinesDTOList, "收货单明细表不可为空!");
        return RestMessage.newInstance(true, "addSuccess", rcvHeadersService.addWithRelated(rcvDTO));
    }

    /**
     * 锁定入库单
     */
    @UserLog("货主转换锁定入库订单")
    @ApiOperation("货主转换锁定入库订单")
    @PostMapping("lock-bill")
    public RestMessage<Object> lockBill(String billId) {
        if (StringUtils.isBlank(billId)) {
            throw new ParameterException("订单id不可为空!");
        }
        return RestMessage.newInstance(true, "lockBill", rcvHeadersService.lockBill(billId));
    }

    /**
     * 货主转换执行入库
     */
    @UserLog("货主转换执行入库")
    @ApiOperation("货主转换执行入库")
    @PostMapping("cargoChangeIn")
    public RestMessage<Object> cargoChangeIn(@RequestBody List<CargoChangeIn> cargoChangeInList) {
        if (ObjectUtils.isNull(cargoChangeInList)) {
            throw new ParameterException("转换数据不可为空!");
        }
        return RestMessage.newInstance(true, "cargoChangeIn", rcvHeadersService.cargoChangeIn(cargoChangeInList));
    }

    /**
     * 货主转换查看订单,以及其明细
     */
    @UserLog("货主转换查看订单,以及其明细")
    @ApiOperation("货主转换查看订单,以及其明细")
    @PostMapping("cargoChangeInBillInfo")
    public RestMessage<Object> cargoChangeInBillInfo(@RequestBody List<String> billIds) {
        if (ObjectUtils.isNull(billIds)) {
            throw new ParameterException("订单ids不可为空!");
        }
        return RestMessage.newInstance(true, "cargoChangeIn", rcvHeadersService.cargoChangeInBillInfo(billIds));
    }

    @UserLog("pda收货单极联新增")
    @ApiOperation("(新)pda收货新增(级联关联表)")
    @PostMapping("/addWithRelatedByPda")
    public RestMessage<Object> addWithRelatedByPda(@Validated(value = {validAdd.class}) @RequestBody RcvDTO rcvDTO) {
        RcvHeadersDTO rcvHeadersDTO = rcvDTO.getRcvHeadersDTO();
        AssertUtils.notNull(rcvHeadersDTO, "收货单主不可为空!");
        List<RcvLinesDTO> rcvLinesDTOList = rcvDTO.getRcvLinesDTOList();
        AssertUtils.notNull(rcvLinesDTOList, "收货单明细表不可为空!");
        return RestMessage.newInstance(true, "addWithRelatedByPdaSuccess", rcvHeadersService.addWithRelatedByPda(rcvDTO));
    }


    @UserLog("提取入库单明细")
    @ApiOperation("提取入库单明细")
    @PostMapping("/extractAsnLine")
    @ApiImplicitParam(value = "单据id",name = "billId",required = true)
    public RestMessage<List<RcvLineDetailsDTO>> extractAsnLine(@RequestParam("billId") String billId){
        return RestMessage.newInstance(true,"success",rcvHeadersService.extractAsnLine(billId));
    }

    @UserLog("rf收货保存")
    @ApiOperation(value = "rf收货保存",notes = "刘溢沅")
    @PostMapping("/rfSave")
    public RestMessage<BigDecimal> rfSave(@Validated(value = {validAdd.class}) @RequestBody RcvDetailsDTO rcvDetailsDTO){
        RcvDTO rcvDTO = rcvHeadersService.buildRcvDto(rcvDetailsDTO);
        RcvHeadersDTO rcvHeadersDTO = rcvDTO.getRcvHeadersDTO();
        AssertUtils.notNull(rcvHeadersDTO, "收货单主不可为空!");
        List<RcvLinesDTO> rcvLinesDTOList = rcvDTO.getRcvLinesDTOList();
        AssertUtils.notNull(rcvLinesDTOList, "收货单明细表不可为空!");
        Boolean flag = rcvHeadersService.rfSaveValidate(rcvDTO);
        return RestMessage.newInstance(true, "保存校验通过", rcvHeadersService.calculationQty(flag,rcvDTO));
    }


    @UserLog("rf收货确认")
    @ApiOperation("rf收货确认")
    @PostMapping("/rfSaveConfrim")
    public RestMessage<Object> rfSaveConfrim(@Validated(value = {validAdd.class}) @RequestBody RcvDTO rcvDTO) {
        return RestMessage.newInstance(true, "保存校验通过", rcvHeadersService.rfSaveConfrim(rcvDTO));
    }

}
