/**
 * Brand Authority Composite Scorer
 * -----------------------------------
 * Aggregates six authority signals with vertical-aware weights into a
 * single 0-100 composite score and tier classification.
 *
 * Internal module -- vendor names permitted in code; forbidden in user-facing output.
 */

import type { AuthoritySignal, AuthorityTier, BrandAuthorityScore } from "./types";

// Default equal-ish weights (sum to 1.0)
const DEFAULT_WEIGHTS: Record<AuthoritySignal["key"], number> = {
  encyclopedic_presence:  0.20,
  editorial_mentions:     0.20,
  industry_directories:   0.15,
  social_proof:           0.15,
  referring_domains:      0.15,
  branded_search_demand:  0.15,
};

const WEIGHT_OVERRIDES: Partial<Record<string, Partial<Record<AuthoritySignal["key"], number>>>> = {
  "local-services": {
    industry_directories:  0.25,
    social_proof:          0.20,
    encyclopedic_presence: 0.10,
    editorial_mentions:    0.15,
    referring_domains:     0.15,
    branded_search_demand: 0.15,
  },
  "healthcare-medical": {
    industry_directories:  0.25,
    social_proof:          0.20,
    editorial_mentions:    0.20,
    encyclopedic_presence: 0.10,
    referring_domains:     0.10,
    branded_search_demand: 0.15,
  },
  "healthcare": {
    industry_directories:  0.25,
    social_proof:          0.20,
    editorial_mentions:    0.20,
    encyclopedic_presence: 0.10,
    referring_domains:     0.10,
    branded_search_demand: 0.15,
  },
  "b2b-saas": {
    editorial_mentions:    0.25,
    industry_directories:  0.20,
    referring_domains:     0.20,
    branded_search_demand: 0.15,
    social_proof:          0.10,
    encyclopedic_presence: 0.10,
  },
  "ecommerce": {
    social_proof:          0.25,
    referring_domains:     0.20,
    branded_search_demand: 0.20,
    editorial_mentions:    0.15,
    industry_directories:  0.10,
    encyclopedic_presence: 0.10,
  },
};

function getWeights(vertical: string): Record<AuthoritySignal["key"], number> {
  const overrides = WEIGHT_OVERRIDES[vertical];
  if (!overrides) return { ...DEFAULT_WEIGHTS };
  return {
    ...DEFAULT_WEIGHTS,
    ...overrides,
  } as Record<AuthoritySignal["key"], number>;
}

function scoreTier(overall: number): AuthorityTier {
  if (overall >= 80) return "Authoritative";
  if (overall >= 60) return "Established";
  if (overall >= 40) return "Emerging";
  return "Limited";
}

function buildNarrative(
  brandName: string,
  tier: AuthorityTier,
  signals: AuthoritySignal[],
): string {
  const strongSignals = signals.filter((s) => s.status === "strong");
  const weakSignals = signals.filter((s) => s.status === "weak" || s.status === "absent");
  const top2 = strongSignals.slice(0, 2).map((s) => s.label).join(" and ");
  const weakest2 = weakSignals.slice(0, 2).map((s) => s.label).join(" and ");

  // Calculate percentage of composite score driven by weakest 2
  const weakContrib = weakSignals
    .slice(0, 2)
    .reduce((sum, s) => sum + s.weight * 100, 0);
  const weakPct = Math.round(weakContrib);

  if (tier === "Authoritative") {
    return `${brandName} demonstrates strong authority signals across ${strongSignals.length} of 6 dimensions. AI search engines are likely to surface this brand as a citation source for queries matching its expertise. The strongest signals are ${top2 || "multiple dimensions"}.`;
  }
  if (tier === "Established") {
    return `${brandName} shows established authority with strong performance on ${strongSignals.length} of 6 signals. AI engines will surface this brand selectively, particularly for queries aligned with its strongest dimensions: ${top2 || "core areas"}. Improvements in ${weakest2 || "weaker dimensions"} would meaningfully expand citation coverage.`;
  }
  if (tier === "Emerging") {
    return `${brandName} has emerging authority signals with moderate strength on ${strongSignals.length} of 6 dimensions. AI engines may surface this brand inconsistently. The largest opportunities are ${weakest2 || "multiple dimensions"}, which together drive ${weakPct}% of the composite score potential.`;
  }
  return `${brandName} currently shows limited authority signals across most measured dimensions. AI engines are unlikely to surface this brand as a citation source without targeted authority-building work. The highest-leverage starting points are ${weakest2 || "all six dimensions"}.`;
}

export function scoreBrandAuthority(
  signals: AuthoritySignal[],
  vertical: string,
  brandName: string,
  windowDate: Date,
  costMetrics: BrandAuthorityScore["costMetrics"],
): BrandAuthorityScore {
  const weights = getWeights(vertical);

  // Apply weights and compute weighted contributions
  const weightedSignals: AuthoritySignal[] = signals.map((s) => {
    const w = weights[s.key] ?? DEFAULT_WEIGHTS[s.key] ?? (1 / 6);
    return {
      ...s,
      weight: w,
      weightedContribution: Math.round(s.rawScore * w * 10) / 10,
    };
  });

  // Overall = sum of (rawScore * weight)
  const overall = Math.min(100, Math.round(
    weightedSignals.reduce((sum, s) => sum + s.rawScore * s.weight, 0),
  ));

  const tier = scoreTier(overall);

  // Top recommendations: sort by (1 - rawScore/100) * weight descending
  const topRecommendations = weightedSignals
    .filter((s) => s.recommendation !== null)
    .sort((a, b) => ((1 - b.rawScore / 100) * b.weight) - ((1 - a.rawScore / 100) * a.weight))
    .slice(0, 3)
    .map((s) => s.recommendation!);

  const narrativeSummary = buildNarrative(brandName, tier, weightedSignals);

  return {
    hasScore: true,
    overall,
    tier,
    signals: weightedSignals,
    topRecommendations,
    narrativeSummary,
    patentRelevance:
      "Brand authority composite combines public knowledge graph presence with editorial mentions, directory authority, and branded search demand to produce a defensible single-number signal of AI-engine citation-worthiness across the LLMO surface.",
    costMetrics,
    windowDate,
  };
}
