package com.starry.admin.modules.weichat.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.starry.admin.common.aspect.CustomUserLogin;
import com.starry.admin.common.conf.ThreadLocalRequestDetail;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
import com.starry.admin.modules.shop.module.enums.CouponClaimConditionType;
import com.starry.admin.modules.shop.module.enums.CouponObtainChannel;
import com.starry.admin.modules.shop.module.enums.CouponOnlineState;
import com.starry.admin.modules.shop.module.enums.CouponValidityPeriodType;
import com.starry.admin.modules.shop.module.support.CouponInventoryPolicy;
import com.starry.admin.modules.shop.module.vo.PlayCommodityInfoVo;
import com.starry.admin.modules.shop.module.vo.PlayCouponDetailsReturnVo;
import com.starry.admin.modules.shop.service.IPlayCommodityInfoService;
import com.starry.admin.modules.shop.service.IPlayCouponDetailsService;
import com.starry.admin.modules.shop.service.IPlayCouponInfoService;
import com.starry.admin.modules.weichat.entity.WxCouponOrderQueryVo;
import com.starry.admin.modules.weichat.entity.WxCouponOrderReturnVo;
import com.starry.admin.modules.weichat.entity.WxCouponReceiveReturnVo;
import com.starry.common.result.R;
import com.starry.common.utils.ConvertUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * @author admin
 * @since 2024/7/4 11:33
 **/
@Api(tags = "微信优惠券接口", description = "微信端优惠券相关接口")
@Slf4j
@RestController
@RequestMapping("/wx/coupon/")
public class WxCouponController {

    @Resource
    IPlayCouponDetailsService couponDetailsService;

    @Resource
    IPlayClerkUserInfoService playClerkUserInfoService;

    @Resource
    IPlayCouponInfoService couponInfoService;

    @Resource
    private IPlayCommodityInfoService playCommodityInfoService;

