package com.dora.controller;

import com.dora.common.Result;
import com.dora.dto.MembershipPlanDto;
import com.dora.entity.MembershipPlan;
import com.dora.entity.Order;
import com.dora.mapper.MembershipPlanMapper;
import com.dora.mapper.OrderMapper;
import com.dora.util.OrderUtil;
import com.dora.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 会员套餐控制器
 */
@Slf4j
@RestController
@RequestMapping("/user/membership")
@RequiredArgsConstructor
@Tag(name = "会员套餐", description = "会员套餐相关接口")
public class MembershipController {

    private final MembershipPlanMapper membershipPlanMapper;
    private final OrderMapper orderMapper;

    /**
     * 获取可购买的套餐列表
     */
    @GetMapping("/plans")
    @Operation(summary = "获取套餐列表", description = "获取所有可购买的会员套餐")
    public Result<MembershipPlanDto.PlanListResponse> getAvailablePlans() {
        MembershipPlanDto.PlanListResponse response = new MembershipPlanDto.PlanListResponse();
        
        try {
            List<MembershipPlan> planList = membershipPlanMapper.selectAllActive();
            List<MembershipPlanDto.PlanInfo> planInfoList = new ArrayList<>();
            
            for (MembershipPlan plan : planList) {
                MembershipPlanDto.PlanInfo planInfo = new MembershipPlanDto.PlanInfo();
                planInfo.setId(plan.getId());
                planInfo.setName(plan.getName());
                planInfo.setDescription(plan.getDescription());
                planInfo.setPrice(plan.getPrice());
                planInfo.setDurationDays(plan.getDurationDays());
                planInfo.setTargetRole(plan.getTargetRole());
                planInfo.setTargetRoleName(getRoleName(plan.getTargetRole()));
                planInfo.setDiscountPercentage(plan.getDiscountPercentage());
                
                // 计算优惠后价格
                BigDecimal discountedPrice = calculateDiscountedPrice(plan.getPrice(), plan.getDiscountPercentage());
                planInfo.setDiscountedPrice(discountedPrice);
                planInfoList.add(planInfo);
            }
            
            response.setSuccess(true);
            response.setMessage("获取成功");
            response.setPlans(planInfoList);
            
            log.info("获取套餐列表成功，共{}个套餐", planInfoList.size());
            
        } catch (Exception e) {
            log.error("获取套餐列表失败", e);
            response.setSuccess(false);
            response.setMessage("获取失败：" + e.getMessage());
        }
        
        return Result.success(response);
    }

