/**
 * Retrieval Functions for the AI Avatar
 * ---------------------------------------
 * Each function fetches summary data from a specific module so the AI
 * can reference real numbers when answering questions.
 *
 * Phase 1: These return PLACEHOLDER data. In Phase 2, they'll query
 * Prisma for real data using the brandId.
 *
 * The AI Avatar calls the right retrieval function based on the
 * user's current page (or the topic of their question).
 */

import type { AvatarContext } from "./context-builder";
import { getTrafficSummary, getConversionSummary } from "@/lib/services/site-tag-analytics";
import { getGscSummary } from "@/lib/services/gsc-sync";
import { getGbpSummary, getGbpConversions } from "@/lib/services/gbp-sync";
import { getGa4Summary } from "@/lib/services/ga4-sync";

/** The shape every retrieval function returns */
export interface RetrievalResult {
  /** Module name */
  module: string;
  /** Plain-text summary the AI can read */
  summary: string;
  /** Key metrics as structured data */
  metrics: Record<string, string | number>;
}

// ─── Dashboard ───────────────────────────────────────────────────────────────

export async function retrieveDashboard(ctx: AvatarContext): Promise<RetrievalResult> {
  // Try real tracked data first (Site Tag + GSC)
  try {
    const traffic = await getTrafficSummary(ctx.brandId, "30d");
    const conversions = await getConversionSummary(ctx.brandId, "30d");
    const gsc = await getGscSummary(ctx.brandId, 28);
    const ga4 = await getGa4Summary(ctx.brandId, 28);

    if (traffic && traffic.pageViews > 0) {
      const topPagesStr = traffic.topPages.slice(0, 3).map(p => `${p.url} (${p.views} views)`).join(", ");
      const topRefStr = traffic.byReferrer.slice(0, 3).map(r => `${r.source} (${r.views})`).join(", ");

      return {
        module: "Dashboard",
        summary: [
          `${ctx.brandName} (${ctx.domain}) dashboard overview (last 30 days):`,
          `- Page views: ${traffic.pageViews.toLocaleString()} (from meSEO Site Tag)`,
          `- Sessions: ${traffic.sessions.toLocaleString()}`,
          `- Pages per session: ${traffic.pagesPerSession}`,
          `- Total conversions: ${conversions?.totalConversions ?? 0}`,
          `- Conversion rate: ${conversions?.conversionRate ?? 0}%`,
          `- Top pages: ${topPagesStr || "N/A"}`,
          `- Top referrers: ${topRefStr || "N/A"}`,
          conversions?.totalConversions
            ? `- Conversions by type: ${Object.entries(conversions.byType).map(([k, v]) => `${k}: ${v}`).join(", ")}`
            : "- No conversion events tracked yet",
          ...(gsc ? [
            `- GSC organic clicks: ${gsc.totalClicks.toLocaleString()} (from Google Search Console)`,
            `- GSC impressions: ${gsc.totalImpressions.toLocaleString()}`,
            `- GSC avg CTR: ${gsc.avgCtr}%`,
            `- GSC avg position: ${gsc.avgPosition}`,
            `- Top queries: ${gsc.topQueries.slice(0, 5).map(q => `"${q.query}" (${q.clicks} clicks, pos ${q.position})`).join(", ")}`,
          ] : ["- GSC data: not connected"]),
          ...(ga4 ? [
            `- GA4 sessions: ${ga4.sessions.toLocaleString()} (from Google Analytics 4)`,
            `- GA4 users: ${ga4.users.toLocaleString()}`,
            `- GA4 page views: ${ga4.pageViews.toLocaleString()}`,
            `- GA4 conversions: ${ga4.conversions}`,
          ] : ["- GA4 data: not connected"]),
        ].join("\n"),
        metrics: {
          pageViews: traffic.pageViews,
          sessions: traffic.sessions,
          pagesPerSession: traffic.pagesPerSession,
          gscClicks: gsc?.totalClicks ?? 0,
          gscImpressions: gsc?.totalImpressions ?? 0,
          conversions: conversions?.totalConversions ?? 0,
          conversionRate: `${conversions?.conversionRate ?? 0}%`,
          topPage: traffic.topPages[0]?.url ?? "N/A",
        },
      };
    }
  } catch { /* fall through to mock data */ }

  // Fallback: mock data (no tracked events yet)
  return {
    module: "Dashboard",
    summary: [
      `${ctx.brandName} (${ctx.domain}) dashboard overview:`,
      "- Organic traffic: 12,480 sessions this month (+8% MoM)",
      "- Total conversions: 487 (+18% MoM)",
      "- Revenue attributed: $243.5K (+22% MoM)",
      "- Top channel: Organic (38% of conversions)",
      "- AI search traffic: 1,100 sessions (+34% MoM)",
      "- Bounce rate: 42% (down from 48%)",
      "- Note: Install meSEO Site Tag to see real tracked data here",
    ].join("\n"),
    metrics: {
      sessions: 12480,
      conversions: 487,
      revenue: 243500,
      bounceRate: "42%",
      topChannel: "Organic",
      aiTraffic: 1100,
    },
  };
}

