package com.qs.mp.web.controller.api.user;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.admin.domain.Ticket;
import com.qs.mp.admin.domain.vo.TicketListVO;
import com.qs.mp.admin.service.IGoodsService;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.page.TableDataInfo;
import com.qs.mp.common.enums.*;
import com.qs.mp.common.utils.DateUtils;
import com.qs.mp.common.utils.StringUtils;
import com.qs.mp.user.domain.UserCoin;
import com.qs.mp.user.domain.UserCoinLog;
import com.qs.mp.user.domain.UserCoupon;
import com.qs.mp.user.domain.UserPrizeStorage;
import com.qs.mp.user.domain.param.UserPrizeStorageQueryParam;
import com.qs.mp.user.domain.param.UserPrizeStorageUpdateParam;
import com.qs.mp.user.domain.vo.UserCouponVO;
import com.qs.mp.user.domain.vo.UserPrizeStorageVO;
import com.qs.mp.user.service.IUserCoinLogService;
import com.qs.mp.user.service.IUserCoinService;
import com.qs.mp.user.service.IUserCouponService;
import com.qs.mp.user.service.IUserPrizeStorageService;
import com.qs.mp.user.service.IUserTicketOrderItemService;
import com.qs.mp.utils.SecurityUtils;
import com.qs.mp.web.controller.common.BaseApiController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/api/v1/mp/user/mine")
@Api(tags = "我的接口")
@AllArgsConstructor
public class UserMineController extends BaseApiController {


  @Autowired
  private IUserTicketOrderItemService userTicketOrderItemService;

  @Autowired
  private IUserPrizeStorageService userPrizeStorageService;

  @Autowired
  private IUserCoinService userCoinService;

  @Autowired
  private IUserCouponService userCouponService;

  @Autowired
  private IUserCoinLogService userCoinLogService;

  @Autowired
  private MapperFacade mapperFacade;

  @Autowired
  private IGoodsService goodsService;

  /**
   * 我的票包
   */
  @PostMapping("/ticket/list")
  @ApiOperation(value = "我的盲票列表", notes = "获取我的盲票列表")
  @ApiResponses(
          @ApiResponse(code = 200, message = "成功", response = TicketListVO.class)
  )
  public TableDataInfo listTicket(@RequestBody Ticket param) {
    Long userId = SecurityUtils.getLoginUser().getUserId();
    startPage();
    List<TicketListVO> ticketListVOS = userTicketOrderItemService.listMyTicketVO(userId,
        param.getStatus());


    // 已兑奖的盲豆奖品需要拼接数量
    if (TicketStatusEnum.CASHED.equals(param.getStatus())) {
      for (TicketListVO ticketListVO : ticketListVOS) {
        if (StringUtils.isBlank(ticketListVO.getPrizeInfo())) {
          continue;
        }
        // 如果为盲豆需要拼接数量
        if (TicketPrizeTypeEnum.COIN.getValue().equals(ticketListVO.getPrizeType())) {
          ticketListVO.setPrizeInfo(ticketListVO.getPrizeInfo() + ticketListVO.getValue() + "个");
        }
      }
    }
    return getDataTable(ticketListVOS);
  }

  /**
   * 我的优惠券
   */
  @PostMapping("/coupon/list")
  @ApiOperation(value = "我的优惠券列表", notes = "获取我的优惠券列表")
  public TableDataInfo listCoupon(@RequestBody UserCoupon param) {
    Long userId = SecurityUtils.getLoginUser().getUserId();
    startPage();
    List<UserCouponVO> userCouponVOList = userCouponService.listCoupon(userId, param.getStatus());
    return getDataTable(userCouponVOList);
  }

  /**
   * 优惠券详情
   */
  @PostMapping("/coupon/detail")
  @ApiOperation(value = "优惠券详情", notes = "获取我的优惠券详情")
  public AjaxResult getCouponInfo(@RequestBody UserCoupon param) {
    Long userId = SecurityUtils.getLoginUser().getUserId();
    List<UserCouponVO> userCouponVOList = userCouponService.listUserCouponVO(new QueryWrapper<UserCoupon>()
        .eq("t1.id", param.getId())
        .eq("t1.user_id", userId));
    if (!CollectionUtils.isEmpty(userCouponVOList)) {
      return AjaxResult.success(userCouponVOList.get(0));
    }
    return AjaxResult.error("优惠券不存在");
  }

