package com.gxwebsoft.shop.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.security.JwtUtil;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.RequestUtil;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.Role;
import com.gxwebsoft.shop.entity.Cart;
import com.gxwebsoft.shop.entity.OrderGoods;
import com.gxwebsoft.shop.entity.OrderInfo;
import com.gxwebsoft.shop.service.CartService;
import com.gxwebsoft.shop.service.OrderGoodsService;
import com.gxwebsoft.shop.service.OrderInfoService;
import com.gxwebsoft.shop.service.OrderService;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.param.OrderParam;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.system.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单控制器
 *
 * @author 科技小王子
 * @since 2024-05-14 13:20:04
 */
@Api(tags = "订单管理")
@RestController
@RequestMapping("/api/shop/order")
public class OrderController extends BaseController {
  @Resource
  private OrderService orderService;
  @Resource
  private OrderInfoService orderInfoService;
  @Resource
  private OrderGoodsService orderGoodsService;
  @Resource
  private CartService cartService;
  @Resource
  private RequestUtil requestUtil;

  @ApiOperation("分页查询订单")
  @GetMapping("/page")
  public ApiResult<PageResult<Order>> page(OrderParam param) {
    // 使用关联查询
    return success(orderService.pageRel(param));
  }

  @ApiOperation("查询全部订单")
  @GetMapping()
  public ApiResult<List<Order>> list(OrderParam param) {
    // 使用关联查询
    return success(orderService.listRel(param));
  }

  @PreAuthorize("hasAuthority('shop:order:list')")
  @ApiOperation("根据id查询订单")
  @GetMapping("/{id}")
  public ApiResult<Order> get(@PathVariable("id") Integer id) {
    // 使用关联查询
    return success(orderService.getByIdRel(id));
  }

