import type { TransferCategory, TransferCondition } from '@prisma/client';

/**
 * Depreciation curves by category (annual depreciation rate as fraction).
 * Based on Vietnamese secondhand market data:
 * - Furniture depreciates ~15-20% per year
 * - Appliances ~20-25% (technology obsolescence)
 * - Office equipment ~25-30%
 * - Kitchen equipment ~15-20%
 */
const DEPRECIATION_RATES: Record<string, number> = {
  FURNITURE: 0.18,
  APPLIANCE: 0.22,
  OFFICE_EQUIPMENT: 0.27,
  KITCHEN: 0.18,
  PREMISES: 0, // Premises don't depreciate the same way
  FULL_UNIT: 0.15,
};

/**
 * Condition multiplier — adjusts the depreciation-based estimate.
 * NEW and LIKE_NEW items retain more value; WORN items lose extra.
 */
const CONDITION_MULTIPLIERS: Record<string, number> = {
  NEW: 1.0,
  LIKE_NEW: 0.92,
  GOOD: 0.80,
  FAIR: 0.65,
  WORN: 0.45,
};

/**
 * Brand tier multipliers — premium brands retain value better.
 * Keys are lowercase brand names (partial match).
 */
const BRAND_TIERS: { keywords: string[]; multiplier: number }[] = [
  // Premium tier — 1.3x value retention
  {
    keywords: [
      'herman miller', 'steelcase', 'b&b italia', 'poliform', 'molteni',
      'boffi', 'sub-zero', 'wolf', 'miele', 'gaggenau', 'smeg',
      'dyson', 'bang & olufsen', 'lg signature',
    ],
    multiplier: 1.30,
  },
  // Mid-premium tier — 1.15x
  {
    keywords: [
      'ikea', 'muji', 'ashley', 'pottery barn', 'west elm',
      'samsung', 'lg', 'panasonic', 'bosch', 'electrolux',
      'daikin', 'mitsubishi', 'toshiba', 'hitachi',
      'hòa phát', 'xuân hòa',
    ],
    multiplier: 1.15,
  },
  // Standard tier — 1.0x (default, no adjustment)
];

/** Minimum floor price: 10% of original (items always have some scrap/resale value) */
const MIN_VALUE_RATIO = 0.10;

/** Maximum age for depreciation curve (beyond this, use floor price) */
const MAX_DEPRECIATION_YEARS = 10;

export interface FurniturePriceEstimate {
  estimatedPriceVND: bigint;
  confidence: number; // 0-1
  factors: {
    depreciationRate: number;
    ageYears: number;
    conditionMultiplier: number;
    brandMultiplier: number;
    depreciatedValue: number; // as fraction of original
  };
}

export interface FurniturePricingInput {
  category: TransferCategory;
  condition: TransferCondition;
  originalPriceVND: bigint;
  purchaseYear: number;
  brand?: string;
}

/**
 * Estimate the current market value of a used furniture/appliance item.
 *
 * Formula: estimatedPrice = originalPrice × depreciatedValue × conditionMultiplier × brandMultiplier
 * Where depreciatedValue = max(MIN_VALUE_RATIO, (1 - annualRate) ^ ageYears)
 */
export function estimateFurniturePrice(input: FurniturePricingInput): FurniturePriceEstimate {
  const currentYear = new Date().getFullYear();
  const ageYears = Math.max(0, currentYear - input.purchaseYear);

  const annualRate = DEPRECIATION_RATES[input.category] ?? 0.20;
  const conditionMult = CONDITION_MULTIPLIERS[input.condition] ?? 0.70;
  const brandMult = getBrandMultiplier(input.brand);

  // Exponential depreciation with floor
  const rawDepreciated = Math.pow(1 - annualRate, Math.min(ageYears, MAX_DEPRECIATION_YEARS));
  const depreciatedValue = Math.max(MIN_VALUE_RATIO, rawDepreciated);

  const finalRatio = depreciatedValue * conditionMult * brandMult;
  const originalNum = Number(input.originalPriceVND);
  const estimatedNum = Math.round(originalNum * finalRatio);

  // Confidence based on data quality
  let confidence = 0.70; // base confidence
  if (input.brand) confidence += 0.10; // known brand helps
  if (input.purchaseYear > 0) confidence += 0.10; // known age helps
  if (ageYears <= 5) confidence += 0.05; // recent items are more predictable
  if (ageYears > MAX_DEPRECIATION_YEARS) confidence -= 0.15; // very old = less predictable
  confidence = Math.max(0.30, Math.min(0.95, confidence));

  return {
    estimatedPriceVND: BigInt(estimatedNum),
    confidence,
    factors: {
      depreciationRate: annualRate,
      ageYears,
      conditionMultiplier: conditionMult,
      brandMultiplier: brandMult,
      depreciatedValue: finalRatio,
    },
  };
}

/**
 * Batch estimate prices for multiple items in a transfer listing.
 */
export function estimateTransferListingPrices(
  items: FurniturePricingInput[],
): { estimates: FurniturePriceEstimate[]; totalEstimateVND: bigint; avgConfidence: number } {
  const estimates = items.map((item) => estimateFurniturePrice(item));
  const totalEstimateVND = estimates.reduce(
    (sum, e) => sum + e.estimatedPriceVND,
    BigInt(0),
  );
  const avgConfidence = estimates.length > 0
    ? estimates.reduce((sum, e) => sum + e.confidence, 0) / estimates.length
    : 0;

  return { estimates, totalEstimateVND, avgConfidence };
}

function getBrandMultiplier(brand?: string): number {
  if (!brand) return 1.0;
  const lower = brand.toLowerCase();
  for (const tier of BRAND_TIERS) {
    if (tier.keywords.some((kw) => lower.includes(kw))) {
      return tier.multiplier;
    }
  }
  return 1.0;
}
