package com.ycwl.basic.pricing.service.impl;

import com.ycwl.basic.pricing.dto.*;
import com.ycwl.basic.pricing.entity.PriceProductConfig;
import com.ycwl.basic.pricing.entity.PriceTierConfig;
import com.ycwl.basic.pricing.enums.ProductType;
import com.ycwl.basic.pricing.exception.PriceCalculationException;
import com.ycwl.basic.pricing.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 价格计算服务实现
 */
@Slf4j
@Service("pricingCalculationServiceImpl")
@RequiredArgsConstructor
public class PriceCalculationServiceImpl implements IPriceCalculationService {
    
    private final IProductConfigService productConfigService;
    private final ICouponService couponService;
    private final IPriceBundleService bundleService;
    private final IDiscountDetectionService discountDetectionService;
    private final IVoucherService voucherService;
    
    @Override
    public PriceCalculationResult calculatePrice(PriceCalculationRequest request) {
        if (request.getProducts() == null || request.getProducts().isEmpty()) {
            throw new PriceCalculationException("商品列表不能为空");
        }
        
        // 计算商品价格和原价
        PriceDetails priceDetails = calculateProductsPriceWithOriginal(request.getProducts());
        BigDecimal totalAmount = priceDetails.getTotalAmount();
        BigDecimal originalTotalAmount = priceDetails.getOriginalTotalAmount();
        
        List<DiscountDetail> discountDetails = new ArrayList<>();
        
        // 添加限时立减折扣（如果原价 > 实际价格）
        BigDecimal limitedTimeDiscount = originalTotalAmount.subtract(totalAmount);
        if (limitedTimeDiscount.compareTo(BigDecimal.ZERO) > 0) {
            discountDetails.add(DiscountDetail.createLimitedTimeDiscount(limitedTimeDiscount));
        }
        
        // 检查一口价优惠
        BigDecimal bundlePrice = bundleService.getBundlePrice(request.getProducts());
        if (bundlePrice != null && bundlePrice.compareTo(totalAmount) < 0) {
            BigDecimal bundleDiscount = totalAmount.subtract(bundlePrice);
            discountDetails.add(DiscountDetail.createBundleDiscount(bundleDiscount));
            totalAmount = bundlePrice;
            log.info("使用一口价: {}, 优惠: {}", bundlePrice, bundleDiscount);
        }
        
        // 构建价格计算结果
        PriceCalculationResult result = new PriceCalculationResult();
        result.setOriginalAmount(originalTotalAmount); // 原总价
        result.setSubtotalAmount(priceDetails.getTotalAmount()); // 商品小计
        result.setProductDetails(request.getProducts());
        
        // 使用新的优惠检测系统处理所有优惠（券码 + 优惠券）
        DiscountCombinationResult discountResult = calculateDiscounts(request, totalAmount);
        
        if (Boolean.TRUE.equals(discountResult.getSuccess())) {
            // 合并所有优惠详情
            List<DiscountDetail> allDiscountDetails = new ArrayList<>(discountDetails);
            if (discountResult.getDiscountDetails() != null) {
                allDiscountDetails.addAll(discountResult.getDiscountDetails());
            }
            
            // 重新排序
            allDiscountDetails.sort(Comparator.comparing(DiscountDetail::getSortOrder));
            
            // 计算总优惠金额（包括限时立减、一口价和其他优惠）
            BigDecimal totalDiscountAmount = allDiscountDetails.stream()
                .map(DiscountDetail::getDiscountAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            // 设置结果
            result.setDiscountAmount(totalDiscountAmount);
            result.setDiscountDetails(allDiscountDetails);
            result.setFinalAmount(originalTotalAmount.subtract(totalDiscountAmount));
            
            // 设置使用的券码和优惠券信息
            setUsedDiscountInfo(result, discountResult, request);
            
            // 如果是预览模式，设置可用优惠列表
            if (Boolean.TRUE.equals(request.getPreviewOnly())) {
                result.setAvailableDiscounts(discountResult.getAvailableDiscounts());
            }
            
        } else {
            log.warn("优惠计算失败: {}", discountResult.getErrorMessage());
            
            // 降级处理：仅使用基础优惠（限时立减、一口价）
            BigDecimal totalDiscountAmount = discountDetails.stream()
                .map(DiscountDetail::getDiscountAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            result.setDiscountAmount(totalDiscountAmount);
            result.setDiscountDetails(discountDetails);
            result.setFinalAmount(originalTotalAmount.subtract(totalDiscountAmount));
        }
        
        // 标记使用的优惠（仅在非预览模式下）
        if (!Boolean.TRUE.equals(request.getPreviewOnly())) {
            markDiscountsAsUsed(result, request);
        }
        
        return result;
    }
    
    private BigDecimal calculateProductsPrice(List<ProductItem> products) {
        BigDecimal totalAmount = BigDecimal.ZERO;
        
        for (ProductItem product : products) {
            BigDecimal itemPrice = calculateSingleProductPrice(product);
            product.setUnitPrice(itemPrice);
            
            BigDecimal subtotal = itemPrice.multiply(BigDecimal.valueOf(product.getPurchaseCount()));
            product.setSubtotal(subtotal);
            
            totalAmount = totalAmount.add(subtotal);
        }
        
        return totalAmount.setScale(2, RoundingMode.HALF_UP);
    }
    
    private PriceDetails calculateProductsPriceWithOriginal(List<ProductItem> products) {
        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal originalTotalAmount = BigDecimal.ZERO;
        
        for (ProductItem product : products) {
            // 计算实际价格和原价
            ProductPriceInfo priceInfo = calculateSingleProductPriceWithOriginal(product);
            
            product.setUnitPrice(priceInfo.getActualPrice());
            product.setOriginalPrice(priceInfo.getOriginalPrice());
            
            BigDecimal subtotal = priceInfo.getActualPrice().multiply(BigDecimal.valueOf(product.getPurchaseCount()));
            BigDecimal originalSubtotal = priceInfo.getOriginalPrice().multiply(BigDecimal.valueOf(product.getPurchaseCount()));
            
            product.setSubtotal(subtotal);
            
            totalAmount = totalAmount.add(subtotal);
            originalTotalAmount = originalTotalAmount.add(originalSubtotal);
        }
        
        return new PriceDetails(
                totalAmount.setScale(2, RoundingMode.HALF_UP),
                originalTotalAmount.setScale(2, RoundingMode.HALF_UP)
        );
    }
    
    private BigDecimal calculateSingleProductPrice(ProductItem product) {
        ProductType productType = product.getProductType();
        String productId = product.getProductId() != null ? product.getProductId() : "default";
        
        // 优先使用基于product_id的阶梯定价
        PriceTierConfig tierConfig = productConfigService.getTierConfig(
                productType.getCode(), productId, product.getQuantity());
        
        if (tierConfig != null) {
            log.debug("使用阶梯定价: productType={}, productId={}, quantity={}, price={}", 
                    productType.getCode(), productId, product.getQuantity(), tierConfig.getPrice());
            return tierConfig.getPrice();
        }
        
        // 使用基于product_id的基础配置
        try {
            PriceProductConfig baseConfig = productConfigService.getProductConfig(productType.getCode(), productId);
            if (baseConfig != null) {
                if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
                    return baseConfig.getBasePrice().multiply(BigDecimal.valueOf(product.getQuantity()));
                } else {
                    return baseConfig.getBasePrice();
                }
            }
        } catch (Exception e) {
            log.warn("未找到具体商品配置: productType={}, productId={}, 尝试使用通用配置", 
                    productType, productId);
        }
        
        // 兜底：使用default配置
        try {
            PriceProductConfig defaultConfig = productConfigService.getProductConfig(productType.getCode(), "default");
            if (defaultConfig != null) {
                if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
                    return defaultConfig.getBasePrice().multiply(BigDecimal.valueOf(product.getQuantity()));
                } else {
                    return defaultConfig.getBasePrice();
                }
            }
        } catch (Exception e) {
            log.warn("未找到default配置: productType={}", productType.getCode());
        }
        
        // 最后兜底：使用通用配置（向后兼容）
        List<PriceProductConfig> configs = productConfigService.getProductConfig(productType.getCode());
        if (!configs.isEmpty()) {
            PriceProductConfig baseConfig = configs.get(0); // 使用第一个配置作为默认
            if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
                return baseConfig.getBasePrice().multiply(BigDecimal.valueOf(product.getQuantity()));
            } else {
                return baseConfig.getBasePrice();
            }
        }
        