    /**
     * 购买套餐（创建订单）
     */
    @PostMapping("/purchase")
    @Operation(summary = "购买套餐", description = "选择套餐创建订单，返回订单信息用于支付")
    public Result<MembershipPlanDto.PurchaseResponse> purchaseMembership(
            @Validated @RequestBody MembershipPlanDto.PurchaseRequest request) {
        
        MembershipPlanDto.PurchaseResponse response = new MembershipPlanDto.PurchaseResponse();
        
        try {
            // 1. 验证用户登录状态
            Long userId = SecurityUtil.getCurrentUserId();
            if (userId == null) {
                response.setSuccess(false);
                response.setMessage("用户未登录");
                return Result.error("用户未登录");
            }
            
            // 2. 验证前端传入的必要参数
            if (request.getActualPrice() == null || request.getActualPrice().compareTo(BigDecimal.ZERO) <= 0) {
                response.setSuccess(false);
                response.setMessage("实际支付价格无效");
                return Result.error("实际支付价格无效");
            }
            
            if (request.getActualDurationDays() == null || request.getActualDurationDays() <= 0) {
                response.setSuccess(false);
                response.setMessage("会员时长无效");
                return Result.error("会员时长无效");
            }
            
            // 3. 验证套餐存在性和有效性
            MembershipPlan plan = membershipPlanMapper.selectById(request.getPlanId());
            if (plan == null) {
                response.setSuccess(false);
                response.setMessage("套餐不存在");
                return Result.error("套餐不存在");
            }
            
            if (!plan.getIsActive()) {
                response.setSuccess(false);
                response.setMessage("套餐已下架");
                return Result.error("套餐已下架");
            }
            
            // 4. 生成唯一订单号
            String orderNo = OrderUtil.generateOrderNo();
            
            // 5. 创建订单记录
            Order order = new Order();
            order.setOrderNo(orderNo);
            order.setUserId(userId);
            order.setPlanId(plan.getId());
            // 使用前端传入的实际支付价格
            order.setOriginalPrice(plan.getPrice());
            order.setAmount(request.getActualPrice());
            order.setActualDurationDays(request.getActualDurationDays());
            order.setDiscountType(request.getDiscountType() != null ? request.getDiscountType() : "NONE");
            order.setDiscountAmount(request.getDiscountAmount());
            order.setDiscountDescription(request.getDiscountDescription());
            order.setStatus(0); // 待支付
            order.setPaymentMethod(null); // 待选择支付方式
            order.setPaidAt(null);
            order.setCreateTime(LocalDateTime.now());
            order.setUpdateTime(LocalDateTime.now());
            order.setIsDeleted(0);
            
            int insertResult = orderMapper.insert(order);
            if (insertResult <= 0) {
                response.setSuccess(false);
                response.setMessage("订单创建失败");
                return Result.error("订单创建失败");
            }
            
            // 6. 构建套餐信息（显示实际的价格和时长）
            MembershipPlanDto.PlanInfo planInfo = new MembershipPlanDto.PlanInfo();
            planInfo.setId(plan.getId());
            planInfo.setName(plan.getName());
            planInfo.setDescription(plan.getDescription());
            planInfo.setPrice(request.getActualPrice()); // 使用实际支付价格
            planInfo.setDurationDays(request.getActualDurationDays()); // 使用实际会员时长
            planInfo.setTargetRole(plan.getTargetRole());
            planInfo.setTargetRoleName(getRoleName(plan.getTargetRole()));
            
            // 7. 返回订单信息
            response.setSuccess(true);
            response.setMessage("订单创建成功");
            response.setOrderNo(orderNo);
            response.setOrderId(order.getId());
            response.setAmount(request.getActualPrice()); // 使用实际支付价格
            response.setPlanInfo(planInfo);
            
            log.info("用户{}购买套餐{}成功，订单号：{}，原价：{}，实际支付：{}，优惠类型：{}，会员时长：{}天", 
                    userId, plan.getName(), orderNo, plan.getPrice(), request.getActualPrice(), 
                    request.getDiscountType(), request.getActualDurationDays());
            
        } catch (Exception e) {
            log.error("购买套餐失败，用户ID：{}，套餐ID：{}", 
                    SecurityUtil.getCurrentUserId(), request.getPlanId(), e);
            response.setSuccess(false);
            response.setMessage("购买失败：" + e.getMessage());
            return Result.error("购买失败：" + e.getMessage());
        }
        
        return Result.success(response);
    }

    /**
     * 计算优惠后价格
     * @param originalPrice 原价
     * @param discountPercentage 优惠百分比率
     * @return 优惠后价格
     */
    private BigDecimal calculateDiscountedPrice(BigDecimal originalPrice, BigDecimal discountPercentage) {
        if (originalPrice == null || discountPercentage == null) {
            return originalPrice;
        }
        
        if (discountPercentage.compareTo(BigDecimal.ZERO) <= 0) {
            return originalPrice;
        }
        
        // 计算优惠金额: 原价 * (优惠百分比 / 100)
        BigDecimal discountAmount = originalPrice.multiply(discountPercentage).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
        
        // 计算优惠后价格: 原价 - 优惠金额
        BigDecimal discountedPrice = originalPrice.subtract(discountAmount);
        
        // 确保优惠后价格不为负数
        return discountedPrice.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : discountedPrice;
    }
    
    /**
     * 获取角色名称
     * @param role 角色等级
     * @return 角色名称
     */
    private String getRoleName(Integer role) {
        if (role == null) return "未知";
        switch (role) {
            case 0: return "游客";
            case 1: return "普通";
            case 2: return "VIP";
            case 3: return "SVIP";
            default: return "未知";
        }
    }
}
