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

import com.prolog.cs.basic.common.model.BaseCommonDict;
import com.prolog.cs.biz.outbound.dao.BarcodeDMapper;
import com.prolog.cs.biz.outbound.dao.BarcodeHMapper;
import com.prolog.cs.biz.outbound.model.BILL_STATUS;
import com.prolog.cs.biz.outbound.model.BILL_TYPE;
import com.prolog.cs.biz.outbound.model.OmsDoBillHDO;
import com.prolog.cs.biz.outbound.model.WAVE_STATUS;
import com.prolog.cs.biz.outbound.model.dto.*;
import com.prolog.cs.biz.outbound.model.entity.OmsDoBillDDO;
import com.prolog.cs.biz.outbound.model.entity.WaveBillDO;
import com.prolog.cs.biz.outbound.model.entity.WaveDO;
import com.prolog.cs.biz.outbound.model.vo.*;
import com.prolog.cs.biz.outbound.model.vo.check.WavePendingBillVO;
import com.prolog.cs.biz.outbound.resource.CommonClient;
import com.prolog.cs.biz.outbound.resource.StrategyResource;
import com.prolog.cs.biz.outbound.service.WavesService;
import com.prolog.cs.biz.outbound.service.impl.WorkStageServiceImpl;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.authority.user.UserTemplate;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.lock.annotation.RepeatOperationLock;
import com.prolog.framework.log.aop.annotation.UserLog;
import com.prolog.framework.utils.ArrayUtils;
import com.prolog.framework.utils.StringUtils;
import com.prolog.upcloud.base.strategy.model.BusinessControl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "波次")
@RestController
@RequestMapping("/wave")
public class WavesController {

    @Autowired
    private WavesService wavesService;

    @Autowired
    BarcodeDMapper barcodeDMapper;

    @Autowired
    BarcodeHMapper barcodeHMapper;

    @Autowired
    private CommonClient commonClient;

    @Autowired
    private WorkStageServiceImpl workStageServiceImpl;

    @Autowired
    private StrategyResource strategyResource;

    @Autowired
    private UserTemplate userTemplate;

    @UserLog
    @ApiOperation(value = "波次生成")
    @PostMapping("/create")
    @RepeatOperationLock(timeOut = 500)
    public RestMessage<String> wavesCreate(@RequestBody WavesCreateDTO wavesCreateVO) {
        String message = wavesService.wavesCreate(wavesCreateVO)[0];
        return RestMessage.success("操作成功", null);
    }

    @UserLog
    @ApiOperation(value = "查询OMS订单列表")
    @PostMapping("/billhpage")
    public RestMessage<Page<OmsDoBillHDO>> getBillHList(@RequestBody BillQueryDTO billQueryDTO) {
        RestMessage<List<BaseCommonDict>> billTypeList = commonClient.getDictBasicListByCodes("proper_bill_type", null);
        List<String> billTypes = billTypeList.getData().stream().map(BaseCommonDict::getDictCode).collect(Collectors.toList());
        billQueryDTO.setBilltypes(billTypes);
        return RestMessage.success("操作成功", wavesService.getBillHList(billQueryDTO));
    }

    @UserLog
    @ApiOperation(value = "波次下发")
    @PostMapping("/distribute")
    @RepeatOperationLock(timeOut = 500)
    public RestMessage<String> waveDistribute(@RequestBody WaveDistributeDTO waveDistributeVO) {
        return wavesService.waveDistribute(waveDistributeVO);
    }

    @UserLog
    @ApiOperation(value = "任务试算")
    @PostMapping("/waveTaskTrial")
    public RestMessage<List<WavePreCalResultVO>> waveTaskTrial(@RequestBody WaveDistributeDTO waveDistributeVO) {
        return wavesService.waveTaskTrial(waveDistributeVO);
    }

    @UserLog
    @ApiOperation(value = "查询OMS订单商品明细列表")
    @PostMapping("/billdbybillid")
    public RestMessage<Page<OmsDoBillDDO>> getBillDByBillId(@RequestBody ItemQueryDTO itemQueryDTO) {
        return RestMessage.success("操作成功", wavesService.getBillDByBillId(itemQueryDTO));
    }

