package com.zbkj.front.controller;

import cn.hutool.core.util.ObjectUtil;
import com.zbkj.common.model.order.OrderDetail;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.*;
import com.zbkj.common.request.bcx.OrderSaveUrlRequest;
import com.zbkj.common.request.bcx.OrderSaveUserRequest;
import com.zbkj.common.response.*;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.vo.LogisticsResultVo;
import com.zbkj.front.service.FrontOrderService;
import com.zbkj.service.service.HuifuWalletService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * H5端订单操作
 * +----------------------------------------------------------------------
 * | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
 * +----------------------------------------------------------------------
 * | Author: CRMEB Team <admin@crmeb.com>
 * +----------------------------------------------------------------------
 */
@Slf4j
@RestController
@RequestMapping("api/front/order")
@Api(tags = "订单")
public class OrderController {

    @Autowired
    private FrontOrderService orderService;

    @Autowired
    private RedissonClient redisson;

    @ApiOperation(value = "预下单")
    @RequestMapping(value = "/pre/order", method = RequestMethod.POST)
    public CommonResult<OrderNoResponse> preOrder(@RequestBody @Validated PreOrderRequest request) {
        return CommonResult.success(orderService.preOrder_V1_3(request));
    }

    @ApiOperation(value = "加载预下单")
    @RequestMapping(value = "load/pre/{preOrderNo}", method = RequestMethod.GET)
    public CommonResult<PreOrderResponse> loadPreOrder(@PathVariable String preOrderNo) {
        return CommonResult.success(orderService.loadPreOrder(preOrderNo));
    }

    @ApiOperation(value = "计算订单价格")
    @RequestMapping(value = "/computed/price", method = RequestMethod.POST)
    public CommonResult<ComputedOrderPriceResponse> computedPrice(@Validated @RequestBody OrderComputedPriceRequest request) {
        return CommonResult.success(orderService.computedOrderPrice(request));
    }

    @ApiOperation(value = "虚拟订单额度退款(解冻)")
    @RequestMapping(value = "/virtual/refund", method = RequestMethod.POST)
    public CommonResult<Boolean> virtualRefund(@Validated @RequestBody CreateVirtualOrderRequest virtualOrderRequest) {
        if (ObjectUtil.isNotNull(orderService.virtualRefund(virtualOrderRequest))) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }
    @ApiOperation(value = "创建体检订单")
    @RequestMapping(value = "/health/create", method = RequestMethod.POST)
    public CommonResult<OrderPayResultResponse> createHealthOrder(@Validated @RequestBody CreateVirtualOrderRequest virtualOrderRequest) {
        String lockId = "HEALTH"+virtualOrderRequest.getSourceId();
        RLock lock = redisson.getLock(lockId);
        try {
            if(lock.tryLock(3,10, TimeUnit.SECONDS)){
                log.debug(lockId+":getLock: " + Thread.currentThread().getId());
                return CommonResult.success(orderService.createHealthOrder(virtualOrderRequest));
            }else{
                return CommonResult.failed("资源繁忙，请稍后重试");
            }
        } catch (InterruptedException e) {
            log.error("createHealthOrder error", e);
            return CommonResult.failed("操作失败，请稍后重试");
        }finally {
            if (lock.isHeldByCurrentThread()) {
                log.debug(lockId+":unLock: " + Thread.currentThread().getId());
                lock.unlock();
            }
        }

    }

    @ApiOperation(value = "创建订单")
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public CommonResult<OrderNoResponse> createOrder(@Validated @RequestBody CreateOrderRequest orderRequest) {
        return CommonResult.success(orderService.createOrder(orderRequest));
    }

    @ApiOperation(value = "导入保险订单(无实际支付，只为了分销分佣)")
    @RequestMapping(value = "/import/insurance", method = RequestMethod.POST)
    public CommonResult<String> importInsuranceOrder(@Validated @RequestBody BatchInsuranceOrderRequest batchInsuranceOrderRequest) {
        String result = orderService.importInsuranceOrder(batchInsuranceOrderRequest);
        return CommonResult.success(result);
    }