  @ApiOperation("根据orderNo查询订单")
  @GetMapping("/getByOrderNo/{orderNo}")
  public ApiResult<Order> getByOrderNo(@PathVariable("orderNo") String orderNo){
    final User loginUser = getLoginUser();
    if(loginUser == null){
      return fail("请先登录",null);
    }

    final Order order = orderService.getByOutTradeNo(orderNo);
    if(order != null){
      final List<OrderInfo> orderInfoList = orderInfoService.list(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderId, order.getOrderId()));
      order.setOrderInfo(orderInfoList);
    }
    return success(order);
  }


  @PreAuthorize("hasAuthority('shop:order:verification')")
  @ApiOperation("根据orderNo核销订单")
  @GetMapping("/verification/{orderNo}")
  public ApiResult<Order> verification(@PathVariable("orderNo") String orderNo){
    final User loginUser = getLoginUser();
    if(loginUser == null){
      return fail("请先登录",null);
    }

    final Set<String> collect = loginUser.getRoles().stream().map(Role::getRoleCode).collect(Collectors.toSet());
    final boolean merchant = Arrays.asList(collect).contains("merchant");
    final boolean merchantClerk = Arrays.asList(collect).contains("merchantClerk");

    if(merchant || merchantClerk){
      System.out.println("merchant = " + merchant);
      System.out.println("merchantClerk = " + merchantClerk);
      final Order order = orderService.getByOutTradeNo(orderNo);
      if(order != null){
        final List<OrderInfo> orderInfoList = orderInfoService.list(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderId, order.getOrderId()));
        order.setOrderInfo(orderInfoList);
      }
      return success(order);
    }
    return fail("核销失败",null);
  }

  @ApiOperation("下单")
  @PostMapping()
  public ApiResult<?> save(@RequestBody Order order, HttpServletRequest request) {
    String access_token = JwtUtil.getAccessToken(request);
    // 记录当前登录用户id
    User loginUser = getLoginUser();
    if (loginUser == null) {
      return fail("请先登录");
    }
    // 微信openid(必填)
    if (StrUtil.isBlank(loginUser.getOpenid())) {
      return fail("微信openid(必填)");
    }
    // 商品描述(必填)
    if (StrUtil.isBlank(order.getComments())) {
      return fail("商品描述(必填)");
    }
    // 判断场地是否被抢占
    if (order.getType().equals(1)) {
      if (ObjectUtil.isNotEmpty(order.getOrderInfo())) {
          order.getOrderInfo().forEach(d -> {
            if (orderInfoService.count(new LambdaUpdateWrapper<OrderInfo>()
              .eq(OrderInfo::getPayStatus,1)
              .eq(OrderInfo::getOrderCode,d.getOrderCode())) > 0) {
              order.setScene(1234);
            }
          });
          if(order.getScene() != null && order.getScene().equals(1234)){
            return fail("场地不存在");
          }
      }
    }
    // 微信支付(商品金额不能为0)
    if (order.getPayType().equals(1)) {
      if (order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
        return fail("商品金额不能为0");
      }
    }

    // 已下过订单
    if(order.getOrderId() != null){
      Order order1 = orderService.getByIdRel(order.getOrderId());
      order1.setPayType(order.getPayType());
      order1.setOpenid(loginUser.getOpenid());
      order1.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
      order1.setAccessToken(access_token);
      order1.setLoginUser(loginUser);
      // 调起支付
      return onPay(order1);
    }

    // 创建订单
    long timeMillis = System.currentTimeMillis();
    long orderNo = IdUtil.getSnowflakeNextId();
    order.setOrderNo(Long.toString(orderNo));
    order.setUserId(loginUser.getUserId());
    order.setOpenid(loginUser.getOpenid());
    order.setRealName(loginUser.getRealName());
    order.setPhone(loginUser.getPhone());
    order.setUserId(loginUser.getUserId());
    order.setLoginUser(loginUser);
    order.setAccessToken(access_token);
    order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.MINUTE, 1));
    if (order.getOrderInfo() != null) {
      order.setTotalNum(order.getOrderInfo().size());
    }
    if (order.getGoodsList() != null) {
      order.setTotalNum(order.getGoodsList().size());
    }

    if (orderService.save(order)) {
      // 商城订单
      if (ObjectUtil.isNotEmpty(order.getGoodsList())) {
        order.getGoodsList().forEach(d -> {
          d.setOrderId(order.getOrderId());
          d.setTimeFlag(timeMillis);
          d.setVersion(10);
          d.setDateTime(DateUtil.date());
          d.setUserId(getLoginUser().getUserId());
          d.setExpirationTime(order.getExpirationTime());
        });
        orderGoodsService.saveBatch(order.getGoodsList());
      }
      // 预定订单
      if (ObjectUtil.isNotEmpty(order.getOrderInfo())) {
        if (ObjectUtil.isNotEmpty(order.getOrderInfo())) {
          order.getOrderInfo().forEach(d -> {
            d.setOrderId(order.getOrderId());
            d.setTimeFlag(timeMillis);
            d.setVersion(10);
            d.setUserId(getLoginUser().getUserId());
            d.setDateTime(d.getDateTime());
            d.setExpirationTime(order.getExpirationTime());
            d.setTenantId(order.getTenantId());
          });
          orderInfoService.saveBatch(order.getOrderInfo());
        }

      }
      // 会员卡订单
//      if (order.getType().equals(2)) {
//        // 会员卡信息
//        final Card card = cardService.getByIdRel(Integer.valueOf(order.getCardId()));
//        final UserCard userCard = new UserCard();
//        userCard.setPhone(loginUser.getPhone());
//        userCard.setSid(card.getMerchantIds());
//        userCard.setCardNum(CommonUtil.createCardNo());
//        userCard.setName(card.getCardName());
//        userCard.setUsername(loginUser.getRealName());
//        userCard.setPhone(loginUser.getPhone());
//        userCard.setPrice(card.getPrice());
//        userCard.setComments(card.getCardDesc());
//        userCard.setInfo(card.getComments());
//        userCard.setUid(loginUser.getUserId());
//        userCard.setRemainingMoney(card.getPrice());
//        userCard.setVid(0);
//        userCard.setAid(0);
//        userCard.setCode(CommonUtil.randomUUID8());
//        userCard.setDiscount(card.getDiscount());
//        userCard.setNumber(1);
//        userCard.setNum(card.getNumber());
//        userCard.setMonth(card.getMonth());
//        userCard.setPayType(1);
//        userCard.setType(card.getType());
//        userCard.setTenantId(card.getTenantId());
//        final long epochMilli = DateUtil.toInstant(DateUtil.offset(DateUtil.date(), DateField.MONTH, card.getMonth())).toEpochMilli();
//        userCard.setExpireTime(epochMilli/1000);
//        userCardService.save(userCard);
//        order.setCardId(userCard.getId());
//      }
      // 调起支付
      return onPay(order);
    }
    return fail("下单失败");
  }

  private ApiResult<?> onPay(Order order) {
    // TODO 余额支付
    if (order.getPayType().equals(0)) {
      order.setAccessToken(order.getAccessToken());
      final User loginUser = order.getLoginUser();
      if (loginUser.getBalance().compareTo(order.getTotalPrice()) < 0) {
        throw new BusinessException("余额不足");
      }
      // 清空购物车
      final Set<Integer> cartIds = order.getGoodsList().stream().map(OrderGoods::getGoodsId).collect(Collectors.toSet());
      cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId,order.getUserId()).in(Cart::getGoodsId,cartIds));
      // 外卖订单
      if(!order.getMerchantId().equals(0)){
        cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId,order.getUserId()).eq(Cart::getType,1));
      }
      return success("下单成功", requestUtil.balancePay(order));
    }

    // TODO 微信统一下单接口
    if (order.getPayType().equals(1)) {
      // 清空购物车
      final Set<Integer> cartIds = order.getGoodsList().stream().map(OrderGoods::getGoodsId).collect(Collectors.toSet());
      cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId,order.getUserId()).in(Cart::getGoodsId,cartIds));
      // 外卖订单
      if(!order.getMerchantId().equals(0)){
        cartService.remove(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId,order.getUserId()).eq(Cart::getType,1));
      }
      return success("下单成功", orderService.createWxOrder(order));
    }

