
export interface PricingRule {
  marginTargetPct: number;
  marginMinPct: number;
  rounding: {
    type: "NONE" | "END_WITH" | "NEAREST_INT" | "MULTIPLE_OF";
    cents?: number;
    step?: number;
  };
  qtyTiers?: Array<{
    minQty: number;
    maxQty?: number;
    marginTargetPct: number;
  }>;
}

export const DEFAULT_PRICING_RULE: PricingRule = {
  marginTargetPct: 50,
  marginMinPct: 35,
  rounding: { type: "END_WITH", cents: 90 },
};

export interface PricingSuggestion {
  suggestedPrice: number;
  marginResultPct: number;
  warnings: string[];
}

export function getPriceSuggestion(
  costTotal: number,
  quantity: number,
  rule: PricingRule = DEFAULT_PRICING_RULE
): PricingSuggestion {
  const warnings: string[] = [];

  if (costTotal <= 0) {
    warnings.push("Custo total é zero ou negativo.");
    return { suggestedPrice: 0, marginResultPct: 0, warnings };
  }

  // 1. Determine target margin
  let targetMargin = rule.marginTargetPct;

  if (rule.qtyTiers && rule.qtyTiers.length > 0) {
    // Find matching tier
    // Sort tiers by minQty desc to find the highest applicable tier first?
    // Actually, usually we look for the range where minQty <= qty <= maxQty
    const sortedTiers = [...rule.qtyTiers].sort((a, b) => b.minQty - a.minQty);
    
    const matchedTier = sortedTiers.find((tier) => {
      if (quantity < tier.minQty) return false;
      if (tier.maxQty !== undefined && quantity > tier.maxQty) return false;
      return true;
    });

    if (matchedTier) {
      targetMargin = matchedTier.marginTargetPct;
    }
  }

  // Clamp margin to avoid division by zero or negative price logic issues (max 95%)
  if (targetMargin >= 95) targetMargin = 95;
  if (targetMargin < 0) targetMargin = 0; // Should not happen usually

  // 2. Calculate raw price
  // Price = Cost / (1 - Margin%)
  const rawPrice = costTotal / (1 - targetMargin / 100);

  // 3. Apply rounding
  let finalPrice = rawPrice;
  const { rounding } = rule;

  if (rounding.type === "NEAREST_INT") {
    finalPrice = Math.round(rawPrice);
  } else if (rounding.type === "END_WITH") {
    // e.g. 90 cents
    const cents = rounding.cents ?? 90;
    const integerPart = Math.floor(rawPrice);
    // If raw is 10.20 and we want .90 -> 10.90
    // If raw is 10.95 and we want .90 -> 10.90? Or 11.90?
    // Usually "end with" implies rounding up or nearest to that ending.
    // Let's implement a simple "floor + cents/100" logic first, but ensure it's not lower than rawPrice significantly?
    // Actually, common retail strategy: 
    // If raw is 10.10, maybe 9.90 is too low? Maybe 10.90.
    // Let's try: Floor to integer. Add cents. If result < rawPrice, add 1.
    
    let candidate = integerPart + cents / 100;
    if (candidate < rawPrice) {
      candidate += 1;
    }
    finalPrice = candidate;
  } else if (rounding.type === "MULTIPLE_OF") {
    const step = rounding.step ?? 5;
    finalPrice = Math.ceil(rawPrice / step) * step;
  }

  // 4. Calculate resulting margin
  // Margin = (Price - Cost) / Price
  let marginResultPct = 0;
  if (finalPrice > 0) {
    marginResultPct = ((finalPrice - costTotal) / finalPrice) * 100;
  }

  // 5. Generate warnings
  if (marginResultPct < rule.marginMinPct) {
    warnings.push(`Margem (${marginResultPct.toFixed(1)}%) abaixo do mínimo (${rule.marginMinPct}%).`);
  }
  if (finalPrice < costTotal) {
    warnings.push("Preço final é menor que o custo total.");
  }

  return {
    suggestedPrice: Number(finalPrice.toFixed(2)),
    marginResultPct: Number(marginResultPct.toFixed(2)),
    warnings,
  };
}
