import {
  areaCopy,
  diagnosticQuestions,
  pairNames,
  type DiagnosticQuestion,
  type OpportunityArea,
} from "@/content/diagnostic";
import type { BusinessModel } from "@/content/types";

export type DiagnosticAnswers = Partial<Record<DiagnosticQuestion["id"], string>>;

export interface DiagnosticResult {
  model: BusinessModel;
  primary: OpportunityArea;
  secondary: OpportunityArea;
  title: string;
  summary: string;
  checks: string[];
  scores: Record<OpportunityArea, number>;
}

type Weights = Partial<Record<OpportunityArea, number>>;

const AREAS: OpportunityArea[] = ["measurement", "conversion", "demand", "creative", "retention"];

const constraintArea: Record<string, OpportunityArea> = {
  traffic: "demand",
  conversion: "conversion",
  tracking: "measurement",
  creative: "creative",
  retention: "retention",
};

const objectiveWeights: Record<string, Weights> = {
  scale: { demand: 2, measurement: 1 },
  efficiency: { measurement: 2, conversion: 1 },
  conversion: { conversion: 2, creative: 1 },
  measurement: { measurement: 2, conversion: 1 },
};

const spendWeights: Record<string, Weights> = {
  none: { demand: 1, measurement: 1 },
  "under-10k": { conversion: 1 },
  "10k-50k": { measurement: 1 },
  "50k-150k": { measurement: 1, creative: 1 },
  "150k-plus": { measurement: 2, creative: 1 },
};

const platformWeights: Record<string, Weights> = {
  google: { demand: 1 },
  meta: { creative: 2 },
  linkedin: { measurement: 1, conversion: 1 },
  microsoft: { demand: 1 },
  organic: { conversion: 1 },
  none: { measurement: 1 },
};

const modelWeights: Record<BusinessModel, Weights> = {
  saas: { measurement: 1 },
  ecommerce: { retention: 1 },
};

export function isDiagnosticComplete(answers: DiagnosticAnswers): answers is Required<DiagnosticAnswers> {
  return diagnosticQuestions.every((question) =>
    question.options.some((option) => option.value === answers[question.id]),
  );
}

function addWeights(scores: Record<OpportunityArea, number>, weights: Weights | undefined) {
  if (!weights) return;
  for (const area of AREAS) scores[area] += weights[area] ?? 0;
}

/**
 * Directional scoring only: it ranks likely opportunity areas from self-reported answers.
 * It deliberately produces no forecasts, percentages, or revenue figures.
 */
export function scoreDiagnostic(answers: DiagnosticAnswers): DiagnosticResult {
  if (!isDiagnosticComplete(answers)) {
    throw new Error("Diagnostic answers are incomplete.");
  }

  const model = answers.model as BusinessModel;
  const scores = Object.fromEntries(AREAS.map((area) => [area, 0])) as Record<OpportunityArea, number>;
  const statedConstraint = constraintArea[answers.constraint];

  scores[statedConstraint] += 3;
  addWeights(scores, objectiveWeights[answers.objective]);
  addWeights(scores, spendWeights[answers.spend]);
  addWeights(scores, platformWeights[answers.platform]);
  addWeights(scores, modelWeights[model]);

  // Tie-break: the stated constraint, then the objective's main area, then a fixed order.
  const objectiveLead = Object.entries(objectiveWeights[answers.objective]).sort((a, b) => b[1] - a[1])[0][0] as OpportunityArea;
  const priority = [...new Set<OpportunityArea>([statedConstraint, objectiveLead, ...AREAS])];

  const ranked = [...AREAS].sort((a, b) => scores[b] - scores[a] || priority.indexOf(a) - priority.indexOf(b));
  const [primary, secondary] = ranked;
  const pairKey = [primary, secondary].sort().join("+");

  return {
    model,
    primary,
    secondary,
    title: pairNames[pairKey],
    summary: areaCopy[primary].summary,
    checks: [...areaCopy[primary].checks[model].slice(0, 2), areaCopy[secondary].checks[model][0]],
    scores,
  };
}

export function auditHrefForResult(result: Pick<DiagnosticResult, "model" | "primary" | "secondary">): string {
  const params = new URLSearchParams({ model: result.model, focus: `${result.primary},${result.secondary}` });
  return `/growth-audit?${params.toString()}`;
}
