/**
 * Live Visual Annotations — Audit Data Source
 * ─────────────────────────────────────────────
 * Captures brand pages, detects visible elements, generates annotation specs,
 * renders overlay screenshots, and uploads all assets to Vercel Blob.
 *
 * Internal module — vendor names permitted in code; forbidden in user-facing output.
 */

import { captureUrl } from "../../visual-annotation/screenshot-capture";
import { detectVisibleElements } from "../../visual-annotation/element-detector";
import { generateAnnotations, type BrandContext } from "../../visual-annotation/annotation-generator";
import { renderAnnotatedScreenshot } from "../../visual-annotation/overlay-renderer";
import { uploadScreenshot } from "../../visual-annotation/storage";
import type { LiveVisualAnnotations, PerPageAnnotation } from "../types";

// ─── Page type classification ─────────────────────────────────────────────────

function classifyPageType(url: string): PerPageAnnotation["pageType"] {
  const path = url.toLowerCase().replace(/^https?:\/\/[^/]+/, "");
  if (path === "/" || path === "" || /^\/(index\.html?)?$/.test(path)) return "homepage";
  if (/\/contact(?:-us)?/i.test(path)) return "contact";
  if (/\/(services?|treatments?|procedures?|solutions?)/i.test(path)) return "service";
  if (/\/(products?|shop|store)/i.test(path)) return "product";
  if (/\/(about|team|story)/i.test(path)) return "about";
  if (/\/(blog|news|articles?)/i.test(path)) return "blog";
  return "other";
}

function pageLabel(url: string, type: PerPageAnnotation["pageType"]): string {
  const map: Record<PerPageAnnotation["pageType"], string> = {
    homepage: "Homepage",
    service: "Services Page",
    product: "Product Page",
    category: "Category Page",
    about: "About Page",
    contact: "Contact Page",
    blog: "Blog Page",
    other: "Page",
  };
  try {
    const path = new URL(url).pathname.replace(/\/$/, "");
    const last = path.split("/").pop();
    if (last && last.length > 2 && type !== "homepage") {
      return last.charAt(0).toUpperCase() + last.slice(1).replace(/-/g, " ");
    }
  } catch {
    // ignore
  }
  return map[type];
}

// ─── Main aggregator ──────────────────────────────────────────────────────────

