package com.gree.mall.miniapp.controller.order;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gree.mall.miniapp.annotation.ApiNotAuth;
import com.gree.mall.miniapp.bean.PayDetail;
import com.gree.mall.miniapp.bean.order.*;
import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
import com.gree.mall.miniapp.bean.workorder.PgOrderSettleNormBean;
import com.gree.mall.miniapp.constant.Constant;
import com.gree.mall.miniapp.enums.QrCodeEnum;
import com.gree.mall.miniapp.exception.RemoteServiceException;
import com.gree.mall.miniapp.helper.ResponseHelper;
import com.gree.mall.miniapp.logic.FreightLogic;
import com.gree.mall.miniapp.logic.common.CommonLogic;
import com.gree.mall.miniapp.logic.common.outside.WechatLogic;
import com.gree.mall.miniapp.logic.order.OrderLogic;
import com.gree.mall.miniapp.logic.user.PayLogic;
import com.gree.mall.miniapp.plus.entity.OrderInfo;
import com.gree.mall.miniapp.utils.IpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

@Slf4j
@RestController
@Api(value = "订单", tags ={"订单"} )
@RequestMapping(value = "/order", produces = "application/json; charset=utf-8")
public class OrderController {

    @Autowired
    OrderLogic orderLogic;
    @Autowired
    FreightLogic freightLogic;
    @Autowired
    WechatLogic wechatLogic;
    @Autowired
    PayLogic payLogic;
//    @Autowired
//    GongdanLogic gongdanLogic;
    @Autowired
    CommonLogic commonLogic;
    @Autowired
    RedisLockRegistry redisLockRegistry;


    @PostMapping("/ackdata")
    @ApiOperation("确认订单内容")
    public ResponseHelper<OrderAckBean> ackData(
            @RequestBody OrderBuyBean orderBuyBean,
            HttpServletRequest request
    ) throws RemoteServiceException, InterruptedException {
        OrderAckBean orderAckBean = orderLogic.ackOrder(orderBuyBean,request);
        try {
            //运费
            if(orderAckBean.getFreight().doubleValue() < 0){
                return ResponseHelper.success(1100,orderAckBean,"暂不支持配送该地区");
            }
        }catch(Exception e){
            return ResponseHelper.success(1100,orderAckBean,e.getMessage());
        }
        return ResponseHelper.success(orderAckBean);
    }


    @PostMapping("/freight/v2")
    @ApiOperation("获取运费")
    public ResponseHelper<BigDecimal> getFregiht(
            @RequestBody OrderBuyBean orderBuyBean,
            HttpServletRequest request
    ) throws RemoteServiceException {
        BigDecimal freightAmount = freightLogic.getFreightAmountV2(orderBuyBean,request);
        return ResponseHelper.success(freightAmount);
    }

    @PostMapping("/buy")
    @ApiOperation("立即购买")
    public ResponseHelper<PayDetail> buy(
            @RequestBody OrderBuyBean orderBuyBean,
            HttpServletRequest request
    ) throws Exception {

        PayDetail buy = orderLogic.buy(orderBuyBean,request);
        return ResponseHelper.success(buy);
    }

    @PostMapping("/wait/pay")
    @ApiOperation("支付待支付订单")
    public ResponseHelper<PayDetail> waitPayOrder(
            @ApiParam(value = "支付人用户id",required = false) @RequestParam(required = false) String userId,
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId,
            @ApiParam(value = "是否小程序支付",required = false) @RequestParam(required = false) Boolean miniPay,
            @ApiParam(value = "openId",required = false) @RequestParam(required = false) String openId,
            HttpServletRequest request
    ) throws Exception {
        String ip = IpUtil.getIpAddr(request);
        PayDetail payDetail = orderLogic.waitPayOrder(userId,orderId,ip,request,miniPay,openId);
        return ResponseHelper.success(payDetail);
    }