    @ApiOperation(value = "领取优惠券", notes = "顾客领取指定ID的优惠券")
    @ApiImplicitParam(name = "id", value = "优惠券ID", required = true, dataType = "String", paramType = "query")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = Map.class),
            @ApiResponse(code = 500, message = "请求参数异常,优惠券ID不能为空")})
    @CustomUserLogin
    @GetMapping("/custom/obtainCoupon")
    public R queryAll(@RequestParam("id") String id) {
        PlayCustomUserInfoEntity customUserInfo = ThreadLocalRequestDetail.getCustomUserInfo();
        if (StrUtil.isEmpty(id)) {
            throw new CustomException("请求参数异常,优惠券ID不能为");
        }
        PlayCouponInfoEntity entity = couponInfoService.selectPlayCouponInfoById(id);
        String msg = couponInfoService.getReasonForNotObtainingCoupons(entity, customUserInfo);
        boolean success = StrUtil.isBlank(msg);
        if (success) {
            try {
                couponInfoService.claimCouponForCustom(entity.getId(), customUserInfo, CouponObtainChannel.SELF_SERVICE);
            } catch (CustomException ex) {
                success = false;
                msg = ex.getMessage();
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("success", success);
        result.put("msg", msg);
        return R.ok(result);
    }

    /**
     * 查询所有优惠券，以及本人是否可领取
     *
     * @return com.starry.common.result.R
     * @author admin
     * @since 2024/7/8 13:53
     **/
    @ApiOperation(value = "查询所有优惠券", notes = "查询所有优惠券并标记用户是否已领取")
    @ApiResponses({
            @ApiResponse(code = 200, message = "操作成功", response = WxCouponReceiveReturnVo.class, responseContainer = "List")})
    @CustomUserLogin
    @PostMapping("/custom/queryAll")
    public R queryAll() {
        String currentCustomId = ThreadLocalRequestDetail.getCustomUserInfo().getId();
        List<PlayCouponDetailsReturnVo> obtainedCoupons = couponDetailsService
                .selectByCustomId(currentCustomId);
        List<PlayCouponInfoEntity> couponInfoEntities = couponInfoService.queryAll();
        LocalDateTime now = LocalDateTime.now();
        List<WxCouponReceiveReturnVo> returnVos = new ArrayList<>(couponInfoEntities.size());
        for (PlayCouponInfoEntity couponInfoEntity : couponInfoEntities) {
            boolean online = CouponOnlineState.fromCode(couponInfoEntity.getCouponOnLineState())
                    .map(state -> state == CouponOnlineState.ONLINE)
                    .orElse(false);
            if (!online) {
                continue;
            }
            CouponInventoryPolicy inventoryPolicy = CouponInventoryPolicy
                    .resolve(couponInfoEntity.getCouponQuantity(), couponInfoEntity.getRemainingQuantity());
            if (!inventoryPolicy.hasStock(couponInfoEntity.getRemainingQuantity())) {
                continue;
            }
            CouponValidityPeriodType validityType = CouponValidityPeriodType
                    .fromCode(couponInfoEntity.getValidityPeriodType())
                    .orElse(CouponValidityPeriodType.PERMANENT);
            if (validityType == CouponValidityPeriodType.FIXED_RANGE) {
                if (couponInfoEntity.getProductiveTime() != null
                        && now.isBefore(couponInfoEntity.getProductiveTime())) {
                    continue;
                }
                if (couponInfoEntity.getExpirationTime() != null
                        && now.isAfter(couponInfoEntity.getExpirationTime())) {
                    continue;
                }
            } else if (validityType == CouponValidityPeriodType.RELATIVE_DAYS) {
                Integer effectiveDay = couponInfoEntity.getEffectiveDay();
                if (effectiveDay == null || effectiveDay <= 0) {
                    continue;
                }
                // RELATIVE_DAYS 按领取时间计算，这里仅进行配置有效性校验，实际过期由详情校验处理
            }
            // 领取白名单：非白名单用户不可见
            if (CouponClaimConditionType.WHITELIST.code().equals(couponInfoEntity.getClaimConditionType())) {
                List<String> wl = couponInfoEntity.getCustomWhitelist();
                if (wl == null || !wl.contains(currentCustomId)) {
                    continue;
                }
            }
            WxCouponReceiveReturnVo vo = ConvertUtil.entityToVo(couponInfoEntity, WxCouponReceiveReturnVo.class);
            for (PlayCouponDetailsReturnVo obtainedCoupon : obtainedCoupons) {
                if (obtainedCoupon.getCouponId().equals(couponInfoEntity.getId())) {
                    vo.setObtained("1");
                }
            }
            returnVos.add(vo);
        }
        return R.ok(returnVos);
    }

    /**
     * 顾客查询订单可使用优惠券
     */
    @ApiOperation(value = "查询订单可用优惠券", notes = "查询当前订单可使用的优惠券列表")
    @ApiResponses({
            @ApiResponse(code = 200, message = "操作成功", response = WxCouponOrderReturnVo.class, responseContainer = "List"),
            @ApiResponse(code = 500, message = "请求参数异常,店员ID不能为空,等级ID不能为空")})
    @CustomUserLogin
    @PostMapping("/custom/queryByOrder")
    public R queryByOrder(
            @ApiParam(value = "订单查询条件", required = true) @Validated @RequestBody WxCouponOrderQueryVo vo) {
        if (vo.getLevelId().isEmpty() && vo.getClerkId().isEmpty()) {
            throw new CustomException("请求参数异常,店员ID不能为空,等级ID不能为空");
        }
        String levelId = vo.getLevelId();
        if (!vo.getClerkId().isEmpty()) {
            PlayClerkUserInfoEntity clerkUserInfo = playClerkUserInfoService.selectById(vo.getClerkId());
            levelId = clerkUserInfo.getLevelId();
        }
        log.info(JSON.toJSONString(vo));
        List<PlayCouponDetailsReturnVo> list = couponDetailsService
                .selectByCustomId(ThreadLocalRequestDetail.getCustomUserInfo().getId());
        PlayCommodityInfoVo commodityInfo = playCommodityInfoService.queryCommodityInfo(vo.getCommodityId(), levelId);
        // 优惠券列表
        List<WxCouponOrderReturnVo> couponReturnVos = new ArrayList<>();
        for (PlayCouponDetailsReturnVo couponDetails : list) {
            try {
                PlayCouponInfoEntity couponInfo = couponInfoService.selectPlayCouponInfoById(couponDetails.getCouponId());
                WxCouponOrderReturnVo wxCouponReturnVo = ConvertUtil.entityToVo(couponDetails, WxCouponOrderReturnVo.class);
                Optional<String> statusReason = couponInfoService.getCouponDetailRestrictionReason(
                        couponInfo,
                        couponDetails.getUseState(),
                        couponDetails.getObtainingTime());
                if (statusReason.isPresent()) {
                    // 已使用、过期、下架等状态的优惠券不展示
                    continue;
                }
                String couponReasonForUnavailableUse = couponInfoService.getCouponReasonForUnavailableUse(couponInfo,
                        vo.getPlaceType(), vo.getCommodityId(), vo.getCommodityQuantity(),
                        commodityInfo.getCommodityPrice());
                if (StrUtil.isEmpty(couponReasonForUnavailableUse)) {
                    wxCouponReturnVo.setAvailable("1");
                } else {
                    wxCouponReturnVo.setAvailable("0");
                    wxCouponReturnVo.setReasonForUnavailableUse(couponReasonForUnavailableUse);
                }
                couponReturnVos.add(wxCouponReturnVo);
            } catch (Exception e) {

            }

        }
        return R.ok(couponReturnVos);
    }

}