    @UserLog
    @ApiOperation(value = "波次概览")
    @GetMapping("/")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "waveId", value = "波次id"),
            @ApiImplicitParam(name = "billCode", value = "订单编码"),
            @ApiImplicitParam(name = "warehouseId", value = "仓库id", required = true),
            @ApiImplicitParam(name = "cargoOwnerId", value = "货主id"),
            @ApiImplicitParam(name = "status", value = "status"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", required = true)
    })
    public RestMessage<Page<WaveVO>> getWaves(String warehouseId,
                                              String waveId,
                                              String billCode,
                                              String cargoOwnerId,
                                              String status,
                                              Integer pageNum,
                                              Integer pageSize) {
        return RestMessage.success("操作成功", wavesService.getWaves(pageNum, pageSize,
                warehouseId,
                waveId,
                billCode,
                cargoOwnerId, status,null));
    }


    @UserLog
    @ApiOperation(value = "波次订单明细")
    @GetMapping("/{waveId}")
    public RestMessage<WaveVO> getBillsByWaveId(@PathVariable String waveId) {
        return RestMessage.success("操作成功", wavesService.getBillsByWaveId(waveId));
    }

    @UserLog
    @ApiOperation(value = "删除波次订单")
    @DeleteMapping("/{waveId}")
    public RestMessage<Boolean> deleteByWaveId(@PathVariable String waveId) {
        return wavesService.deleteByWaveId(waveId);
    }


    @UserLog
    @ApiOperation(value = "波次订单商品明细")
    @GetMapping("/bill/{billId}")
    public RestMessage<WaveBillVO> getItemsByBillId(@PathVariable String billId,@Param("withStockQty") Integer withStockQty) {
        return RestMessage.success("操作成功", wavesService.getItemsByBillId(billId,withStockQty));
    }


    @UserLog
    @ApiOperation(value = "波次挂起订单查询")
    @GetMapping("/bill/query")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "warehouseId", value = "仓库id", required = true),
            @ApiImplicitParam(name = "billCode", value = "仓库id", required = true),
            @ApiImplicitParam(name = "consignorId", value = "货主id", required = true),
            @ApiImplicitParam(name = "waveId", value = "波次id", required = true),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", required = true)
    })
    public RestMessage<Page<WavePendingBillVO>> getPendingBills(String warehouseId,
                                                                String waveId,
                                                                String billCode,
                                                                String consignorId,
                                                                Integer pageNum,
                                                                Integer pageSize) {
        return RestMessage.success("操作成功",
                wavesService.getPendingBills(null,warehouseId, waveId,
                        billCode, consignorId,
                        pageNum, pageSize));
    }

    @UserLog
    @ApiOperation(value = "波次监控")
    @GetMapping("/statistics")
    @ApiImplicitParam(name = "waveId", value = "波次id", required = true)
    public RestMessage<WaveStatisticVO> getStatistics(String waveId) {
        return RestMessage.success("操作成功", wavesService.getStatistics(waveId));
    }


    @UserLog
    @RepeatOperationLock(timeOut = 500)
    @ApiOperation(value = "取消订单")
    @PostMapping("/bill/cancel")
    @ApiImplicitParam(name = "billId", value = "订单id", required = true)
    public RestMessage<Boolean> cancelBillById(String billId) {
        return wavesService.cancelBillById(billId);
    }

    @UserLog
    @ApiOperation(value = "订单重试")
    @PostMapping("/bill/retry")
    @ApiImplicitParam(name = "billId", value = "订单id", required = true)
    public RestMessage<Boolean> retryBillById(String billId) {
        return RestMessage.success("操作成功", wavesService.retryBillById(billId));
    }


    @UserLog
    @ApiOperation(value = "枚举波次状态")
    @GetMapping("/status/enum")
    public RestMessage<List<WaveStatusVO>> getWaveStatusEnum() {
        WAVE_STATUS[] values = WAVE_STATUS.values();
        List<WaveStatusVO> statusVOS = Arrays.stream(values).map(WaveStatusVO::new).collect(Collectors.toList());
        return RestMessage.success("操作成功", statusVOS);
    }

    @UserLog
    @ApiOperation(value = "枚举订单状态")
    @GetMapping("/bill/status/enum")
    public RestMessage<List<BillStatusVO>> getBillStatusEnum() {
        BILL_STATUS[] values = BILL_STATUS.values();
        List<BillStatusVO> statusVOS = Arrays.stream(values).map(BillStatusVO::new).collect(Collectors.toList());
        return RestMessage.success("操作成功", statusVOS);
    }


    @UserLog
    @ApiOperation(value = "根据状态查询订单")
    @GetMapping("/bill/")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "订单状态", required = true),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", required = true)})
    public RestMessage<Page<WaveBillDO>> getBillsByStatus(BILL_STATUS status,
                                                          Integer pageNum,
                                                          Integer pageSize) {
        WavesGroupBillQueryDTO billDto = new WavesGroupBillQueryDTO();
        billDto.setStatus(status);
        billDto.setPageNum(pageNum);
        billDto.setPageSize(pageSize);
        return RestMessage.success("操作成功", wavesService.getWaveBills(billDto));

    }

    @UserLog
    @ApiOperation(value = "波次库存预占查询")
    @GetMapping("/bill/item/locator/")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "warehouseId", value = "仓库id", required = true),
            @ApiImplicitParam(name = "waveId", value = "波次id"),
            @ApiImplicitParam(name = "billId", value = "订单id"),
            @ApiImplicitParam(name = "billDId", value = "订单商品明细id"),
            @ApiImplicitParam(name = "itemCode", value = "商品编码"),
            @ApiImplicitParam(name = "locatorId", value = "库位id"),
            @ApiImplicitParam(name = "billCode", value = "订单编码"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", required = true)})
    public RestMessage<Page<WaveStorageVO>> getWaveLocatorInfo(String warehouseId,
                                                               String waveId,
                                                               String billId,
                                                               String billDId,
                                                               String itemCode,
                                                               String locatorId,
                                                               String billCode,
                                                               Integer pageNum,
                                                               Integer pageSize) {

        return RestMessage.success("操作成功", wavesService.getWaveLocatorInfo(warehouseId,
                waveId, billId, billDId, itemCode, locatorId,billCode, pageNum, pageSize));

    }


    @UserLog
    @ApiOperation(value = "波次暂存区预占查询")
    @GetMapping("/workstage/")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "warehouseId", value = "仓库id", required = true),
            @ApiImplicitParam(name = "waveId", value = "波次id"),
            @ApiImplicitParam(name = "billId", value = "订单id"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", required = true)})
    public RestMessage<Page<WorkStageVO>> getWorkStage(String warehouseId,
                                                       String waveId,
                                                       String billId,
                                                       Integer pageNum,
                                                       Integer pageSize
    ) {
        return RestMessage.success("操作成功", wavesService.getWaveWorkStage(warehouseId,
                waveId, billId, pageNum, pageSize));
    }


    @UserLog
    @ApiOperation(value = "根据状态查询波次")
    @GetMapping("/condition/status")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "订单状态", required = true),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", required = true)})
    public RestMessage<Page<WaveDO>> getWaveSByStatus(WAVE_STATUS status,
                                                      Integer pageNum,
                                                      Integer pageSize) {
        WavesHeaderQueryDTO waveDto = new WavesHeaderQueryDTO();
        waveDto.setStatus(status);
        waveDto.setPageNum(pageNum);
        waveDto.setPageSize(pageSize);
        return RestMessage.success("操作成功", wavesService.getWavesByStatus(status, pageNum, pageSize));

    }

    @UserLog
    @ApiOperation(value = "发货暂存")
    @PostMapping("/update/billtype")
    public RestMessage<?> updateBillType(@RequestBody List<String> billids) {
        wavesService.updateBillType(billids);
        return RestMessage.success("操作成功", null);
    }


    /*@UserLog
    @ApiOperation(value = "任务试算")
    @GetMapping("/pre/caculate")
    public RestMessage<List<WavePreCalResultVO>> preCalculate(List<String> wavesIds) {
        return wavesService.preCalculate(wavesIds);
    }
*/
//    @UserLog
//    @ApiOperation(value = "测试波次下发，后期删除")
//    @PostMapping("/test/wave/result")
//    public RestMessage<Boolean> testWave(@ApiParam BigDecimal qty) {
//        barcodeHMapper.getLclNo("14", "111", '0');
//
//        return RestMessage.success("操作成功", true);
//    }

    @ApiOperation(value = "波次进度查询", notes = "波次进度分页查询-/waveMonitorPage/v1.0")
    @UserLog("波次进度查询")
    @PostMapping("/monitor-data")
    public RestMessage<Page<WaveMonitorPageDTO>> waveMonitorPage(@RequestBody WaveMonitorPageVO vo) {
        Page<WaveMonitorPageDTO> list = wavesService.waveMonitorPage(vo);
        return RestMessage.newInstance(true, "成功", list);
    }

    @ApiOperation(value = "自动下发波次-定时任务")
    @PostMapping("/v1/autoCreateWave")
    public RestMessage<?> autoCreateWave() {
        UserDTO userDTO = userTemplate.getUserDTO();

        String waveId = wavesService.autoCreateWave();
        if(StringUtils.isBlank(waveId)){
            return RestMessage.success("操作成功，没有待创建波次的数据", null);
        }

        Integer autoWaveDistribute = 1; // 默认自动波次下发
        RestMessage<Map<String, BusinessControl>> rest = strategyResource.getControlByCodes(new String[]{"auto_waveDistribute"}, userDTO.getUserBizModel().getDefaultWarehouseId(), null, userDTO.getEnterpriseId(), null);
        if (rest.isSuccess() && rest.getData() != null) {
            Map<String,BusinessControl> conMap = rest.getData();
            if (conMap.containsKey("auto_waveDistribute")) {
                autoWaveDistribute = Integer.valueOf(conMap.get("auto_waveDistribute").getRegValue());
            }
        }
        if (0 == autoWaveDistribute) {
            return RestMessage.success("操作成功", waveId);
        }
        // 波次下发
        WaveDistributeDTO waveDistributeDTO = new WaveDistributeDTO();
        waveDistributeDTO.setWavesIds(Collections.singletonList(waveId));
        wavesService.waveDistribute(waveDistributeDTO);
        return RestMessage.success("操作成功", waveId);
    }

    @ApiOperation(value = "预补货列表查询", notes = "预补货列表查询")
    @UserLog("预补货列表查询")
    @PostMapping("/pre-replenish")
    public RestMessage<Page<PreReplenishDto>> getPreReplenishPageList(@RequestBody PreReplenishVo vo) {
        Page<PreReplenishDto> list = wavesService.getPreReplenishPageList(vo);
        return RestMessage.newInstance(true, "成功", list);
    }

    @ApiOperation(value = "手动处理波次下的物料库库存")
    @PostMapping("/v1/handleGift")
    public RestMessage<?> handleGift(@RequestParam("waveId") String waveId) {
        workStageServiceImpl.handleGift(waveId);
        return RestMessage.success("操作成功", null);
    }

    @ApiOperation(value = "波次发票重推查询")
    @PostMapping("/v1/listWaveRepush")
    public RestMessage<Page<WaveDO>> listWaveRepush(@RequestBody Map<String, Object> param) {
        return RestMessage.success("查询成功", wavesService.listWaveRepush(param));
    }

    @ApiOperation(value = "波次发票重推")
    @PostMapping("/v1/waveRepush")
    public RestMessage<?> waveRepush(@RequestBody List<String> ids) {
        wavesService.waveRepush(ids);
        return RestMessage.success("波次发票重推成功", null);
    }

    @ApiOperation(value = "挂起订单")
    @PostMapping("/v1/hangupBill")
    public RestMessage hangupBill(@RequestBody List<String> taskLineIds) {
        wavesService.hangupBill(taskLineIds);
        return RestMessage.success("挂起订单", null);
    }
}
