import type { PerPageMobileEvaluation, MobileFinding, MobileDimension } from "./types";

// Dimension weights by vertical (sum to 100)
const VERTICAL_DIMENSION_WEIGHTS: Record<
  string,
  Record<MobileDimension, number>
> = {
  "healthcare-medical": { viewport: 25, touch_targets: 25, mobile_schema: 20, amp: 5, above_fold_composition: 25 },
  "dental": { viewport: 25, touch_targets: 25, mobile_schema: 20, amp: 5, above_fold_composition: 25 },
  "legal": { viewport: 25, touch_targets: 20, mobile_schema: 15, amp: 5, above_fold_composition: 35 },
  "home-services": { viewport: 25, touch_targets: 20, mobile_schema: 15, amp: 5, above_fold_composition: 35 },
  "restaurant": { viewport: 20, touch_targets: 20, mobile_schema: 20, amp: 5, above_fold_composition: 35 },
  "saas": { viewport: 30, touch_targets: 25, mobile_schema: 15, amp: 5, above_fold_composition: 25 },
  "ecommerce": { viewport: 25, touch_targets: 30, mobile_schema: 15, amp: 5, above_fold_composition: 25 },
  "default": { viewport: 25, touch_targets: 25, mobile_schema: 20, amp: 5, above_fold_composition: 25 },
};

function getDimensionWeights(vertical: string): Record<MobileDimension, number> {
  return VERTICAL_DIMENSION_WEIGHTS[vertical] ?? VERTICAL_DIMENSION_WEIGHTS["default"];
}

function viewportScore(eval_: PerPageMobileEvaluation): number {
  if (!eval_.viewport.hasViewportMeta) return 0;
  if (eval_.viewport.isOptimal) return 100;
  const penaltyPerIssue = 20;
  return Math.max(0, 100 - eval_.viewport.issues.length * penaltyPerIssue);
}

function touchScore(eval_: PerPageMobileEvaluation): number {
  const base = eval_.touchTargets.passRate;
  const closePenalty = Math.min(eval_.touchTargets.tooCloseCount * 3, 20);
  return Math.max(0, base - closePenalty);
}

function schemaScore(eval_: PerPageMobileEvaluation): number {
  if (eval_.mobileSchema.hasMobileSpecificSchema) return 90;
  if (eval_.mobileSchema.detectedTypes.length > 0) return 60;
  return 20;
}

function ampScore(eval_: PerPageMobileEvaluation): number {
  if (!eval_.ampStatus.hasAmpVersion) return 50; // not expected everywhere
  if (eval_.ampStatus.ampValid) return 100;
  return 30;
}

function compositionScore(eval_: PerPageMobileEvaluation): number {
  return eval_.aboveFoldComposition.score;
}

export function scorePerPageMobile(
  evaluation: PerPageMobileEvaluation,
  vertical: string,
): number {
  const weights = getDimensionWeights(vertical);
  const total = Object.values(weights).reduce((s, w) => s + w, 0);

  const dimensionScores: Record<MobileDimension, number> = {
    viewport: viewportScore(evaluation),
    touch_targets: touchScore(evaluation),
    mobile_schema: schemaScore(evaluation),
    amp: ampScore(evaluation),
    above_fold_composition: compositionScore(evaluation),
  };

  const weighted = (Object.keys(weights) as MobileDimension[]).reduce(
    (sum, dim) => sum + (dimensionScores[dim] * weights[dim]) / total,
    0,
  );

  return Math.round(weighted);
}

export function buildTopPriorityFindings(
  evaluations: PerPageMobileEvaluation[],
): MobileFinding[] {
  const allFindings: MobileFinding[] = evaluations.flatMap((e) => e.findings);
  const severityOrder = { critical: 0, high: 1, moderate: 2, low: 3 };
  return allFindings
    .sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity])
    .slice(0, 5);
}
