/**
 * AI Visibility ↔ Content Intel Bridge
 * ─────────────────────────────────────
 * Analyses what makes content AI-citable and identifies gaps
 * on pages that aren't yet cited.
 */

import { Prisma } from "@prisma/client";
import { prisma } from "@/lib/prisma";

export interface CitationAnalysis {
  pageUrl: string;
  citedForKeywords: string[];
  contentCharacteristics: {
    hasSchemaMarkup: boolean;
    schemaTypes: string[];
    hasFaqStructure: boolean;
    wordCount: number;
    hasStructuredData: boolean;
    internalLinkCount: number;
  };
}

export interface CitationGap {
  characteristic: string;
  yourPage: string;
  citedAverage: string;
  impact: "high" | "medium" | "low";
  recommendation: string;
}

export interface CitationGapAnalysis {
  pageUrl: string;
  targetKeyword: string;
  overallReadiness: number;
  gaps: CitationGap[];
}

export async function analyzeCitedPages(brandId: string): Promise<CitationAnalysis[]> {
  const d30 = new Date(Date.now() - 30 * 86_400_000);

  const citations = await prisma.aiCitation.findMany({
    where: { brandId, brandCited: true, checkedAt: { gte: d30 } },
    select: { citedUrl: true, keyword: true },
  });

  const byUrl = new Map<string, string[]>();
  for (const c of citations) {
    if (!c.citedUrl) continue;
    const list = byUrl.get(c.citedUrl) ?? [];
    list.push(c.keyword);
    byUrl.set(c.citedUrl, list);
  }

  const schemaMarkups = await prisma.schemaMarkup.findMany({
    where: { brandId },
    select: { pageUrl: true, schemaType: true },
  }).catch(() => []);

  const schemaByPage = new Map<string, string[]>();
  for (const s of schemaMarkups) {
    const list = schemaByPage.get(s.pageUrl) ?? [];
    list.push(s.schemaType);
    schemaByPage.set(s.pageUrl, list);
  }

  const results: CitationAnalysis[] = [];
  for (const [url, keywords] of byUrl) {
    const schemas = schemaByPage.get(url) ?? [];
    results.push({
      pageUrl: url,
      citedForKeywords: [...new Set(keywords)],
      contentCharacteristics: {
        hasSchemaMarkup: schemas.length > 0,
        schemaTypes: schemas,
        hasFaqStructure: schemas.some((s) => s.toLowerCase().includes("faq")),
        wordCount: 0,
        hasStructuredData: schemas.length > 0,
        internalLinkCount: 0,
      },
    });
  }

  return results;
}

export async function analyzePageCitationReadiness(
  brandId: string,
  pageUrl: string,
  targetKeyword: string,
): Promise<CitationGapAnalysis> {
  const gaps: CitationGap[] = [];
  let readiness = 50;

  const schema = await prisma.schemaMarkup.findFirst({
    where: { brandId, pageUrl },
  }).catch(() => null);

  if (!schema) {
    gaps.push({
      characteristic: "Schema Markup",
      yourPage: "Missing",
      citedAverage: "FAQPage + LocalBusiness schema",
      impact: "high",
      recommendation: `Add FAQPage schema with 5+ Q&As about "${targetKeyword}". Also add relevant business schema.`,
    });
    readiness -= 25;
  }

  const hasFaq = schema?.schemaType?.toLowerCase().includes("faq") ?? false;
  if (!hasFaq) {
    gaps.push({
      characteristic: "FAQ Structure",
      yourPage: "No FAQ section detected",
      citedAverage: "Structured FAQ with 5-10 questions",
      impact: "high",
      recommendation: "Add a FAQ section with common questions. AI models strongly prefer FAQ-structured content.",
    });
    readiness -= 15;
  }

  const citedCompetitors = await prisma.aiCitation.findMany({
    where: {
      brandId,
      keyword: targetKeyword,
      brandCited: false,
      competitorsCited: { not: Prisma.JsonNull },
    },
    select: { competitorsCited: true },
    take: 5,
  }).catch(() => []);

  if (citedCompetitors.length > 0) {
    gaps.push({
      characteristic: "Competitive Coverage",
      yourPage: "Not cited for this keyword",
      citedAverage: `${citedCompetitors.length} competitor(s) are cited`,
      impact: "high",
      recommendation: `Competitors are cited for "${targetKeyword}". Match or exceed their content depth, add unique differentiators and schema markup.`,
    });
    readiness -= 10;
  }

  return {
    pageUrl,
    targetKeyword,
    overallReadiness: Math.max(0, Math.min(100, readiness)),
    gaps,
  };
}

export async function getAiCoverageStats(brandId: string): Promise<{
  totalPages: number;
  pagesWithAiTraffic: number;
  avgResonanceScore: number;
  topAiPage: { url: string; visits: number; conversions: number } | null;
}> {
  const d30 = new Date(Date.now() - 30 * 86_400_000);

  const [pageGroups, convGroups, totalPages] = await Promise.all([
    prisma.aiAttribution.groupBy({
      by: ["landingPage"],
      where: { brandId, timestamp: { gte: d30 } },
      _count: true,
      orderBy: { _count: { landingPage: "desc" } },
      take: 50,
    }).catch(() => []),

    prisma.aiAttribution.groupBy({
      by: ["landingPage"],
      where: { brandId, timestamp: { gte: d30 }, converted: true },
      _count: true,
    }).catch(() => []),

    prisma.pageRecord.count({
      where: { brandId },
    }).catch(() => 0),
  ]);

  const convMap = new Map(convGroups.map((c) => [c.landingPage, typeof c._count === "number" ? c._count : 0]));
  const pagesWithAiTraffic = pageGroups.length;

  let topAiPage: { url: string; visits: number; conversions: number } | null = null;
  if (pageGroups.length > 0) {
    const top = pageGroups[0];
    topAiPage = {
      url: top.landingPage,
      visits: typeof top._count === "number" ? top._count : 0,
      conversions: convMap.get(top.landingPage) ?? 0,
    };
  }

  return {
    totalPages: totalPages || pageGroups.length,
    pagesWithAiTraffic,
    avgResonanceScore: 0,
    topAiPage,
  };
}