        throw new PriceCalculationException("无法计算商品价格: " + productType.getDescription() + ", productId: " + productId);
    }
    
    private ProductPriceInfo calculateSingleProductPriceWithOriginal(ProductItem product) {
        ProductType productType = product.getProductType();
        String productId = product.getProductId() != null ? product.getProductId() : "default";
        
        BigDecimal actualPrice;
        BigDecimal originalPrice = null;
        
        // 优先使用基于product_id的阶梯定价
        PriceTierConfig tierConfig = productConfigService.getTierConfig(
                productType.getCode(), productId, product.getQuantity());
        
        if (tierConfig != null) {
            actualPrice = tierConfig.getPrice();
            originalPrice = tierConfig.getOriginalPrice();
            log.debug("使用阶梯定价: productType={}, productId={}, quantity={}, price={}, originalPrice={}", 
                    productType.getCode(), productId, product.getQuantity(), actualPrice, originalPrice);
        } else {
            // 使用基于product_id的基础配置
            try {
                PriceProductConfig baseConfig = productConfigService.getProductConfig(productType.getCode(), productId);
                if (baseConfig != null) {
                    actualPrice = baseConfig.getBasePrice();
                    originalPrice = baseConfig.getOriginalPrice();
                    
                    if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
                        actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
                        if (originalPrice != null) {
                            originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
                        }
                    }
                } else {
                    throw new PriceCalculationException("无法找到具体商品配置");
                }
            } catch (Exception e) {
                log.warn("未找到具体商品配置: productType={}, productId={}, 尝试使用通用配置", 
                        productType, productId);
                
                // 兜底：使用default配置
                try {
                    PriceProductConfig defaultConfig = productConfigService.getProductConfig(productType.getCode(), "default");
                    if (defaultConfig != null) {
                        actualPrice = defaultConfig.getBasePrice();
                        originalPrice = defaultConfig.getOriginalPrice();
                        
                        if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
                            actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
                            if (originalPrice != null) {
                                originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
                            }
                        }
                    } else {
                        throw new PriceCalculationException("无法找到default配置");
                    }
                } catch (Exception defaultEx) {
                    log.warn("未找到default配置: productType={}", productType.getCode());
                    
                    // 最后兜底：使用通用配置（向后兼容）
                    List<PriceProductConfig> configs = productConfigService.getProductConfig(productType.getCode());
                    if (!configs.isEmpty()) {
                        PriceProductConfig baseConfig = configs.getFirst(); // 使用第一个配置作为默认
                        actualPrice = baseConfig.getBasePrice();
                        originalPrice = baseConfig.getOriginalPrice();
                        
                        if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
                            actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
                            if (originalPrice != null) {
                                originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
                            }
                        }
                    } else {
                        throw new PriceCalculationException("无法计算商品价格: " + productType.getDescription() + ", productId: " + productId);
                    }
                }
            }
        }
        
        return new ProductPriceInfo(actualPrice, originalPrice);
    }
    
    /**
     * 计算优惠（券码 + 优惠券）
     */
    private DiscountCombinationResult calculateDiscounts(PriceCalculationRequest request, BigDecimal currentAmount) {
        try {
            // 构建优惠检测上下文
            DiscountDetectionContext context = new DiscountDetectionContext();
            context.setUserId(request.getUserId());
            context.setFaceId(request.getFaceId());
            context.setScenicId(request.getScenicId());
            context.setProducts(request.getProducts());
            context.setCurrentAmount(currentAmount);
            context.setVoucherCode(request.getVoucherCode());
            context.setAutoUseCoupon(request.getAutoUseCoupon());
            context.setAutoUseVoucher(request.getAutoUseVoucher());
            
            // 使用优惠检测服务计算最优组合
            if (Boolean.TRUE.equals(request.getPreviewOnly())) {
                return discountDetectionService.previewOptimalCombination(context);
            } else {
                return discountDetectionService.calculateOptimalCombination(context);
            }
            
        } catch (Exception e) {
            log.error("计算优惠时发生异常", e);
            
            // 返回失败结果
            DiscountCombinationResult failureResult = new DiscountCombinationResult();
            failureResult.setOriginalAmount(currentAmount);
            failureResult.setFinalAmount(currentAmount);
            failureResult.setTotalDiscountAmount(BigDecimal.ZERO);
            failureResult.setSuccess(false);
            failureResult.setErrorMessage("优惠计算失败: " + e.getMessage());
            return failureResult;
        }
    }
    
    /**
     * 设置使用的优惠信息到结果中
     */
    private void setUsedDiscountInfo(PriceCalculationResult result, DiscountCombinationResult discountResult, PriceCalculationRequest request) {
        if (discountResult.getAppliedDiscounts() == null) {
            return;
        }
        
        for (DiscountResult discountApplied : discountResult.getAppliedDiscounts()) {
            DiscountInfo discountInfo = discountApplied.getDiscountInfo();
            
            if ("COUPON".equals(discountInfo.getProviderType()) && discountInfo.getCouponId() != null) {
                // 构建优惠券信息（这里可能需要重新查询完整信息）
                CouponInfo couponInfo = new CouponInfo();
                couponInfo.setCouponId(discountInfo.getCouponId());
                couponInfo.setCouponName(discountInfo.getDiscountName());
                couponInfo.setActualDiscountAmount(discountApplied.getActualDiscountAmount());
                result.setUsedCoupon(couponInfo);
                
            } else if ("VOUCHER".equals(discountInfo.getProviderType()) && discountInfo.getVoucherCode() != null) {
                // 获取券码信息
                VoucherInfo voucherInfo = voucherService.validateAndGetVoucherInfo(
                    discountInfo.getVoucherCode(), 
                    request.getFaceId(),
                    request.getScenicId()
                );
                if (voucherInfo != null) {
                    voucherInfo.setActualDiscountAmount(discountApplied.getActualDiscountAmount());
                    result.setUsedVoucher(voucherInfo);
                }
            }
        }
    }
    
    /**
     * 标记优惠为已使用（仅在非预览模式下调用）
     */
    private void markDiscountsAsUsed(PriceCalculationResult result, PriceCalculationRequest request) {
        try {
            // 标记券码为已使用
            if (result.getUsedVoucher() != null && result.getUsedVoucher().getVoucherCode() != null) {
                String remark = String.format("价格计算使用 - 订单金额: %s", result.getFinalAmount());
                voucherService.markVoucherAsUsed(result.getUsedVoucher().getVoucherCode(), remark);
                log.info("已标记券码为使用: {}", result.getUsedVoucher().getVoucherCode());
            }
            
            // 优惠券的使用标记由原有的CouponService处理
            // 这里不需要额外处理
            
        } catch (Exception e) {
            log.error("标记优惠使用状态时发生异常", e);
            // 不抛出异常，避免影响主流程
        }
    }
}