// ─── Conversion Intelligence ─────────────────────────────────────────────────

export async function retrieveConversions(ctx: AvatarContext): Promise<RetrievalResult> {
  // Try real tracked conversion data first
  try {
    const conversions = await getConversionSummary(ctx.brandId, "30d");
    const traffic = await getTrafficSummary(ctx.brandId, "30d");

    if (conversions && conversions.totalConversions > 0) {
      const byTypeStr = Object.entries(conversions.byType).map(([k, v]) => `${k}: ${v}`).join(", ");
      const topPagesStr = conversions.topConvertingPages.slice(0, 3).map(p => `${p.url} (${p.conversions})`).join(", ");
      const utmStr = conversions.byUtmSource.slice(0, 3).map(s => `${s.source} (${s.conversions})`).join(", ");

      return {
        module: "Conversion Intelligence",
        summary: [
          `${ctx.brandName} conversion data (last 30 days, from meSEO Site Tag):`,
          `- Total conversions: ${conversions.totalConversions}`,
          `- Conversion rate: ${conversions.conversionRate}% (${conversions.totalConversions} conversions / ${traffic?.sessions ?? "?"} sessions)`,
          `- By type: ${byTypeStr}`,
          `- Top converting pages: ${topPagesStr || "N/A"}`,
          `- By source: ${utmStr || "N/A (no UTM tags detected)"}`,
        ].join("\n"),
        metrics: {
          totalConversions: conversions.totalConversions,
          conversionRate: `${conversions.conversionRate}%`,
          topConvertingPage: conversions.topConvertingPages[0]?.url ?? "N/A",
          formSubmits: conversions.byType.form_submit ?? 0,
          clickToCalls: conversions.byType.click_to_call ?? 0,
        },
      };
    }
  } catch { /* fall through to mock */ }

  // Fallback mock data
  return {
    module: "Conversion Intelligence",
    summary: [
      `${ctx.brandName} conversion data:`,
      "- Total conversions: 487 across 5 channels",
      "- Organic: 186 conversions ($93K revenue, 4.4% rate)",
      "- GBP: 142 conversions ($71K revenue)",
      "- AI Search: 67 conversions ($33.5K, highest rev/conv at $500)",
      "- Direct: 58 conversions ($29K)",
      "- Social: 34 conversions ($17K, but 264 assisted touches)",
      "- Top conversion type: Phone calls (46.2%)",
      "- ROI multiple: 3.2x across all channels",
      "- Note: Install meSEO Site Tag to see real conversion tracking here",
    ].join("\n"),
    metrics: {
      totalConversions: 487,
      totalRevenue: 243500,
      topChannel: "Organic",
      roiMultiple: "3.2x",
      phoneCallPct: "46.2%",
    },
  };
}

// ─── Technical Audit ─────────────────────────────────────────────────────────

