package com.clx.performance.controller.pc;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.order.feign.OrderFeign;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.param.pc.OrderGoodsCancelParam;
import com.clx.performance.param.pc.UpdateEditOrderGoodsParam;
import com.clx.performance.param.pc.OrderGoodsParams;
import com.clx.performance.param.pc.PageOrderGoodsListParam;
import com.clx.order.vo.feign.FeignOrderVO;
import com.clx.performance.component.GoodsOrderStrategyContext;
import com.clx.performance.constant.RedisConstants;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.param.pc.UpdateOrderGoodsPriceParam;
import com.clx.performance.service.OrderChildService;
import com.clx.performance.service.OrderGoodsService;
import com.clx.performance.service.OrderGoodsTruckBindService;
import com.clx.performance.vo.pc.OrderChildPCVO;
import com.clx.performance.vo.pc.OrderGoodsEditVO;
import com.clx.performance.vo.pc.OrderGoodsVO;
import com.msl.common.base.PageData;
import com.msl.common.convertor.aspect.UnitCovert;
import com.msl.common.exception.ServiceSystemException;
import com.msl.common.result.Result;
import com.msl.common.utils.DateUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName GoodsOrderController
 * @Description
 * @Author kavin
 * @Date 2023/9/17 17:16
 * @Version 1.0
 */

@Slf4j
@RestController
@RequestMapping("/pc/goodsOrder")
@Validated
@Api(tags = "PC-货单")
public class GoodsOrderController {

    @Autowired
    OrderGoodsService orderGoodsService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private OrderChildService orderChildService;

    @Autowired
    private GoodsOrderStrategyContext goodsOrderStrategyContext;

    @Autowired
    private OrderGoodsTruckBindService orderGoodsTruckBindService;

    @ApiOperation(value = "提交货单", notes = "<br>By:胡宇帆")
    @PostMapping("/saveGoodsOrder")
    @UnitCovert(result = false)
    public Result<Object> saveGoodName(@RequestBody @Validated OrderGoodsParams orderGoodsParams) {
        String orderNo = orderGoodsParams.getOrderNo();
        LocalDateTime now = LocalDateTime.now();
        RLock rLock = null;
        try {
            //1. 加分布式锁通过订单ID
            //获取锁
            rLock = redissonClient.getLock(RedisConstants.ORDER_NO_BLOCK + orderNo);
            //设置超时
            rLock.lock(5, TimeUnit.SECONDS);
            //2. 通过OrderNo 查询订单信息
            FeignOrderVO orderInfo = orderFeign.getOrderInfoFeign(orderNo);
            //1平台车辆 2部分平台车辆 3自有车辆
            Integer truckDemand = orderInfo.getTruckDemand();
            goodsOrderStrategyContext.strategyContext.get(truckDemand).saveGoodsOrder(orderGoodsParams, orderInfo, now, rabbitTemplate);

        } catch (Exception e) {
            log.info(e.getMessage());
            throw new ServiceSystemException(PerformanceResultEnum.ORDER_GOODS_SAVE_FAIL, e.getMessage());
        } finally {
            try {
                if (rLock != null && rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                    rLock.unlock();
                }
                log.info("锁释放完成");
            } catch (Exception e) {
                log.error("redis 分布式锁释放异常!", e);
            }
        }

        return Result.ok();
    }


    @ApiOperation(value = "查看货单详情", notes = "<br>By:胡宇帆")
    @GetMapping("/getOrderGoodsInfo")
    @UnitCovert(param = false)
    public Result<OrderGoodsVO> getOrderGoodsInfo(@RequestParam String orderGoodsNo) {
        return Result.ok(orderGoodsService.getOrderGoodsInfoByOrderGoodsNoForPC(orderGoodsNo));
    }

    @ApiOperation(value = "查看货单详情-相关运单", notes = "<br>By:胡宇帆")
    @GetMapping("/getOrderChildInfoByOrderGoodsNo")
    @UnitCovert(param = false)
    public Result<List<OrderChildPCVO>> getOrderChildInfoByOrderGoodsNo(@RequestParam String orderGoodsNo) {
        return Result.ok(orderChildService.getOrderChildInfoByOrderGoodsNo(orderGoodsNo));
    }