//      // TODO 微信Native支付
//      if(order.getPayType().equals(102)){
//        order.setAccessToken(access_token);
//        order.setLoginUser(loginUser);
//        return success("下单成功", orderService.payByWxNative(order));
//      }

    // TODO 会员卡支付
//    if(order.getPayType().equals(2)){
//      order.setAccessToken(order.getAccessToken());
//      System.out.println("getAccessToken = " + order.getAccessToken());
//      return success("下单成功", orderService.payByUserCard(order));
//    }
    return fail("支付失败");
  }

  @ApiOperation("修改订单")
  @PutMapping()
  public ApiResult<?> update(@RequestBody Order order) {
    if(order.getOrderStatus().equals(2)){
      order.setExpirationTime(DateUtil.date());
      orderInfoService.update(new LambdaUpdateWrapper<OrderInfo>().eq(OrderInfo::getOrderId,order.getOrderId()).set(OrderInfo::getExpirationTime,DateUtil.date()));
    }
    if (orderService.updateById(order)) {
      return success("操作成功");
    }
    return fail("操作失败");
  }

  @ApiOperation("删除订单")
  @DeleteMapping("/{id}")
  public ApiResult<?> remove(@PathVariable("id") Integer id) {
    if (orderService.removeById(id)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }

  @ApiOperation("批量添加订单")
  @PostMapping("/batch")
  public ApiResult<?> saveBatch(@RequestBody List<Order> list) {
    if (orderService.saveBatch(list)) {
      return success("添加成功");
    }
    return fail("添加失败");
  }

  @ApiOperation("批量修改订单")
  @PutMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody BatchParam<Order> batchParam) {
    if (batchParam.update(orderService, "order_id")) {
      return success("修改成功");
    }
    return fail("修改失败");
  }

  @ApiOperation("批量删除订单")
  @DeleteMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
    if (orderService.removeByIds(ids)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }
}