export async function retrieveTechnicalAudit(ctx: AvatarContext): Promise<RetrievalResult> {
  return {
    module: "Technical Audit",
    summary: [
      `${ctx.brandName} technical health:`,
      "- Site health score: 68/100",
      "- Errors: 17 (critical — meta descriptions, broken links, duplicate titles)",
      "- Warnings: 34 (images missing alt, oversized images, no structured data)",
      "- Notices: 12 (missing H1, slow pages, missing canonicals)",
      "- Passed audits: 89",
      "- Top fix: Write meta descriptions for 14 pages (+8% CTR est.)",
      "- Second fix: Resolve 17 broken internal links (+5% crawl efficiency)",
      "- Estimated impact of fixing all: +18% traffic, +11% conversions",
    ].join("\n"),
    metrics: {
      healthScore: 68,
      errors: 17,
      warnings: 34,
      notices: 12,
      passed: 89,
      estTrafficLift: "+18%",
    },
  };
}

// ─── Competitors ─────────────────────────────────────────────────────────────

export async function retrieveCompetitors(ctx: AvatarContext): Promise<RetrievalResult> {
  return {
    module: "Competitors",
    summary: [
      `${ctx.brandName} competitive landscape:`,
      "- 6 competitors tracked",
      "- Your visibility score: 74/100 (rank #4 among tracked competitors)",
      "- Top threat: Moz Blog (score 92, 18 pts ahead)",
      "- SEMrush Blog: score 89 (publishes 20+ articles/week)",
      "- ContentKing: score 87 (strong pillar content strategy)",
      "- Fastest riser: RankFast (+16 pts in 6 months)",
      "- Key opportunity: No competitor covers AI/LLMO visibility",
      "- Key opportunity: 40% of Moz's pages haven't been updated in 12+ months",
    ].join("\n"),
    metrics: {
      competitorsTracked: 6,
      yourScore: 74,
      yourRank: 4,
      topThreat: "Moz Blog",
      topThreatScore: 92,
      visibilityGap: -18,
    },
  };
}

// ─── Content Briefs ──────────────────────────────────────────────────────────

export async function retrieveContentBriefs(ctx: AvatarContext): Promise<RetrievalResult> {
  return {
    module: "Content Briefs",
    summary: [
      `${ctx.brandName} content pipeline:`,
      "- Active SEO briefs: 4 (2 in draft, 1 in review, 1 published)",
      "- Active LLMO briefs: 3 (1 in draft, 2 in review)",
      "- Avg SEO brief score: 72/100",
      "- Avg LLMO brief score: 68/100",
      "- Top keyword target: 'technical SEO checklist' (2,400 searches/mo)",
      "- Briefs ready to publish: 2 (estimated +2,100 visits/mo)",
      "- Content gap: No briefs targeting AI visibility keywords yet",
    ].join("\n"),
    metrics: {
      seoBriefs: 4,
      llmoBriefs: 3,
      avgSeoScore: 72,
      avgLlmoScore: 68,
      readyToPublish: 2,
    },
  };
}

// ─── Local GEO ──────────────────────────────────────────────────────────────