    @GetMapping("/my/order")
    @ApiOperation("我的订单")
    public ResponseHelper<IPage<OrderDetailBean>> myOrder(
            @ApiParam(value = "用户id",required = true) @RequestParam String userId,
            @ApiParam(value = "订单状态(NOPAY:待付款 DFH:待发货 YFH:已发货 OVER:已完成 CLOSE:已关闭)",required = false) @RequestParam(required = false) String orderStatus,
            @ApiParam(value = "申请优惠状态 (100=全部  1=待审核 2=已通过 3=已驳回)",required = false) @RequestParam(required = false) Integer promotionApplyStatus,
            @ApiParam(value = "pageNo",required = true) @RequestParam Integer pageNo,
            @ApiParam(value = "pageSize",required = true) @RequestParam Integer pageSize
    ){
        IPage<OrderDetailBean> list = orderLogic.list(userId, orderStatus,promotionApplyStatus, pageNo, pageSize);
        return ResponseHelper.success(list);
    }


    @GetMapping("/detail")
    @ApiOperation("订单详情")
    public ResponseHelper<OrderDetailBean> detail(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId
    ){
        OrderDetailBean detail = orderLogic.detail(orderId);
        return ResponseHelper.success(detail);
    }

    @GetMapping("/cancel")
    @ApiOperation("取消订单")
    public ResponseHelper cancel(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId
    ) throws RemoteServiceException, InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + orderId);
        if(!obtain.tryLock(10,TimeUnit.SECONDS)){
            throw new RemoteServiceException("请勿频繁操作，请稍后再试");
        }
        try {
            orderLogic.cancel(Arrays.asList(orderId));
            return ResponseHelper.success();
        }finally {
            obtain.unlock();
        }
    }

    @PostMapping("/ack")
    @ApiOperation("确认收货")
    public ResponseHelper ack(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + orderId);
        if(!obtain.tryLock(10,TimeUnit.SECONDS)){
            throw new RemoteServiceException("请勿频繁操作，请稍后再试");
        }
        try {
            orderLogic.ack(orderId);
            return ResponseHelper.success();
        }finally {
            obtain.unlock();
        }
    }


    @PostMapping("/refund/cancel")
    @ApiOperation("售后订单-撤销申请")
    public ResponseHelper<String> applyRefund(
            @ApiParam(value = "订单id",required = true) @RequestParam String refundOrderId
    ) throws RemoteServiceException, InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + refundOrderId);
        if(!obtain.tryLock(10,TimeUnit.SECONDS)){
            throw new RemoteServiceException("请勿频繁操作，请稍后再试");
        }
        try {
            String s = orderLogic.cancelRefund(refundOrderId);
            return ResponseHelper.success(s);
        }finally {
            obtain.unlock();
        }
    }


    @PostMapping("/refund/apply")
    @ApiOperation("售后订单-申请退款")
    public ResponseHelper<String> applyRefund(
            @ApiParam(value = "退款",required = true) @RequestBody RefundGoodsBean refundGoodsBean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + refundGoodsBean.getOrderId());
        if(!obtain.tryLock(10,TimeUnit.SECONDS)){
            throw new RemoteServiceException("请勿频繁操作，请稍后再试");
        }
        try {
            String s = orderLogic.applyAfterSale(refundGoodsBean);
            return ResponseHelper.success(s);
        }finally {
            obtain.unlock();
        }
    }

    @GetMapping("/refund/list")
    @ApiOperation("售后订单-列表")
    public ResponseHelper<IPage<OrderRefundDetailBean>> refundDetail(
            @ApiParam(value = "用户id",required = true) @RequestParam String userId,
            @ApiParam(value = "订单状态(DSJCL=待商家处理  DSJSH=待商家收货 DMJCL=待买家处理 OVER=已完成 CANCEL=已取消)",required = false) @RequestParam(required = false) String orderStatus,
            @ApiParam(value = "pageNo",required = true) @RequestParam Integer pageNo,
            @ApiParam(value = "pageSize",required = true) @RequestParam Integer pageSize
    ){
        IPage<OrderRefundDetailBean> orderRefundDetailBeanIPage = orderLogic.refundList(userId, orderStatus, pageNo, pageSize);
        return ResponseHelper.success(orderRefundDetailBeanIPage);
    }


    @GetMapping("/refund/detail")
    @ApiOperation("售后订单-订单退款详情")
    public ResponseHelper<OrderRefundDetailBean> refundDetail(
            @ApiParam(value = "售后订单id",required = true) @RequestParam String orderRefundId
    ){
        OrderRefundDetailBean orderRefundDetailBean = orderLogic.orderRefundDetail(orderRefundId);
        return ResponseHelper.success(orderRefundDetailBean);
    }

    @PostMapping("/refund/supply")
    @ApiOperation("售后订单-商家已处理填写资料")
    public ResponseHelper applyRefund(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderRefundId,
            @ApiParam(value = "物流单号",required = true) @RequestParam String logisticsNo,
            @ApiParam(value = "快递公司code",required = true) @RequestParam String expressCompany,
            @ApiParam(value = "凭证ids",required = true) @RequestParam List<String> imgIds
    ) throws RemoteServiceException, InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + orderRefundId);
        if(!obtain.tryLock(10,TimeUnit.SECONDS)){
            throw new RemoteServiceException("请勿频繁操作，请稍后再试");
        }
        try {
            orderLogic.supplyData(orderRefundId, logisticsNo, expressCompany, imgIds);
            return ResponseHelper.success();
        }finally {
            obtain.unlock();
        }
    }

    @GetMapping("/count")
    @ApiOperation("各订单状态的数量")
    public ResponseHelper<OrderStatusBean> count(
            @ApiParam(value = "用户id",required = true) @RequestParam String userId
    ){
        OrderStatusBean count = orderLogic.count(userId);
        return ResponseHelper.success(count);
    }

    @GetMapping("/qrcode")
    @ApiOperation("获取付费订单码")
    public ResponseHelper<String> qrcode(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId,
            @ApiParam(value = "用户id",required = true) @RequestParam String userId,
            HttpServletRequest request
    ) throws RemoteServiceException {
        CurrentCompanyWechat currentCompanyWechat = commonLogic.getCurrentCompanyWechat(request);
        String qrcode = wechatLogic.getQrcode(QrCodeEnum.ORDER.toString().toLowerCase(Locale.ROOT),
                orderId,userId,currentCompanyWechat.getCompanyWechatId());
        return ResponseHelper.success(qrcode);
    }

    @PostMapping("/notice")
    @ApiOperation("提醒发货")
    public ResponseHelper notice(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId
    ){
        orderLogic.notice(orderId);
        return ResponseHelper.success();
    }

    @GetMapping("/work/list")
    @ApiOperation("工单列表")
    public ResponseHelper<IPage<WorkerOrderInfo>> workList(
            @ApiParam(value = "用户id", required = true) @RequestParam(required = true) String userId,
            @ApiParam(value = "工单号", required = false) @RequestParam(required = false) String workerOrderNo,
            @ApiParam(value = "pageNo",required = true) @RequestParam Integer pageNo,
            @ApiParam(value = "pageSize",required = true) @RequestParam Integer pageSize
    ) throws Exception {
        IPage<WorkerOrderInfo> workerOrder = orderLogic.getWorkerOrder(userId, workerOrderNo, pageNo, pageSize);
        return ResponseHelper.success(workerOrder);
    }

    @PostMapping("/rece/info/update")
    @ApiOperation("收货信息修改")
    public ResponseHelper updateReceInfo(
            @ApiParam(value = "订单", required = true) @RequestBody OrderInfo orderInfo
    ) throws Exception {
        orderLogic.updateReceInfo(orderInfo);
        return ResponseHelper.success();
    }

    @PostMapping("/settle/norm/detail")
    @ApiOperation("费用结算")
    public ResponseHelper<List<PgOrderSettleNormBean>> settleNormDetail(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId,
            HttpServletRequest request
    ){
        List<PgOrderSettleNormBean> list = orderLogic.settleNormDetail(orderId, request);
        return ResponseHelper.success(list);
    }

    @PostMapping("/settle/norm/detail/count")
    @ApiOperation("费用结算")
    public ResponseHelper<BigDecimal> settleNormDetailCount(
            @ApiParam(value = "订单id",required = true) @RequestParam String orderId,
            HttpServletRequest request
    ){
        BigDecimal total = orderLogic.settleNormDetailCount(orderId, request);
        return ResponseHelper.success(total);
    }
}
