/**
 * Fundamental dimension readouts for the Fundamentals tab.
 *
 * Scoring mirrors app/services/scoring_service.py _compute_fundamental_score:
 * equal-weighted average of available P/E, revenue growth, and earnings
 * surprise (need ≥2 metrics). Market cap is display-only, not scored.
 */

export interface FundamentalMetrics {
  pe_ratio: number | null;
  revenue_growth: number | null;
  earnings_surprise: number | null;
  market_cap?: number | null;
}

export interface StatusRead {
  text: string;
  tone: string;
}

const clamp = (v: number, lo = 0, hi = 100) => Math.max(lo, Math.min(hi, v));

/** P/E sub-score: lower is better. PE 15 → 100, 30 → 50, 45 → 0. */
export function peSubScore(pe: number): number {
  return clamp(100 - (pe - 15) * (100 / 30));
}

/** Revenue growth sub-score: 0% → 50, +20% → 100, −20% → 0. */
export function revenueGrowthSubScore(growthPct: number): number {
  return clamp(50 + growthPct * 2.5);
}

/** Earnings surprise sub-score: 0% → 50, +10% → 100, −10% → 0. */
export function earningsSurpriseSubScore(surprisePct: number): number {
  return clamp(50 + surprisePct * 5);
}

/**
 * Overall fundamental score, or null when fewer than 2 scored metrics.
 * Matches backend MIN_METRICS = 2.
 */
export function fundamentalScore(m: FundamentalMetrics): number | null {
  const parts: number[] = [];
  if (m.pe_ratio != null && m.pe_ratio > 0) parts.push(peSubScore(m.pe_ratio));
  if (m.revenue_growth != null) parts.push(revenueGrowthSubScore(m.revenue_growth));
  if (m.earnings_surprise != null) parts.push(earningsSurpriseSubScore(m.earnings_surprise));
  if (parts.length < 2) return null;
  return parts.reduce((a, b) => a + b, 0) / parts.length;
}

export function overallFundamentalStatus(score: number | null): StatusRead {
  if (score == null) {
    return { text: 'incomplete data', tone: 'text-amber-300' };
  }
  if (score >= 70) return { text: 'strong fundamentals', tone: 'text-emerald-300' };
  if (score >= 55) return { text: 'healthy', tone: 'text-emerald-300' };
  if (score >= 45) return { text: 'mixed / average', tone: 'text-gray-400' };
  if (score >= 30) return { text: 'soft', tone: 'text-amber-300' };
  return { text: 'weak fundamentals', tone: 'text-red-300' };
}

export function peStatus(pe: number | null): StatusRead | null {
  if (pe == null || !(pe > 0)) return null;
  if (pe <= 15) return { text: 'cheap / attractive', tone: 'text-emerald-300' };
  if (pe <= 25) return { text: 'fair', tone: 'text-gray-400' };
  if (pe <= 35) return { text: 'expensive', tone: 'text-amber-300' };
  return { text: 'rich', tone: 'text-red-300' };
}

export function revenueGrowthStatus(growthPct: number | null): StatusRead | null {
  if (growthPct == null) return null;
  if (growthPct >= 20) return { text: 'strong growth', tone: 'text-emerald-300' };
  if (growthPct >= 5) return { text: 'solid growth', tone: 'text-emerald-300' };
  if (growthPct >= -5) return { text: 'flat', tone: 'text-gray-400' };
  if (growthPct >= -20) return { text: 'contracting', tone: 'text-amber-300' };
  return { text: 'deep contraction', tone: 'text-red-300' };
}

export function earningsSurpriseStatus(surprisePct: number | null): StatusRead | null {
  if (surprisePct == null) return null;
  if (surprisePct >= 10) return { text: 'beat (large)', tone: 'text-emerald-300' };
  if (surprisePct >= 2) return { text: 'beat', tone: 'text-emerald-300' };
  if (surprisePct >= -2) return { text: 'in line', tone: 'text-gray-400' };
  if (surprisePct >= -10) return { text: 'miss', tone: 'text-amber-300' };
  return { text: 'miss (large)', tone: 'text-red-300' };
}

/** Size band only — not good/bad, not part of the score. */
export function marketCapStatus(marketCap: number | null): StatusRead | null {
  if (marketCap == null || !(marketCap > 0)) return null;
  if (marketCap >= 200e9) return { text: 'mega cap', tone: 'text-gray-400' };
  if (marketCap >= 10e9) return { text: 'large cap', tone: 'text-gray-400' };
  if (marketCap >= 2e9) return { text: 'mid cap', tone: 'text-gray-400' };
  if (marketCap >= 300e6) return { text: 'small cap', tone: 'text-gray-400' };
  return { text: 'micro cap', tone: 'text-gray-400' };
}

export function metricStatus(
  key: 'pe_ratio' | 'revenue_growth' | 'earnings_surprise' | 'market_cap',
  value: number | null,
): StatusRead | null {
  switch (key) {
    case 'pe_ratio':
      return peStatus(value);
    case 'revenue_growth':
      return revenueGrowthStatus(value);
    case 'earnings_surprise':
      return earningsSurpriseStatus(value);
    case 'market_cap':
      return marketCapStatus(value);
  }
}