export async function retrieveLocalGeo(ctx: AvatarContext): Promise<RetrievalResult> {
  // Try real GBP data first
  try {
    const gbp = await getGbpSummary(ctx.brandId, 28);
    if (gbp && (gbp.location || gbp.recentReviews.length > 0)) {
      const loc = gbp.location;
      const m = gbp.metrics;
      const reviewSnippets = gbp.recentReviews.slice(0, 3).map(r =>
        `${r.rating}★ by ${r.authorName}${r.comment ? `: "${r.comment.slice(0, 60)}..."` : ""}`
      ).join("; ");

      return {
        module: "Local GEO",
        summary: [
          `${ctx.brandName} Google Business Profile data (last 28 days):`,
          loc ? `- Location: ${loc.name}` : "- Location: not configured",
          loc?.address ? `- Address: ${loc.address}` : null,
          loc?.category ? `- Category: ${loc.category}` : null,
          loc ? `- Avg rating: ${loc.avgRating}/5 (${loc.totalReviews} reviews)` : null,
          `- Total search appearances: ${m.searchesTotal.toLocaleString()}`,
          `- Direct searches (by name): ${m.searchesDirect.toLocaleString()}`,
          `- Discovery searches (category): ${m.searchesDiscovery.toLocaleString()}`,
          `- Profile views: ${m.viewsTotal.toLocaleString()}`,
          `- Website clicks: ${m.actionsWebsite.toLocaleString()}`,
          `- Phone call clicks: ${m.actionsPhone.toLocaleString()}`,
          `- Direction requests: ${m.actionsDirections.toLocaleString()}`,
          reviewSnippets ? `- Recent reviews: ${reviewSnippets}` : null,
          `- Rating breakdown: 5★=${gbp.ratingBreakdown[5]}, 4★=${gbp.ratingBreakdown[4]}, 3★=${gbp.ratingBreakdown[3]}, 2★=${gbp.ratingBreakdown[2]}, 1★=${gbp.ratingBreakdown[1]}`,
        ].filter(Boolean).join("\n"),
        metrics: {
          avgRating: loc?.avgRating ?? 0,
          totalReviews: loc?.totalReviews ?? 0,
          searchesTotal: m.searchesTotal,
          viewsTotal: m.viewsTotal,
          actionsPhone: m.actionsPhone,
          actionsWebsite: m.actionsWebsite,
          actionsDirections: m.actionsDirections,
        },
      };
    }
  } catch { /* fall through to mock */ }

  // Fallback mock data
  return {
    module: "Local GEO",
    summary: [
      `${ctx.brandName} local visibility across 8 markets:`,
      "- Markets tracked: 8 (NYC, LA, Chicago, Houston, Phoenix, Seattle, Miami, Denver)",
      "- Strongest market: Seattle (score 85, #1 in AI Visibility, +18 pts trend)",
      "- Weakest market: Denver (completely untapped — 0 presence, 11k searches/mo)",
      "- Declining market: Phoenix (score 45, -4 pts this period, all services below 52)",
      "- Average visibility across active markets: 68/100",
      "- Note: Connect Google Business Profile to see real local data here",
    ].join("\n"),
    metrics: {
      marketsTracked: 8,
      strongMarkets: 2,
      weakMarkets: 3,
      avgVisibility: 68,
      bestMarket: "Seattle",
      worstMarket: "Denver",
    },
  };
}

// ─── SEO Content Brief ──────────────────────────────────────────────────────

export async function retrieveSeoContentBrief(ctx: AvatarContext): Promise<RetrievalResult> {
  return {
    module: "SEO Content Brief",
    summary: [
      `${ctx.brandName} SEO content pipeline:`,
      "- Active SEO briefs: 4",
      "- Status breakdown: 2 in draft, 1 in review, 1 published",
      "- Average SEO score: 72/100 (keyword coverage 35%, internal linking 25%, structure 40%)",
      "- Top keyword target: 'technical SEO checklist' (2,400 searches/mo, difficulty 38)",
      "- Second keyword: 'site audit tool' (1,800 searches/mo, difficulty 45)",
      "- Briefs ready to publish: 1 (est. +1,200 visits/mo)",
      "- Weakest scoring area: Internal linking strength (avg 58/100)",
      "- SERP competition: 2 of 4 target keywords have featured snippets held by competitors",
      "- Content gap: No briefs targeting 'AI SEO' or 'LLMO optimization' keyword clusters",
    ].join("\n"),
    metrics: {
      activeBriefs: 4,
      drafts: 2,
      inReview: 1,
      published: 1,
      avgScore: 72,
      readyToPublish: 1,
      weakestArea: "Internal linking",
    },
  };
}

// ─── LLMO Content Brief ─────────────────────────────────────────────────────