    @ApiOperation(value = "对保险订单指定绑定用户归属（当前E站风评WEB端使用）")
    @RequestMapping(value = "/bind/insurance", method = RequestMethod.POST)
    public CommonResult<String> bindUserByInsuranceOrder(@Validated @RequestBody OrderSaveUserRequest orderSaveUserRequest) {
        String result = orderService.bindUserByInsuranceOrder(orderSaveUserRequest);
        return CommonResult.success(result);
    }

    @ApiOperation(value = "订单列表")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "订单状态（-1：全部，0：待支付，1：待发货,2：部分发货， 3：待核销，4：待收货,5：已收货,6：已完成，9：已取消）", required = true),
            @ApiImplicitParam(name = "categoryId", value = "平台分类第三极id"),
            @ApiImplicitParam(name = "bizType", value = "商品类型（0-实物商品订单, 1-虚拟商品订单, 2-特殊类型(考培)订单, 3-保险类订单, 4-风评）"),
            @ApiImplicitParam(name = "fapiaoStatus", value = "开票状态（0-未开, 1-已开）")
    })
    public CommonResult<CommonPage<OrderFrontDataResponse>> orderList(@RequestParam(name = "status") Integer status,
                                                                      @RequestParam(name = "categoryId", required = false) Integer categoryId,
                                                                      @RequestParam(name = "bizType", required = false) Integer bizType,
                                                                      @RequestParam(name = "fapiaoStatus", required = false) Integer fapiaoStatus,
                                                                      @ModelAttribute PageParamRequest pageRequest) {
        return CommonResult.success(CommonPage.restPage(orderService.list(status,categoryId, bizType,fapiaoStatus, pageRequest)));
    }

    @ApiOperation(value = "订单详情")
    @RequestMapping(value = "/detail/{orderNo}", method = RequestMethod.GET)
    public CommonResult<OrderFrontDetailResponse> orderDetail(@PathVariable String orderNo) {
        return CommonResult.success(orderService.frontDetail(orderNo));
    }

    @ApiOperation(value = "订单取消")
    @RequestMapping(value = "/cancel/{orderNo}", method = RequestMethod.POST)
    public CommonResult<Boolean> cancel(@PathVariable(value = "orderNo") String orderNo) {
        if (orderService.cancel(orderNo)) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @ApiOperation(value = "批量订单退款(特殊商品-考培)")
    @RequestMapping(value = "/cancel/orders", method = RequestMethod.POST)
    public CommonResult<List<OrdersBatchOpsResponse>> cancelOrders(@RequestBody @Validated OrdersBatchOpsRequest orders) {
        List<OrdersBatchOpsResponse> result = orderService.refundOrders(orders);
        return CommonResult.success(result);
    }

    @ApiOperation(value = "批量订单退款(临时用)")
    @RequestMapping(value = "/cancel/orders/test", method = RequestMethod.POST)
    public CommonResult<List<OrdersBatchOpsResponse>> cancelOrdersTest(@RequestBody @Validated OrdersBatchOpsRequest orders) {
        List<OrdersBatchOpsResponse> result = orderService.refundOrdersTest(orders);
        return CommonResult.success(result);
    }

    @ApiOperation(value = "订单商品评论列表")
    @RequestMapping(value = "/reply/list", method = RequestMethod.GET)
    public CommonResult<CommonPage<InfoReplyResponse>> replyList(@ModelAttribute PageParamRequest pageRequest) {
        return CommonResult.success(CommonPage.restPage(orderService.replyList(pageRequest)));
    }

    @ApiOperation(value = "评价订单商品")
    @RequestMapping(value = "/reply/product", method = RequestMethod.POST)
    public CommonResult<Boolean> replyProduct(@RequestBody @Validated OrderProductReplyRequest request) {
        if (orderService.replyProduct(request)) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @ApiOperation(value = "删除订单")
    @RequestMapping(value = "/delete/{orderNo}", method = RequestMethod.POST)
    public CommonResult<Boolean> delete(@PathVariable(value = "orderNo") String orderNo) {
        if (orderService.delete(orderNo)) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @ApiOperation(value = "订单收货")
    @RequestMapping(value = "/take/delivery/{orderNo}", method = RequestMethod.POST)
    public CommonResult<String> take(@PathVariable(value = "orderNo") String orderNo) {
        if (orderService.takeDelivery(orderNo)) {
            return CommonResult.success("订单收货成功");
        }
        return CommonResult.failed("订单收货失败");
    }

    @ApiOperation(value = "特殊商品(考培)批量订单收货")
    @RequestMapping(value = "/take/delivery/orders", method = RequestMethod.POST)
    public CommonResult<List<OrdersBatchOpsResponse>> takeOrders(@RequestBody @Validated OrdersBatchOpsRequest orders) {
        List<OrdersBatchOpsResponse> result = orderService.takeSpecialOrders(orders);
        return CommonResult.success(result);
    }

    @ApiOperation(value = "售后申请列表(可申请售后列表)")
    @RequestMapping(value = "/after/sale/apply/list", method = RequestMethod.GET)
    @ApiImplicitParam(name = "orderNo", value = "订单号")
    public CommonResult<CommonPage<OrderDetail>> afterSaleApplyList(@RequestParam(value = "orderNo", defaultValue = "", required = false) String orderNo,
                                                                    @ModelAttribute PageParamRequest pageParamRequest) {
        return CommonResult.success(CommonPage.restPage(orderService.getAfterSaleApplyList(orderNo, pageParamRequest)));
    }

    @ApiOperation(value = "订单退款申请")
    @RequestMapping(value = "/refund", method = RequestMethod.POST)
    public CommonResult<Boolean> refundApply(@RequestBody @Validated OrderRefundApplyRequest request) {
        if (ObjectUtil.isNotNull(orderService.refundApply(request))) {
            return CommonResult.success();
        }
        return CommonResult.failed();
    }

    @ApiOperation(value = "订单退款理由（平台提供）")
    @RequestMapping(value = "/refund/reason", method = RequestMethod.GET)
    public CommonResult<List<String>> refundReason() {
        return CommonResult.success(orderService.getRefundReason());
    }

    @ApiOperation(value = "退款订单详情")
    @RequestMapping(value = "/refund/detail/{refundOrderNo}", method = RequestMethod.GET)
    public CommonResult<RefundOrderInfoResponse> refundOrderDetail(@PathVariable String refundOrderNo) {
        return CommonResult.success(orderService.refundOrderDetail(refundOrderNo));
    }

    @ApiOperation(value = "退款订单列表")
    @RequestMapping(value = "/refund/list", method = RequestMethod.GET)
    @ApiImplicitParam(name = "type", value = "列表类型：0-处理中，9-申请记录", required = true)
    public CommonResult<CommonPage<RefundOrderResponse>> refundOrderList(@RequestParam(value = "type") Integer type,
                                                                         @ModelAttribute PageParamRequest pageRequest) {
        return CommonResult.success(CommonPage.restPage(orderService.getRefundOrderList(type, pageRequest)));
    }

    @ApiOperation(value = "获取订单发货单列表")
    @RequestMapping(value = "/{orderNo}/invoice/list", method = RequestMethod.GET)
    public CommonResult<OrderInvoiceFrontResponse> getInvoiceList(@PathVariable(value = "orderNo") String orderNo) {
        return CommonResult.success(orderService.getInvoiceList(orderNo));
    }

    @ApiOperation(value = "物流信息查询")
    @RequestMapping(value = "/logistics/{invoiceId}", method = RequestMethod.GET)
    public CommonResult<LogisticsResultVo> getLogisticsInfo(@PathVariable(value = "invoiceId") Integer invoiceId) {
        return CommonResult.success(orderService.getLogisticsInfo(invoiceId));
    }

    @ApiOperation(value = "获取订单状态图")
    @RequestMapping(value = "/status/image", method = RequestMethod.GET)
    public CommonResult<List<HashMap<String, Object>>> getOrderStatusImage() {
        return CommonResult.success(orderService.getOrderStatusImage());
    }

    @ApiOperation(value = "保存风评报告订单的报告url")
    @RequestMapping(value = "/save/url", method = RequestMethod.POST)
    public CommonResult<Boolean> saveUrl(@RequestBody @Validated OrderSaveUrlRequest request){
        return CommonResult.success(orderService.saveOrderUrl(request));
    }
}
