package com.ruoyi.app.user;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.dto.PromotionCalcRequest;
import com.ruoyi.system.dto.PromotionCalcResponse;
import com.ruoyi.system.service.IPromotionCalcService;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.JwtUtil;

/**
 * 用户端优惠计算接口
 *
 * 【优惠叠加规则】
 * 1. 一个订单最多使用 1个促销 + 1张优惠券 + 新客立减(如适用)
 * 2. 促销三选一(满减/折扣/第二份半价)，系统自动算两条路径选最优，用户可手动切换(forcePath)
 * 3. 优惠券每单只能用一张(couponId 传单个值，不是数组)
 * 4. 同享券可与促销叠加，互斥券与促销二选一
 * 5. 商品券对应的商品如在折扣/第二份半价活动中，该券不可用于该商品
 * 6. 计算顺序：商品原价 → 促销(三选一) → 优惠券 → 新客立减 → 实付金额(最低¥0.01)
 *
 * 【入参说明】
 * storeId   (必填) 门店ID
 * items     (必填) 购物车商品列表 [{productId, quantity, specPrice}]，不传商品价格，后端从数据库查；
 *           specPrice(选填)规格加价，可为0或不传，实付单价=商品价格+规格价格
 * couponId  (选填) 用户要使用的优惠券ID，对应 promotion_user_coupon.id，每单只能用一张
 * forcePath (选填) 强制指定路径 "A"(折扣/第二份半价) 或 "B"(满减)，不传则系统自动选最优
 *
 * 【调用场景】
 * - 进入结算页：不传 forcePath、不传 couponId → 返回两条路径对比 + 最优方案 + 可用券列表
 * - 用户切换促销方案：传 forcePath → 强制走用户选的路径
 * - 用户选了优惠券：传 couponId + forcePath(如有偏好) → 在当前路径基础上叠券计算
 */
@RestController
@RequestMapping("/app/userPromotionCalc")
public class UserPromotionCalcController extends BaseController {

    @Autowired
    private IPromotionCalcService promotionCalcService;

    /**
     * 计算订单优惠
     *
     * @param token   用户登录token
     * @param request 算价请求DTO
     * @return PromotionCalcResponse 含 originalAmount, pathA, pathB, optimalPath, finalAmount, details, availableCoupons
     */
    @Anonymous
    @Auth
    @PostMapping("/calculate")
    public AjaxResult calculate(@RequestHeader String token, @RequestBody PromotionCalcRequest request) {
        JwtUtil jwtUtil = new JwtUtil();
        String userId = jwtUtil.getusid(token);
        if (userId == null) {
            return AjaxResult.error("请先登录");
        }
        if (request.getStoreId() == null) {
            return AjaxResult.error("参数错误：缺少storeId");
        }
        if (request.getItems() == null || request.getItems().isEmpty()) {
            return AjaxResult.error("参数错误：缺少items");
        }

        PromotionCalcResponse result = promotionCalcService.calculate(request, Long.valueOf(userId));
        return AjaxResult.success("",result);
    }
}