export async function retrieveLlmoContentBrief(ctx: AvatarContext): Promise<RetrievalResult> {
  return {
    module: "LLMO Content Brief",
    summary: [
      `${ctx.brandName} LLMO/AI content pipeline:`,
      "- Active LLMO briefs: 3",
      "- Status breakdown: 1 in draft, 2 in review",
      "- Average LLMO score: 68/100 (conversational depth 30%, long-tail 30%, answer-ready 40%)",
      "- Weakest area: Answer-ready format (avg 55/100) — content isn't structured for AI extraction",
      "- Strongest area: Long-tail coverage (avg 74/100)",
      "- AI citation potential: 2 briefs target queries where ChatGPT currently cites competitors",
      "- Recommended structure: FAQ blocks, direct-answer H2s, structured data markup",
      "- Opportunity: 'what is LLMO' has 3,200 searches/mo with no authoritative AI-optimized page",
      "- 5 existing pages could be retrofitted for AI visibility with formatting changes only",
    ].join("\n"),
    metrics: {
      activeBriefs: 3,
      drafts: 1,
      inReview: 2,
      avgScore: 68,
      weakestArea: "Answer-ready format",
      retrofitCandidates: 5,
    },
  };
}

// ─── Execution Hub ──────────────────────────────────────────────────────────

export async function retrieveExecutionHub(ctx: AvatarContext): Promise<RetrievalResult> {
  return {
    module: "Execution Hub",
    summary: [
      `${ctx.brandName} task management:`,
      "- Total active tasks: 18",
      "- By priority: 5 high, 8 medium, 5 low",
      "- By status: 6 to-do, 7 in-progress, 5 completed",
      "- Overdue tasks: 3 (all high priority)",
      "- Overdue: 'Fix broken internal links' (due 5 days ago, affects 17 pages)",
      "- Overdue: 'Write meta descriptions' (due 3 days ago, affects 14 pages)",
      "- Overdue: 'Compress oversized images' (due 1 day ago, affects 23 pages)",
      "- Tasks created this week: 4",
      "- Tasks completed this week: 2",
      "- Estimated impact of completing overdue tasks: +2,200 visits/mo, +26 leads/mo",
      "- Next due: 'Add structured data to product pages' (due in 2 days)",
    ].join("\n"),
    metrics: {
      totalTasks: 18,
      highPriority: 5,
      overdue: 3,
      completedThisWeek: 2,
      todoCount: 6,
      inProgressCount: 7,
    },
  };
}

// ─── Page Launch Tracker ────────────────────────────────────────────────────

export async function retrieveLaunchTracker(ctx: AvatarContext): Promise<RetrievalResult> {
  return {
    module: "Page Launch Tracker",
    summary: [
      `${ctx.brandName} page launch pipeline:`,
      "- Total pages in pipeline: 8",
      "- Status: 2 drafting, 3 in review, 2 approved (ready to launch), 1 live",
      "- Pages ready to launch: 2",
      "  - '/blog/ai-seo-guide' — targeting 'AI SEO' (1,900 searches/mo)",
      "  - '/resources/technical-checklist' — targeting 'SEO checklist' (2,400 searches/mo)",
      "- Estimated traffic from launching both: +1,400 visits/mo",
      "- Top performer (live): '/blog/content-strategy' — 3,200 visits/mo since launch",
      "- Average time from draft to launch: 12 days",
      "- Bottleneck: Review stage (avg 5 days, 3 pages currently waiting)",
    ].join("\n"),
    metrics: {
      totalPages: 8,
      readyToLaunch: 2,
      inReview: 3,
      live: 1,
      estTrafficFromReady: 1400,
      avgDaysToLaunch: 12,
    },
  };
}

// ─── Router: pick the right retrieval function ───────────────────────────────

/**
 * Given the user's current page, fetch the most relevant data summary.
 * The router matches the longest prefix first, so /llmo-content-brief
 * matches before the generic /content-brief fallback.
 */
export async function retrieveForPage(ctx: AvatarContext): Promise<RetrievalResult> {
  const page = ctx.currentPage;

  if (page.startsWith("/dashboard") || page === "/")
    return retrieveDashboard(ctx);
  if (page.startsWith("/conversion-intelligence") || page.startsWith("/site-tag-analytics"))
    return retrieveConversions(ctx);
  if (page.startsWith("/technical-audit"))
    return retrieveTechnicalAudit(ctx);
  if (page.startsWith("/competitors"))
    return retrieveCompetitors(ctx);
  if (page.startsWith("/local-geo"))
    return retrieveLocalGeo(ctx);
  if (page.startsWith("/llmo-content-brief"))
    return retrieveLlmoContentBrief(ctx);
  if (page.startsWith("/content-brief"))
    return retrieveSeoContentBrief(ctx);
  if (page.startsWith("/execution-hub"))
    return retrieveExecutionHub(ctx);
  if (page.startsWith("/page-launch-tracker"))
    return retrieveLaunchTracker(ctx);

  // Fallback: return the dashboard overview
  return retrieveDashboard(ctx);
}

