package org.springblade.modules.api.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.enums.MessageTypeEnum;
import org.springblade.common.enums.OrderStateEnum;
import org.springblade.common.enums.OrderTypeEnum;
import org.springblade.common.enums.YesOrNoEnum;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.modules.api.request.CartSubmitOrderRequest;
import org.springblade.modules.api.request.IDRequest;
import org.springblade.modules.api.request.ModifyAddressRequest;
import org.springblade.modules.api.response.OrderDetailResponse;
import org.springblade.modules.api.response.SubmitOrderResponse;
import org.springblade.modules.api.service.impl.CartSampleWineOrderImpl;
import org.springblade.modules.api.vo.LogisticVO;
import org.springblade.modules.api.vo.OrderStatisNum;
import org.springblade.modules.finance.entity.CustomWineOrder;
import org.springblade.modules.finance.entity.Order;
import org.springblade.modules.finance.entity.OrderDetail;
import org.springblade.modules.finance.entity.OrderGoods;
import org.springblade.modules.finance.service.ICustomWineOrderService;
import org.springblade.modules.finance.service.IOrderDetailService;
import org.springblade.modules.finance.service.IOrderGoodsService;
import org.springblade.modules.finance.service.IOrderService;
import org.springblade.modules.finance.service.impl.OrderTimeoutService;
import org.springblade.modules.finance.vo.CustomWineOrderVO;
import org.springblade.modules.finance.vo.OrderVO;
import org.springblade.modules.finance.wrapper.CustomWineOrderWrapper;
import org.springblade.modules.finance.wrapper.OrderWrapper;
import org.springblade.modules.platform.service.IUserMessageService;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * Author pangqijun
 * Date 2023/2/24
 * Description
 */
@RestController
@AllArgsConstructor
@RequestMapping(CommonConstant.API_URL + "/appOrder")
@Api(value = "订单模块接口", tags = "09.订单模块接口")
public class AppOrderController extends BladeController {

    @Resource
    private IOrderService orderService;
    @Resource
    private IOrderGoodsService orderGoodsService;
    @Resource
    private IOrderDetailService orderDetailService;
    @Resource
    private ICustomWineOrderService customWineOrderService;
    @Resource
    private IUserMessageService userMessageService;
    @Resource
    private OrderTimeoutService orderTimeoutService;
    @Resource
    private CartSampleWineOrderImpl cartSampleWineOrder;

