/**
 * Report Studio export bridge
 * ─────────────────────────────
 * Converts a BrandReport (the structured output of report-generator.ts)
 * into the existing ReportDocument shape that DOCX/PDF/Markdown
 * exporters already know how to render. Keeping the existing exporters
 * untouched means DOCX/PDF output quality stays identical to the
 * AI Strategist's analysis exports.
 */

import type { BrandReport, ReportPage, ReportKeyword, ReportKpi } from "./report-generator";
import type { ReportDocument, ReportBlock, ReportMeta } from "./report-export";

export function brandReportToReportDocument(report: BrandReport): ReportDocument {
  const meta: ReportMeta = {
    appBrand: "meSEO",
    clientName: report.brand.name,
    clientDomain: report.brand.domain,
    clientLogoUrl: null,
    reportTitle: `${report.brand.name} — Performance Report`,
    reportSubtitle: `${report.dateRange.days}-day performance overview`,
    reportDate: report.generatedAt.split("T")[0],
    generatedBy: "meSEO Report Studio",
    analysisId: `report-${Date.now()}`,
    periodLabel: `${report.dateRange.start} → ${report.dateRange.end}`,
  };

  const blocks: ReportBlock[] = [];

  // ── Executive summary ──────────────────────────────────────────────
  blocks.push({ type: "heading", level: 1, text: "Executive Summary" });
  if (report.executiveSummary.narrative) {
    blocks.push({ type: "paragraph", text: report.executiveSummary.narrative });
  }
  if (report.executiveSummary.healthScore !== null) {
    blocks.push({
      type: "metric_row",
      label: "Site Health Score",
      value: `${report.executiveSummary.healthScore}/100`,
      source: "Technical Audit",
    });
  }
  for (const kpi of report.executiveSummary.kpis) {
    blocks.push({
      type: "metric_row",
      label: kpi.label,
      value: kpi.value.toLocaleString(),
      change: kpi.changePct !== null && kpi.changePct !== undefined
        ? `${kpi.changePct >= 0 ? "+" : ""}${kpi.changePct.toFixed(1)}%`
        : undefined,
      changeDirection: kpi.direction,
      source: kpi.label.includes("Click") || kpi.label.includes("Impression") ? "GSC" : "GA4",
    });
  }
  if (report.executiveSummary.topWin) {
    blocks.push({ type: "callout", severity: "info", title: "Top Win", body: report.executiveSummary.topWin });
  }
  if (report.executiveSummary.topConcern) {
    blocks.push({ type: "callout", severity: "warning", title: "Top Concern", body: report.executiveSummary.topConcern });
  }
  if (report.executiveSummary.topOpportunity) {
    blocks.push({ type: "callout", severity: "info", title: "Top Opportunity", body: report.executiveSummary.topOpportunity });
  }
  blocks.push({ type: "divider" });

  // ── Wins ────────────────────────────────────────────────────────────
  blocks.push({ type: "heading", level: 1, text: "What's Working" });

  if (report.wins.topPages.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Top Performing Pages" });
    blocks.push({ type: "paragraph", text: pagesToText(report.wins.topPages) });
  }
  if (report.wins.topKeywords.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Top Performing Keywords" });
    blocks.push({ type: "paragraph", text: keywordsToText(report.wins.topKeywords) });
  }
  if (report.wins.growingPages.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Growth Areas" });
    for (const p of report.wins.growingPages) {
      blocks.push({
        type: "callout",
        severity: "info",
        title: p.url,
        body: `Clicks grew ${p.clicksChangePct?.toFixed(1)}% (from ${p.previousClicks?.toLocaleString() ?? 0} to ${p.clicks.toLocaleString()}).`,
      });
    }
  }
  if (report.wins.newPages.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "New Pages Generating Traffic" });
    for (const p of report.wins.newPages) {
      blocks.push({
        type: "callout",
        severity: "info",
        title: p.url,
        body: `Detected ${new Date(p.firstSeenAt).toLocaleDateString()} · ${p.clicks.toLocaleString()} clicks since first seen.`,
      });
    }
  }
  if (report.wins.conversionWin && report.wins.conversionWin.changePct !== null) {
    blocks.push({
      type: "metric_row",
      label: "Conversion Growth",
      value: `${report.wins.conversionWin.current.toLocaleString()} conversions`,
      change: `${report.wins.conversionWin.changePct >= 0 ? "+" : ""}${report.wins.conversionWin.changePct.toFixed(1)}%`,
      changeDirection: report.wins.conversionWin.changePct >= 0 ? "up" : "down",
      source: "GA4",
    });
  }
  blocks.push({ type: "divider" });

  // ── Declines ────────────────────────────────────────────────────────
  blocks.push({ type: "heading", level: 1, text: "What's Not Working" });

  if (report.declines.decliningPages.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Declining Pages" });
    for (const p of report.declines.decliningPages) {
      blocks.push({
        type: "callout",
        severity: "warning",
        title: p.url,
        body: `Clicks dropped ${Math.abs(p.clicksChangePct ?? 0).toFixed(1)}% (from ${p.previousClicks?.toLocaleString() ?? 0} to ${p.clicks.toLocaleString()}). Current position: ${p.position.toFixed(1)}.`,
      });
    }
  }
  if (report.declines.decliningKeywords.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Declining Keywords" });
    for (const k of report.declines.decliningKeywords) {
      blocks.push({
        type: "callout",
        severity: "warning",
        title: k.query,
        body: `Position slipped ${Math.abs(k.positionChange ?? 0).toFixed(0)} spots (from ${k.previousPosition?.toFixed(1)} to ${k.position.toFixed(1)}). Impressions: ${k.impressions.toLocaleString()}.`,
      });
    }
  }
  if (report.declines.technicalIssues) {
    blocks.push({ type: "heading", level: 2, text: "Technical Health" });
    blocks.push({
      type: "metric_row",
      label: "Crawl Health",
      value: `${report.declines.technicalIssues.crawlHealth}/100`,
      source: "Technical Audit",
    });
    blocks.push({
      type: "metric_row",
      label: "Errors / Warnings",
      value: `${report.declines.technicalIssues.errorCount} errors · ${report.declines.technicalIssues.warningCount} warnings`,
      source: "Technical Audit",
    });
    for (const issue of report.declines.technicalIssues.criticalIssues) {
      blocks.push({
        type: "callout",
        severity: "critical",
        title: issue.title,
        body: `${issue.category} · ${issue.affected} page${issue.affected !== 1 ? "s" : ""} affected${issue.pageUrl ? ` · ${issue.pageUrl}` : ""}`,
      });
    }
  }
  if (report.declines.pageHealthIssues.pagesWent404.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Pages That Went 404" });
    for (const p of report.declines.pageHealthIssues.pagesWent404) {
      blocks.push({
        type: "callout",
        severity: "critical",
        title: p.url,
        body: `Detected ${new Date(p.detectedAt).toLocaleDateString()}`,
      });
    }
  }
  if (report.declines.pageHealthIssues.lowCtrHighImpression.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "High Impressions, Low CTR" });
    for (const p of report.declines.pageHealthIssues.lowCtrHighImpression) {
      blocks.push({
        type: "callout",
        severity: "warning",
        title: p.url,
        body: `${p.impressions.toLocaleString()} impressions but only ${p.ctr.toFixed(2)}% CTR at position ${p.position.toFixed(1)}.`,
      });
    }
  }
  blocks.push({ type: "divider" });

  // ── Opportunities ───────────────────────────────────────────────────
  blocks.push({ type: "heading", level: 1, text: "Optimization Opportunities" });

  if (report.opportunities.ctrOptimization.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "CTR Optimization — Quick Wins" });
    blocks.push({
      type: "paragraph",
      text: "Pages ranking well but under-performing on click-through rate. Metadata tuning (title tags, meta descriptions) could recover significant traffic.",
    });
    for (const o of report.opportunities.ctrOptimization) {
      blocks.push({
        type: "callout",
        severity: "info",
        title: o.url,
        body: `Position ${o.position.toFixed(1)} · ${o.currentCtr.toFixed(2)}% CTR vs ${o.expectedCtr.toFixed(1)}% expected. Optimising metadata could add ~${o.estimatedClickGain.toLocaleString()} clicks.`,
      });
    }
  }
  if (report.opportunities.strikingDistance.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Striking Distance — Position Improvement" });
    blocks.push({
      type: "paragraph",
      text: "Pages and keywords in positions 4-10 with high impressions. A small ranking boost translates into disproportionate click gains.",
    });
    for (const s of report.opportunities.strikingDistance) {
      blocks.push({
        type: "callout",
        severity: "info",
        title: s.type === "keyword" ? `"${s.target}"` : s.target,
        body: `Position ${s.position.toFixed(1)} · ${s.impressions.toLocaleString()} impressions. Reaching top 3 could add ~${(s.estimatedClicksAtTop3 - s.currentClicks).toLocaleString()} clicks.`,
      });
    }
  }
  if (report.opportunities.contentRefresh.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Content Refresh Candidates" });
    for (const c of report.opportunities.contentRefresh) {
      blocks.push({
        type: "callout",
        severity: "warning",
        title: c.url,
        body: `Clicks dropped ${Math.abs(c.changePct).toFixed(1)}% but still has ${c.impressions.toLocaleString()} impressions. Content refresh recommended.`,
      });
    }
  }
  if (report.opportunities.technicalFixes.length > 0) {
    blocks.push({ type: "heading", level: 2, text: "Technical Fixes" });
    for (const f of report.opportunities.technicalFixes) {
      blocks.push({
        type: "callout",
        severity: f.priority === "critical" ? "critical" : "warning",
        title: f.title,
        body: `${f.category} · ${f.priority} priority · ${f.affected} page${f.affected !== 1 ? "s" : ""} affected`,
      });
    }
  }
  blocks.push({ type: "divider" });

  // ── AI Insights ─────────────────────────────────────────────────────
  if (report.aiInsights.available) {
    blocks.push({ type: "heading", level: 1, text: "AI Strategist Insights" });

    if (report.aiInsights.findings.length > 0) {
      blocks.push({ type: "heading", level: 2, text: "Findings" });
      report.aiInsights.findings.slice(0, 10).forEach((f, i) => {
        blocks.push({
          type: "finding",
          index: i + 1,
          severity: f.severity,
          title: f.title,
          description: f.description,
          evidence: f.evidence,
          impact: f.impact,
        });
      });
    }
    if (report.aiInsights.predictions.length > 0) {
      blocks.push({ type: "heading", level: 2, text: "Predictions" });
      for (const p of report.aiInsights.predictions) {
        blocks.push({
          type: "prediction",
          metric: p.metric,
          current: p.current,
          predicted: p.predicted,
          confidence: p.confidence,
          timeframe: p.timeframe,
          basis: p.basis,
        });
      }
    }
    if (report.aiInsights.recommendations.length > 0) {
      blocks.push({ type: "heading", level: 2, text: "Recommendations" });
      report.aiInsights.recommendations.slice(0, 10).forEach((r, i) => {
        blocks.push({
          type: "recommendation",
          index: i + 1,
          priority: r.priority,
          title: r.title,
          description: r.description,
          expectedImpact: r.expectedImpact,
        });
      });
    }
    blocks.push({ type: "divider" });
  }

  // ── Footer ──────────────────────────────────────────────────────────
  blocks.push({
    type: "footer",
    text: `Generated by meSEO Report Studio · ${new Date(report.generatedAt).toLocaleString()}`,
  });

  return { meta, blocks };
}

// ─── Helpers ─────────────────────────────────────────────────────────────

function pagesToText(pages: ReportPage[]): string {
  return pages
    .map((p, i) =>
      `${i + 1}. ${p.url} — ${p.clicks.toLocaleString()} clicks · ${p.impressions.toLocaleString()} impressions · ${p.ctr.toFixed(2)}% CTR · pos ${p.position.toFixed(1)}${
        p.clicksChangePct !== undefined ? ` (${p.clicksChangePct >= 0 ? "+" : ""}${p.clicksChangePct.toFixed(1)}%)` : ""
      }`,
    )
    .join("\n");
}

function keywordsToText(keywords: ReportKeyword[]): string {
  return keywords
    .map((k, i) =>
      `${i + 1}. "${k.query}" — ${k.clicks.toLocaleString()} clicks · pos ${k.position.toFixed(1)}${
        k.positionChange !== undefined && k.positionChange !== 0
          ? ` (${k.positionChange > 0 ? "+" : ""}${k.positionChange.toFixed(0)} spots)`
          : ""
      }`,
    )
    .join("\n");
}

// Re-export so the API export route can find it in one import
export type { BrandReport, ReportPage, ReportKeyword, ReportKpi };