// ─── Intent-based multi-module retrieval ─────────────────────────────────────

/**
 * Keyword → module mapping for intent detection.
 * When a user asks a question, we scan for these keywords to decide
 * which modules to include. Multiple modules can match.
 */
const INTENT_MAP: Array<{ keywords: string[]; retriever: (ctx: AvatarContext) => Promise<RetrievalResult> }> = [
  { keywords: ["traffic", "session", "pageview", "visit", "bounce", "organic"],       retriever: retrieveDashboard },
  { keywords: ["conversion", "revenue", "roi", "funnel", "attribution", "phone", "form", "lead"], retriever: retrieveConversions },
  { keywords: ["technical", "audit", "error", "broken", "crawl", "meta", "health", "fix", "issue"], retriever: retrieveTechnicalAudit },
  { keywords: ["competitor", "compete", "moz", "semrush", "threat", "gap", "outrank"],  retriever: retrieveCompetitors },
  { keywords: ["local", "geo", "city", "market", "gbp", "maps", "review", "rating", "location"], retriever: retrieveLocalGeo },
  { keywords: ["seo brief", "seo content", "keyword", "serp", "ranking", "position"],   retriever: retrieveSeoContentBrief },
  { keywords: ["llmo", "ai content", "ai brief", "chatgpt", "perplexity", "ai visibility", "citation", "answer-ready"], retriever: retrieveLlmoContentBrief },
  { keywords: ["task", "execution", "overdue", "backlog", "to-do", "assign", "sprint"],  retriever: retrieveExecutionHub },
  { keywords: ["launch", "pipeline", "publish", "go live", "page launch", "deploy"],     retriever: retrieveLaunchTracker },
];

/**
 * Detect which modules are relevant to the user's question and fetch
 * data from all of them. Returns the current page's data PLUS any
 * modules that match the question's intent.
 *
 * For broad questions ("What should I focus on?"), returns data from
 * dashboard + technical audit + execution hub (the most actionable sources).
 */
export async function retrieveByIntent(
  ctx: AvatarContext,
  message: string
): Promise<RetrievalResult[]> {
  const q = message.toLowerCase();
  const results: RetrievalResult[] = [];
  const fetchedModules = new Set<string>();

  // Always include the current page's data
  const pageData = await retrieveForPage(ctx);
  results.push(pageData);
  fetchedModules.add(pageData.module);

  // Scan the question for intent keywords
  for (const { keywords, retriever } of INTENT_MAP) {
    if (keywords.some(kw => q.includes(kw))) {
      try {
        const data = await retriever(ctx);
        if (!fetchedModules.has(data.module)) {
          results.push(data);
          fetchedModules.add(data.module);
        }
      } catch { /* skip failed retrievers */ }
    }
  }

  // For broad questions, include key modules if not already fetched
  const broadIndicators = ["what should", "priority", "focus", "opportunity", "biggest", "summary", "overview", "client", "what changed", "this week", "this month", "tell my", "what happened", "what is happening", "next step"];
  const isBroad = broadIndicators.some(kw => q.includes(kw));

  if (isBroad) {
    const broadRetrievers = [retrieveDashboard, retrieveTechnicalAudit, retrieveExecutionHub, retrieveCompetitors];
    for (const retriever of broadRetrievers) {
      try {
        const data = await retriever(ctx);
        if (!fetchedModules.has(data.module)) {
          results.push(data);
          fetchedModules.add(data.module);
        }
      } catch { /* skip */ }
    }
  }

  // Cap at 5 modules to stay within token limits
  return results.slice(0, 5);
}