    @GetMapping("list")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "订单列表", notes = "订单状态 0:全部，1待付款，2:待发货，3待收货，4已完成，5售后")
    public R<List<OrderVO>> orderPage(@ApiParam(value = "支付状态") @RequestParam(required = false) Integer orderState,
                                      Query query) {
        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery(Order.class).eq(Order::getCreateUserId, AuthUtil.getUserId())
                .orderByDesc(Order::getCreateTime);
        if (orderState == 0) {
            wrapper.notIn(Order::getOrderState, Arrays.asList(OrderStateEnum.REFUNDING.getValue(), OrderStateEnum.REFUNDED.getValue()));
        } else if (orderState == 5) {
            wrapper.in(Order::getOrderState, Arrays.asList(OrderStateEnum.REFUNDING.getValue(), OrderStateEnum.REFUNDED.getValue()));
        } else {
            wrapper.eq(Order::getOrderState, orderState);
        }
        IPage<Order> pages = orderService.page(Condition.getPage(query), wrapper);
        List<OrderVO> orderVOS = OrderWrapper.build().listVO(pages.getRecords());

        if (CollUtil.isNotEmpty(orderVOS)) {
            for (OrderVO orderVO : orderVOS) {
                if (OrderTypeEnum.GOODS.getValue().equals(orderVO.getOrderType())) {
                    OrderGoods orderGoods = orderGoodsService.getByOrderNo(orderVO.getOrderNo());
                    orderVO.setOrderGoods(orderGoods);
                }
            }
        }
        return data(orderVOS);
    }

    @GetMapping("detail")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "订单详情")
    public R<OrderDetailResponse> orderPage(@ApiParam(value = "订单编号", required = true) @RequestParam String orderNo) {
        OrderDetailResponse response = new OrderDetailResponse();
        Order order = orderService.getByOrderNo(orderNo);
        OrderDetail orderDetail = orderDetailService.getByOrderId(order.getId());
        if (OrderTypeEnum.CUSTOM_WINE.getValue().equals(order.getOrderType())) {
            CustomWineOrder customWineOrder = customWineOrderService.getByOrderId(order.getId());
            CustomWineOrderVO customWineOrderVO = CustomWineOrderWrapper.build().entityVO(customWineOrder);

            response.setCustomWineOrder(customWineOrderVO);
        } else {
            OrderGoods orderGoods = orderGoodsService.getByOrderNo(order.getOrderNo());
            response.setOrderGoods(orderGoods);
        }

        OrderVO orderVO = OrderWrapper.build().entityVO(order);
        response.setOrder(orderVO);
        response.setOrderDetail(orderDetail);

        long timeoutTime = orderTimeoutService.getTimeoutTime();
        long curr = System.currentTimeMillis();
        if (OrderStateEnum.WAIT_PAY.getValue().equals(orderVO.getOrderState())) {
            long t = orderVO.getCreateTime().getTime() + (timeoutTime * 1000);
            // 支付剩余总秒数
            long c = (t - curr) / 1000;
            // 支付剩余分钟数
            orderVO.setMinutes(c / 60);
            orderVO.setSeconds(c - (orderVO.getMinutes() * 60));
        }
        return data(response);
    }

    @PostMapping("cancel")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "取消订单", notes = "传入订单号")
    public R orderCancel(@RequestBody IDRequest request) {
        Order record = orderService.getById(request.getId());
        if (record == null) {
            return R.fail("订单数据不存在");
        }
        orderService.cancel(record);
        return R.success("订单已取消");
    }

    @ApiLog("确认收货")
    @PostMapping("/confirm")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "确认收货", notes = "待收货变为已完成")
    public R orderConfirm(@RequestBody IDRequest request) {
        orderService.confirm(request.getId());
        return success("操作成功");
    }

    @PostMapping("/refund")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "申请退款", notes = "传入订单号")
    public R orderRefund(@RequestBody IDRequest request) {
        orderService.orderRefund(request.getId());
        return success("操作成功");
    }

    @GetMapping("logistic")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "查询物流信息", notes = "传入订单号")
    public R<LogisticVO> logistic(@ApiParam(value = "订单id", required = true) @RequestParam Long orderId) throws IOException {
        return data(orderService.logistic(orderId));
    }

    @PostMapping("remove")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "删除订单订单", notes = "传入订单号")
    public R orderRemove(@RequestBody IDRequest request) {
        Order order = orderService.getById(request.getId());
        Assert.notNull(order, "订单数据不存在");
        if (OrderStateEnum.CANCEL.getValue().equals(order.getOrderState())) {
            order.setUpdateTime(new Date());
            order.setIsDelete(YesOrNoEnum.YES.getValue());
            orderService.lambdaUpdate().set(Order::getIsDelete, YesOrNoEnum.YES.getValue())
                    .eq(Order::getId, order.getId()).update();
        } else {
            return R.fail("当前订单不支持删除");
        }
        return success("订单已删除");
    }


    @PostMapping("modifyAddress")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "修改订单地址")
    public R modifyAddress(@Valid @RequestBody ModifyAddressRequest request) {
        orderService.modifyAddress(request);
        return success("已修改");
    }

    @GetMapping("statis-num")
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "订单数量统计", notes = "传入订单号")
    public R<List<OrderStatisNum>> statisNum() {
        return data(orderService.statisNum(AuthUtil.getUserId()));
    }

    @ApiLog("通用购物车下单")
    @PostMapping("/cart/submit")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "提交下单")
    public R<SubmitOrderResponse> cartSubmitOrder(@Valid @RequestBody CartSubmitOrderRequest request) {
        request.setUserId(AuthUtil.getUserId());
        String orderNo = cartSampleWineOrder.cartSubmitOrder(request);
        return data(new SubmitOrderResponse(orderNo));
    }
}