export async function aggregateLiveVisualAnnotations(
  brandUrl: string,
  brandContext: BrandContext,
  industryVertical: string,
  additionalPageUrls: string[] = [],
): Promise<LiveVisualAnnotations | null> {
  if (!process.env.BLOB_READ_WRITE_TOKEN) return null;

  const start = Date.now();

  // Determine pages: homepage + up to 2 additional
  const urlsToCapture = [
    brandUrl,
    ...additionalPageUrls.slice(0, 2),
  ].filter((u, i, arr) => arr.indexOf(u) === i); // deduplicate

  const perPageAnnotations: PerPageAnnotation[] = [];
  let totalScreenshots = 0;
  let totalAnnotations = 0;

  for (const url of urlsToCapture) {
    try {
      const [desktopCapture, mobileCapture] = await Promise.all([
        captureUrl(url, { viewport: "desktop", fullPage: false }),
        captureUrl(url, { viewport: "mobile", fullPage: false }),
      ]);

      if (!desktopCapture) continue;

      totalScreenshots += mobileCapture ? 2 : 1;

      const detected = detectVisibleElements(desktopCapture.dom);
      const annotations = generateAnnotations(detected, brandContext, industryVertical);
      const annotatedBuffer = await renderAnnotatedScreenshot(desktopCapture.buffer, annotations);

      const pageType = classifyPageType(url);
      const label = pageLabel(url, pageType);
      const slug = label.toLowerCase().replace(/\s+/g, "-");

      const [desktopUrl, annotatedUrl, mobileUrl] = await Promise.all([
        uploadScreenshot(desktopCapture.buffer, slug, "desktop"),
        uploadScreenshot(annotatedBuffer, slug, "desktop-annotated"),
        mobileCapture ? uploadScreenshot(mobileCapture.buffer, slug, "mobile") : Promise.resolve(null),
      ]);

      if (!desktopUrl || !annotatedUrl) continue;

      const severityBreakdown = {
        critical: annotations.filter((a) => a.severity === "critical").length,
        high: annotations.filter((a) => a.severity === "high").length,
        moderate: annotations.filter((a) => a.severity === "moderate").length,
        low: annotations.filter((a) => a.severity === "low").length,
        positive: annotations.filter((a) => a.severity === "positive").length,
      };

      totalAnnotations += annotations.length;

      perPageAnnotations.push({
        pageUrl: url,
        pageLabel: label,
        pageType,
        desktopScreenshotUrl: desktopUrl,
        desktopAnnotatedScreenshotUrl: annotatedUrl,
        mobileScreenshotUrl: mobileUrl ?? desktopUrl,
        annotations,
        annotationCount: annotations.length,
        severityBreakdown,
      });
    } catch (err) {
      console.warn(`[live-visual-annotations] page capture failed for ${url}:`, err instanceof Error ? err.message : err);
    }
  }

  if (perPageAnnotations.length === 0) return null;

  // ── Aggregate insights ────────────────────────────────────────────────────

  const allAnnotations = perPageAnnotations.flatMap((p) =>
    p.annotations.map((a) => ({ ...a, pageUrl: p.pageUrl })),
  );

  const severityOrder: Record<string, number> = { critical: 0, high: 1, moderate: 2, low: 3, positive: 4 };
  const topPriorityAnnotations = allAnnotations
    .filter((a) => a.severity !== "positive")
    .sort((a, b) => (severityOrder[a.severity] ?? 5) - (severityOrder[b.severity] ?? 5))
    .slice(0, 5)
    .map((a) => ({
      annotationId: a.id,
      pageUrl: a.pageUrl,
      severity: a.severity,
      shortLabel: a.shortLabel,
      description: a.description,
    }));

  const pagesWithCriticalIssues = perPageAnnotations.filter(
    (p) => p.severityBreakdown.critical > 0,
  ).length;

  const strongestPage = perPageAnnotations
    .sort((a, b) => b.severityBreakdown.positive - a.severityBreakdown.positive)
    .find((p) => p.severityBreakdown.positive > 0);

  const weakestPage = perPageAnnotations
    .sort(
      (a, b) =>
        b.severityBreakdown.critical * 10 +
        b.severityBreakdown.high -
        (a.severityBreakdown.critical * 10 + a.severityBreakdown.high),
    )
    .find((p) => p.severityBreakdown.critical + p.severityBreakdown.high > 0);

  const runtimeSeconds = (Date.now() - start) / 1000;

  return {
    hasAnnotations: true,
    windowDate: new Date().toISOString(),
    perPageAnnotations,
    aggregateInsights: {
      totalAnnotations,
      pagesWithCriticalIssues,
      topPriorityAnnotations,
      strongestPage: strongestPage
        ? {
            url: strongestPage.pageUrl,
            label: strongestPage.pageLabel,
            annotationCount: strongestPage.annotationCount,
            positiveAnnotationCount: strongestPage.severityBreakdown.positive,
          }
        : null,
      weakestPage: weakestPage
        ? {
            url: weakestPage.pageUrl,
            label: weakestPage.pageLabel,
            criticalCount: weakestPage.severityBreakdown.critical,
            highCount: weakestPage.severityBreakdown.high,
          }
        : null,
    },
    patentRelevance:
      "Visual analysis combined with structural audit produces multi-layer evidence of conversion gaps; visible-element detection bridges what users see and what search engines parse.",
    costMetrics: {
      totalScreenshotsCaptured: totalScreenshots,
      totalAnnotationsGenerated: totalAnnotations,
      estimatedCostUsd: totalScreenshots * 0.008,
      runtimeSeconds,
    },
  };
}
