package com.clx.performance.controller.pc;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.order.feign.OrderFeign;
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.*;
import com.clx.performance.param.pc.carrier.PageSettlementOrderChildRiskParam;
import com.clx.performance.service.OrderChildService;
import com.clx.performance.service.OrderGoodsAdjustmentPriceService;
import com.clx.performance.service.OrderGoodsService;
import com.clx.performance.service.OrderGoodsTruckBindService;
import com.clx.performance.service.*;
import com.clx.performance.vo.feign.OrderExtractWeightVO;
import com.clx.performance.vo.pc.*;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
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.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
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;

    @Autowired
    private OrderGoodsAdjustmentPriceService orderGoodsAdjustmentPriceService;

    @Autowired
    private OrderWeightService orderWeightService;

    @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();

            OrderExtractWeightVO orderCanExtractWeight = orderWeightService.getOrderCanExtractWeight(orderNo);

            goodsOrderStrategyContext.strategyContext.get(truckDemand).saveGoodsOrder(orderGoodsParams, orderInfo,
                    orderCanExtractWeight,now);

        } 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:胡宇帆")
    @PostMapping("/getOrderChildInfoByOrderGoodsNo")
    @UnitCovert(param = false)
    public Result<List<OrderChildPCVO>> getOrderChildInfoByOrderGoodsNo(@RequestBody @Validated QueryOrderChildsListByParam param) {
        return Result.ok(orderChildService.getOrderChildInfoByOrderGoodsNo(param));
    }

    @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:杨启发")
    @PostMapping("/exportOrderGoods")
    public void exportOrderGoods(@RequestBody PageOrderGoodsListParam param, HttpServletResponse response) throws Exception {
        try (SXSSFWorkbook workbook = orderGoodsService.exportOrderGoods(param)) {
            response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
            workbook.write(response.getOutputStream());
        }
    }

    @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();
    }


    @ApiOperation(value = "司机运费列表", notes = "<br>By:刘海泉")
    @GetMapping("/getDriverFreightPriceList")
    @UnitCovert(param = false)
    public Result<List<DriverFreightPriceVO>> getDriverFreightPriceList(@RequestParam(value = "orderNo")
    @NotBlank(message = "订单编号不能为空") String orderNo) {
        List<DriverFreightPriceVO> list = orderGoodsService.getDriverFreightPriceList(orderNo);
        return Result.ok(list);
    }


    @ApiOperation(value = "订单下挂单时间列表", notes = "<br>By:刘海泉")
    @GetMapping("/getOrderGoodsPendingList")
    public Result<List<OrderGoodsPendingVO>> getOrderGoodsPendingList(@RequestParam(value = "orderNo")
    @NotBlank(message = "订单编号不能为空") String orderNo) {
        List<OrderGoodsPendingVO> list = orderGoodsService.getOrderGoodsPendingList(orderNo);
        return Result.ok(list);
    }

    @ApiOperation(value = "司机运费记录柱形图", notes = "<br>By:刘海泉")
    @GetMapping("/getDriverFreightPriceChart")
    @UnitCovert(param = false)
    public Result<List<DriverFreightPriceChartVO>> getDriverFreightPriceChart(@RequestParam(value = "orderNo")
    @NotBlank(message = "订单编号不能为空") String orderNo) {
        List<DriverFreightPriceChartVO> list = orderGoodsAdjustmentPriceService.getDriverFreightPriceChart(orderNo);
        return Result.ok(list);
    }





}