    @ApiOperation(value = "查看货单列表", notes = "<br>By:胡宇帆")
    @PostMapping("/pageOrderGoodsList")
    @UnitCovert(param = false)
    public Result<PageData<OrderGoodsVO>> pageOrderGoodsList(@RequestBody PageOrderGoodsListParam param) {
        IPage<OrderGoodsVO> page = orderGoodsService.pageOrderGoodsList(param);
        return Result.page(page.getRecords(), page.getTotal(), page.getPages());
    }

    @ApiOperation(value = "货单编辑查询", notes = "<br>By:胡宇帆")
    @GetMapping("/findOrderGoodsByBatchNumber")
    @UnitCovert
    public Result<OrderGoodsEditVO> findOrderGoodsByBatchNumber(@RequestParam(value = "id") Integer id){
        OrderGoodsEditVO orderGoodsVO = orderGoodsService.findOrderGoodsById(id);
        return Result.ok(orderGoodsVO);
    }

    @ApiOperation(value = "货单编辑提交", notes = "<br>By:刘海泉")
    @PostMapping("/updateEditOrderGoods")
    @UnitCovert
    public Result<Object> updateEditOrderGoods(@RequestBody @Validated UpdateEditOrderGoodsParam param) {
        orderGoodsService.updateEditOrderGoods(param);
        return Result.ok();
    }


    @ApiOperation(value = "取消订单获取弹窗样式", notes = "<br>By:胡宇帆")
    @GetMapping("/orderCancelStyle")
    public Result<String> orderCancelStyle(@RequestParam(value = "orderNo") String orderNo) {
        return Result.ok(orderGoodsService.orderCancelStyle(orderNo));
    }

    @ApiOperation(value = "取消货单获取弹窗样式", notes = "<br>By:胡宇帆")
    @GetMapping("/orderGoodsCancelStyle")
    public Result<String> orderGoodsCancelStyle(@RequestParam(value = "orderGoodsNo") String orderGoodsNo) {
        return Result.ok(orderGoodsService.orderGoodsCancelStyle(orderGoodsNo));
    }

    @ApiOperation(value = "查看未装车的车辆用于货单取消弹窗展示", notes = "<br>By:胡宇帆")
    @GetMapping("/getOrderChildTruckList")
    public Result<List<String>> getOrderChildTruckList(@RequestParam(value = "orderGoodsNo") String orderGoodsNo) {
        return Result.ok(orderGoodsService.getOrderChildTruckList(orderGoodsNo));
    }

    @ApiOperation(value = "取消货单", notes = "<br>By:胡宇帆")
    @PostMapping("/orderGoodsCancel")
    public Result<Object> orderGoodsCancel(@RequestBody OrderGoodsCancelParam param) {
        orderGoodsService.orderGoodsCancel(param);
        return Result.ok();
    }

    @ApiOperation(value = "获取当前订单可取消吨数", notes = "<br>By:胡宇帆")
    @GetMapping("/orderCancelResidueWeight")
    public Result<BigDecimal> orderCancelResidueWeight(@RequestParam(value = "orderNo") String orderNo, @RequestParam(value = "optionType") String optionType) {
        return Result.ok(orderGoodsService.orderCancelResidueWeight(orderNo,optionType));
    }

    @ApiOperation(value = "获取当前货单可取消吨数", notes = "<br>By:胡宇帆")
    @PostMapping("/orderGoodsCancelResidueWeight")
    public Result<BigDecimal> orderGoodsCancelResidueWeight(@RequestBody OrderGoodsCancelParam goodsCancelParam) {
        return Result.ok(orderGoodsService.orderGoodsCancelResidueWeight(goodsCancelParam));
    }

    @ApiOperation(value = "调整货单价格", notes = "<br>By:刘海泉")
    @PostMapping("/updateOrderGoodsPrice")
    @UnitCovert(result = false)
    public Result<Object> updateOrderGoodsPrice(@RequestBody @Validated UpdateOrderGoodsPriceParam param) {
        orderGoodsService.updateOrderGoodsPrice(param);
        return Result.ok();
    }


}
