package com.gxwebsoft.shop.controller;

import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.shop.entity.ShopUserCoupon;
import com.gxwebsoft.shop.service.CouponStatusService;
import com.gxwebsoft.shop.service.CouponStatusService.CouponStatusResult;
import com.gxwebsoft.shop.service.CouponStatusService.CouponValidationResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

/**
 * 优惠券状态管理控制器
 *
 * @author WebSoft
 * @since 2025-01-15
 */
@Slf4j
@Tag(name = "优惠券状态管理")
@RestController
@RequestMapping("/api/shop/coupon-status")
public class CouponStatusController extends BaseController {

    @Autowired
    private CouponStatusService couponStatusService;

    @Operation(summary = "获取当前用户可用优惠券")
    @GetMapping("/available")
    public ApiResult<List<ShopUserCoupon>> getAvailableCoupons() {
        try {
            List<ShopUserCoupon> coupons = couponStatusService.getAvailableCoupons(getLoginUserId());
            return success("获取成功", coupons);
        } catch (Exception e) {
            log.error("获取可用优惠券失败", e);
            return fail("获取失败",null);
        }
    }

    @Operation(summary = "获取当前用户已使用优惠券")
    @GetMapping("/used")
    public ApiResult<List<ShopUserCoupon>> getUsedCoupons() {
        try {
            List<ShopUserCoupon> coupons = couponStatusService.getUsedCoupons(getLoginUserId());
            return success("获取成功", coupons);
        } catch (Exception e) {
            log.error("获取已使用优惠券失败", e);
            return fail("获取失败",null);
        }
    }

    @Operation(summary = "获取当前用户已过期优惠券")
    @GetMapping("/expired")
    public ApiResult<List<ShopUserCoupon>> getExpiredCoupons() {
        try {
            List<ShopUserCoupon> coupons = couponStatusService.getExpiredCoupons(getLoginUserId());
            return success("获取成功", coupons);
        } catch (Exception e) {
            log.error("获取已过期优惠券失败", e);
            return fail("获取失败",null);
        }
    }

    @Operation(summary = "获取当前用户所有优惠券（按状态分类）")
    @GetMapping("/all-grouped")
    public ApiResult<CouponStatusResult> getAllCouponsGrouped() {
        try {
            CouponStatusResult result = couponStatusService.getUserCouponsGroupByStatus(getLoginUserId());
            return success("获取成功", result);
        } catch (Exception e) {
            log.error("获取优惠券分类失败", e);
            return fail("获取失败",null);
        }
    }

    @Operation(summary = "验证优惠券是否可用于订单")
    @PostMapping("/validate")
    public ApiResult<CouponValidationResult> validateCouponForOrder(
            @Parameter(description = "用户优惠券ID") @RequestParam Long userCouponId,
            @Parameter(description = "订单总金额") @RequestParam BigDecimal totalAmount,
            @Parameter(description = "商品ID列表") @RequestBody List<Integer> goodsIds) {
        try {
            CouponValidationResult result = couponStatusService.validateCouponForOrder(
                    userCouponId, totalAmount, goodsIds);
            return success(result.getMessage(), result);
        } catch (Exception e) {
            log.error("验证优惠券失败", e);
            return fail("验证失败",null);
        }
    }

    @Operation(summary = "使用优惠券")
    @PostMapping("/use")
    public ApiResult<?> useCoupon(
            @Parameter(description = "用户优惠券ID") @RequestParam Long userCouponId,
            @Parameter(description = "订单ID") @RequestParam Integer orderId,
            @Parameter(description = "订单号") @RequestParam String orderNo) {
        try {
            boolean success = couponStatusService.useCoupon(userCouponId, orderId, orderNo);
            if (success) {
                return success("使用成功");
            } else {
                return fail("使用失败");
            }
        } catch (Exception e) {
            log.error("使用优惠券失败", e);
            return fail("使用失败");
        }
    }

    @Operation(summary = "退还优惠券（订单取消时）")
    @PostMapping("/return/{orderId}")
    public ApiResult<?> returnCoupon(
            @Parameter(description = "订单ID") @PathVariable Integer orderId) {
        try {
            boolean success = couponStatusService.returnCoupon(orderId);
            if (success) {
                return success("退还成功");
            } else {
                return fail("退还失败");
            }
        } catch (Exception e) {
            log.error("退还优惠券失败", e);
            return fail("退还失败");
        }
    }

    @PreAuthorize("hasAuthority('shop:coupon:manage')")
    @Operation(summary = "批量更新过期优惠券状态（管理员）")
    @PostMapping("/update-expired")
    public ApiResult<?> updateExpiredCoupons() {
        try {
            int updatedCount = couponStatusService.updateExpiredCoupons();
            return success("更新完成，共更新 " + updatedCount + " 张优惠券");
        } catch (Exception e) {
            log.error("批量更新过期优惠券失败", e);
            return fail("更新失败");
        }
    }

    @Operation(summary = "获取优惠券状态统计")
    @GetMapping("/statistics")
    public ApiResult<CouponStatistics> getCouponStatistics() {
        try {
            CouponStatusResult result = couponStatusService.getUserCouponsGroupByStatus(getLoginUserId());

            CouponStatistics statistics = new CouponStatistics();
            statistics.setAvailableCount(result.getAvailableCoupons().size());
            statistics.setUsedCount(result.getUsedCoupons().size());
            statistics.setExpiredCount(result.getExpiredCoupons().size());
            statistics.setTotalCount(result.getTotalCount());

            return success("获取成功", statistics);
        } catch (Exception e) {
            log.error("获取优惠券统计失败", e);
            return fail("获取失败",null);
        }
    }

    /**
     * 优惠券统计信息
     */
    public static class CouponStatistics {
        private int availableCount;  // 可用数量
        private int usedCount;       // 已使用数量
        private int expiredCount;    // 已过期数量
        private int totalCount;      // 总数量

        // Getters and Setters
        public int getAvailableCount() { return availableCount; }
        public void setAvailableCount(int availableCount) { this.availableCount = availableCount; }

        public int getUsedCount() { return usedCount; }
        public void setUsedCount(int usedCount) { this.usedCount = usedCount; }

        public int getExpiredCount() { return expiredCount; }
        public void setExpiredCount(int expiredCount) { this.expiredCount = expiredCount; }

        public int getTotalCount() { return totalCount; }
        public void setTotalCount(int totalCount) { this.totalCount = totalCount; }
    }
}