  /**
   * 我的盲豆
   */
  @PostMapping("/coin/log/list")
  @ApiOperation(value = "我的盲豆记录", notes = "获取我的盲豆记录")
  public TableDataInfo listCoinLog(@RequestBody JSONObject param) {
    Long userId = SecurityUtils.getLoginUser().getUserId();
    startPage();
    List<UserCoinLog> userCoinLogList = userCoinLogService.list(
        new LambdaQueryWrapper<UserCoinLog>()
            .eq(UserCoinLog::getUserId, userId).orderByDesc(UserCoinLog::getBizTime));
    return getDataTable(userCoinLogList);
  }

  /**
   * 我的实物奖品库
   */
  @PostMapping("/prize/list")
  @ApiOperation(value = "我的实物奖品库", notes = "获取我的实物奖品库")
  @ApiResponses(
          @ApiResponse(code = 200, message = "成功", response = UserPrizeStorageVO.class)
  )
  public TableDataInfo listPrize(@RequestBody JSONObject param) {
    Long userId = SecurityUtils.getLoginUser().getUserId();
    startPage();
    QueryWrapper<UserPrizeStorage> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("t1.user_id", userId);
    queryWrapper.eq("t1.status", PrizeStorageStatusEnum.NOT_DISTRIBUTED);
    queryWrapper.orderByDesc("t1.created_time");
    List<UserPrizeStorageVO> userPrizeStorageVOList = userPrizeStorageService.listByQueryWrapper(queryWrapper);
    return getDataTable(userPrizeStorageVOList);
  }


  @PostMapping("/prize/saveSku")
  @ApiOperation("设置实物奖品的SKU")
  @ApiResponses(
          @ApiResponse(code = 200, message = "success")
  )
  public AjaxResult saveSku(@Validated @RequestBody UserPrizeStorageUpdateParam userPrizeStorageUpdateParam) {
    UserPrizeStorage userPrizeStorage = userPrizeStorageService.getById(userPrizeStorageUpdateParam.getStorageId());
    if (userPrizeStorage == null) {
      return AjaxResult.error("奖品存储ID不正确");
    }

    if (PrizeStorageInTypeEnum.COIN_EXCHANGE.equals(userPrizeStorage.getInType())) {
      return AjaxResult.error("当前来源不支持选择规格");
    }

    if (userPrizeStorage.getSkuId() != null) {
      return AjaxResult.error("非法调用,已存在规格");
    }

    // 保存商品的sku信息
    boolean rtn = userPrizeStorageService.update(new LambdaUpdateWrapper<UserPrizeStorage>()
            .set(UserPrizeStorage::getSkuId, userPrizeStorageUpdateParam.getSkuId())
            .set(UserPrizeStorage::getProperties, userPrizeStorageUpdateParam.getProperties())
            .eq(UserPrizeStorage::getStorageId, userPrizeStorageUpdateParam.getStorageId()));
    if (!rtn) {
      return AjaxResult.error("保存规格失败,请重试");
    }

    return AjaxResult.success();
  }


  /**
   * 我的
   */
  @PostMapping("/init")
  @ApiOperation(value = "查看我的", notes = "查看我的")
  public AjaxResult getInfo(@RequestBody JSONObject param) {
    Long userId = SecurityUtils.getLoginUser().getUserId();
    Map<String, Object> storageMap = userPrizeStorageService.getMap(
        new QueryWrapper<UserPrizeStorage>()
            .select("count(IFNULL(goods_num,0)) as total")
            .eq("user_id", userId).eq("status", PrizeStorageStatusEnum.NOT_DISTRIBUTED));
    int couponCnt = userCouponService.count(new LambdaQueryWrapper<UserCoupon>()
            .eq(UserCoupon::getUserId, userId)
        .eq(UserCoupon::getStatus, UserCouponStatusEnum.UNUSED)
        .le(UserCoupon::getValidStart, DateUtils.getToday())
        .ge(UserCoupon::getValidEnd, DateUtils.getToday()));
    JSONObject result = new JSONObject();
    result.put("prizeNum", Integer.valueOf(String.valueOf(null != storageMap ? storageMap.get("total") : 0)) + couponCnt);

    int ticketNum = userTicketOrderItemService.countMyTicket(userId, null);
    result.put("ticketNum", ticketNum);

    UserCoin userCoin = userCoinService.getById(userId);
    result.put("coinNum", null != userCoin ? userCoin.getCoin() : 0);
    return AjaxResult.success(result);
  }

}
