/**
 * Source Registry — single source of truth for all platform data source statuses.
 *
 * Every sidebar page can read from this instead of independently querying
 * its own status. Resolves one canonical status per source for a brand.
 */

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

// ─── Types ──────────────────────────────────────────────────────────────────

export type SourceStatus =
  | "connected"           // active, has recent data
  | "not_connected"       // integration not set up
  | "no_data"             // connected/exists but no data yet
  | "queued"              // run is scheduled but not started
  | "running"             // audit or sync in progress
  | "completed"           // run finished successfully (alias for connected with recent data)
  | "stale"               // has data, but older than threshold
  | "failed"              // last run/sync failed
  | "partial_failure"     // some data collected, some failed
  | "partially_available" // some data exists, not fully set up
  | "awaiting_first_run"; // source is set up but has never been run

export interface SourceEntry {
  id: string;
  label: string;
  status: SourceStatus;
  /** Optional: when data was last updated */
  lastUpdated: string | null;
  /** Optional: extra context (error message, count, etc.) */
  detail: string | null;
}

export type SourceMap = Record<string, SourceEntry>;

/** How many days before data is considered stale */
const STALE_DAYS = 30;

function isStale(date: Date | null | undefined): boolean {
  if (!date) return true;
  return Date.now() - date.getTime() > STALE_DAYS * 86400000;
}

// ─── Registry Builder ───────────────────────────────────────────────────────

export async function getSourceStatuses(brandId: string): Promise<SourceMap> {
  const [
    siteTag,
    techAudit,
    techAuditRunning,
    perfAudit,
    deadPages,
    conversionData,
    aiVisibility,
    aiVisibilityChecks,
    aiVisibilityQueries,
    competitors,
    localGeo,
    ga4,
    gsc,
    tasks,
    brandProfile,
    website,
  ] = await Promise.all([
    // Site Tag
    prisma.trackedSite.findFirst({
      where: { brandId },
      select: { id: true, status: true, lastEventAt: true },
    }),
    // Technical Audit — latest completed
    prisma.technicalAudit.findFirst({
      where: { brandId, status: "completed" },
      orderBy: { createdAt: "desc" },
      select: { id: true, completedAt: true, errorCount: true, warningCount: true },
    }),
    // Technical Audit — currently running?
    prisma.technicalAudit.findFirst({
      where: { brandId, status: "running" },
      select: { id: true },
    }),
    // Performance Audit — latest completed or running
    prisma.performanceAudit.findFirst({
      where: { brandId },
      orderBy: { createdAt: "desc" },
      select: { id: true, status: true, completedAt: true, createdAt: true },
    }),
    // Dead Pages
    prisma.deadPage.count({ where: { brandId, status: "open" } }),
    // Conversion data (real sources only)
    prisma.metricSnapshot.count({
      where: { brandId, source: { in: ["ga4", "gsc"] } },
    }),
    // AI Visibility — three signals, any of which means the user has
    // engaged with the feature:
    //   1. AiVisibilitySnapshot — periodic aggregate snapshot.
    //   2. AiVisibilityCheck    — individual platform query results.
    //   3. AiVisibilityQuery    — saved tracking queries.
    // The previous implementation only checked snapshots, so brands
    // that had added queries / run checks but never had a snapshot
    // generated would see "Set up AI visibility tracking" forever.
    prisma.aiVisibilitySnapshot.findFirst({
      where: { brandId },
      orderBy: { date: "desc" },
      select: { date: true },
    }),
    prisma.aiVisibilityCheck.findFirst({
      where: { brandId },
      orderBy: { checkedAt: "desc" },
      select: { checkedAt: true },
    }),
    prisma.aiVisibilityQuery.count({ where: { brandId, isActive: true } }),
    // Competitors — only active rows. Soft-deleted Competitor rows
    // stay in the table with isActive=false; without this filter the
    // source-status count disagreed with the Dashboard + Competitor
    // Intel page (which both filter by isActive).
    prisma.competitor.count({ where: { brandId, isActive: true } }),
    // Local GEO
    prisma.gbpLocation.findFirst({
      where: { brandId },
      select: { id: true, isActive: true, updatedAt: true },
    }),
    // GA4 integration
    prisma.brandIntegration.findFirst({
      where: { brandId, integrationId: "ga4" },
      select: { connected: true, status: true, lastSynced: true, syncError: true },
    }),
    // GSC integration
    prisma.brandIntegration.findFirst({
      where: { brandId, integrationId: "gsc" },
      select: { connected: true, status: true, lastSynced: true, syncError: true },
    }),
    // Execution Hub
    prisma.task.count({ where: { brandId } }),
    // Brand Profile
    prisma.brandProfile.findFirst({
      where: { brandId },
      select: { extractedAt: true, companyName: true },
    }),
    // Website
    prisma.website.findFirst({
      where: { brandId },
      select: { isVerified: true, lastCrawled: true },
    }),
  ]);

  const sources: SourceMap = {};

  // ── Site Tag ──
  sources.site_tag = {
    id: "site_tag",
    label: "Site Tag",
    ...resolveSiteTag(siteTag),
  };

  // ── Technical Audit ──
  sources.technical_audit = {
    id: "technical_audit",
    label: "Technical Audit",
    ...resolveTechAudit(techAudit, techAuditRunning),
  };

  // ── Core Web Intelligence (Performance Audit) ──
  sources.performance_audit = {
    id: "performance_audit",
    label: "Core Web Intelligence",
    status: perfAudit
      ? perfAudit.status === "running" ? "running"
        : perfAudit.status === "failed" ? "failed"
        : perfAudit.status === "completed" ? (isStale(perfAudit.completedAt) ? "stale" : "connected")
        : "awaiting_first_run"
      : "awaiting_first_run",
    lastUpdated: perfAudit?.completedAt?.toISOString() ?? perfAudit?.createdAt?.toISOString() ?? null,
    detail: perfAudit?.status === "running" ? "Audit in progress" : !perfAudit ? "Run your first performance audit" : null,
  };

  // ── Dead 404 Pages ──
  sources.dead_pages = {
    id: "dead_pages",
    label: "Dead 404 Pages",
    status: deadPages > 0 ? "connected" : "no_data",
    lastUpdated: null,
    detail: deadPages > 0 ? `${deadPages} open` : null,
  };

  // ── Conversion Intel ──
  sources.conversion_intel = {
    id: "conversion_intel",
    label: "Conversion Intel",
    ...resolveConversionIntel(ga4, gsc, conversionData),
  };

  // ── AI Visibility ──
  // Status priority:
  //   • snapshot present → status from snapshot freshness (existing behaviour)
  //   • check present    → connected, lastUpdated = check timestamp
  //   • only queries     → connected (the user has set up tracking even
  //                        if no checks have run yet)
  //   • nothing          → no_data
  // Detail line surfaces the most informative metric available so the
  // dashboard card has something to show besides "Set up tracking".
  let aiStatus: "connected" | "stale" | "no_data";
  let aiLastUpdated: string | null = null;
  let aiDetail: string | null = null;
  if (aiVisibility) {
    aiStatus = isStale(aiVisibility.date) ? "stale" : "connected";
    aiLastUpdated = aiVisibility.date.toISOString();
    aiDetail = aiVisibilityQueries > 0
      ? `${aiVisibilityQueries} ${aiVisibilityQueries === 1 ? "query" : "queries"} tracked`
      : null;
  } else if (aiVisibilityChecks) {
    aiStatus = isStale(aiVisibilityChecks.checkedAt) ? "stale" : "connected";
    aiLastUpdated = aiVisibilityChecks.checkedAt.toISOString();
    aiDetail = aiVisibilityQueries > 0
      ? `${aiVisibilityQueries} ${aiVisibilityQueries === 1 ? "query" : "queries"} tracked`
      : "Recent checks available";
  } else if (aiVisibilityQueries > 0) {
    aiStatus = "connected";
    aiDetail = `${aiVisibilityQueries} ${aiVisibilityQueries === 1 ? "query" : "queries"} set up — run a check to populate results`;
  } else {
    aiStatus = "no_data";
  }
  sources.ai_visibility = {
    id: "ai_visibility",
    label: "AI Visibility",
    status: aiStatus,
    lastUpdated: aiLastUpdated,
    detail: aiDetail,
  };

  // ── Competitors ──
  sources.competitors = {
    id: "competitors",
    label: "Competitors",
    status: competitors > 0 ? "connected" : "no_data",
    lastUpdated: null,
    detail: competitors > 0 ? `${competitors} tracked` : null,
  };

  // ── Local GEO ──
  sources.local_geo = {
    id: "local_geo",
    label: "Local GEO",
    status: localGeo
      ? localGeo.isActive ? "connected" : "failed"
      : "not_connected",
    lastUpdated: localGeo?.updatedAt?.toISOString() ?? null,
    detail: null,
  };

  // ── GA4 ──
  sources.ga4 = {
    id: "ga4",
    label: "Google Analytics 4",
    ...resolveIntegration(ga4),
  };

  // ── GSC ──
  sources.gsc = {
    id: "gsc",
    label: "Google Search Console",
    ...resolveIntegration(gsc),
  };

  // ── Execution Hub ──
  sources.execution_hub = {
    id: "execution_hub",
    label: "Execution Hub",
    status: tasks > 0 ? "connected" : "no_data",
    lastUpdated: null,
    detail: tasks > 0 ? `${tasks} tasks` : null,
  };

  // ── Recommendations ──
  // Recommendations are derived from other sources — available if any audit source has data
  const hasAuditData = !!techAudit || deadPages > 0 || !!perfAudit;
  sources.recommendations = {
    id: "recommendations",
    label: "Recommendations",
    status: hasAuditData ? "connected" : "no_data",
    lastUpdated: null,
    detail: null,
  };

  // ── Website Intake ──
  sources.website_intake = {
    id: "website_intake",
    label: "AI Website Intake",
    status: website
      ? website.isVerified ? "connected" : "partially_available"
      : "no_data",
    lastUpdated: website?.lastCrawled?.toISOString() ?? null,
    detail: null,
  };

  // ── AI Avatar / Brand Profile ──
  sources.brand_profile = {
    id: "brand_profile",
    label: "AI Avatar",
    status: brandProfile?.extractedAt
      ? "connected"
      : brandProfile?.companyName
        ? "partially_available"
        : "no_data",
    lastUpdated: brandProfile?.extractedAt?.toISOString() ?? null,
    detail: null,
  };

  return sources;
}

// ─── Resolvers ──────────────────────────────────────────────────────────────

function resolveSiteTag(
  site: { id: string; status: string; lastEventAt: Date | null } | null
): { status: SourceStatus; lastUpdated: string | null; detail: string | null } {
  if (!site) return { status: "not_connected", lastUpdated: null, detail: null };
  if (site.status !== "active") return { status: "not_connected", lastUpdated: null, detail: `Status: ${site.status}` };
  if (!site.lastEventAt) return { status: "awaiting_first_run", lastUpdated: null, detail: "Tag installed, awaiting first event" };
  if (isStale(site.lastEventAt)) return { status: "stale", lastUpdated: site.lastEventAt.toISOString(), detail: "No recent events" };
  return { status: "connected", lastUpdated: site.lastEventAt.toISOString(), detail: null };
}

function resolveTechAudit(
  completed: { id: string; completedAt: Date | null; errorCount: number; warningCount: number } | null,
  running: { id: string } | null
): { status: SourceStatus; lastUpdated: string | null; detail: string | null } {
  if (running) return { status: "running", lastUpdated: null, detail: "Audit in progress" };
  if (!completed) return { status: "awaiting_first_run", lastUpdated: null, detail: "Run your first audit" };
  const issues = completed.errorCount + completed.warningCount;
  return {
    status: isStale(completed.completedAt) ? "stale" : "connected",
    lastUpdated: completed.completedAt?.toISOString() ?? null,
    detail: `${issues} issues`,
  };
}

function resolveIntegration(
  integration: { connected: boolean; status: string; lastSynced: Date | null; syncError: string | null } | null
): { status: SourceStatus; lastUpdated: string | null; detail: string | null } {
  if (!integration) return { status: "not_connected", lastUpdated: null, detail: null };
  if (!integration.connected) return { status: "not_connected", lastUpdated: null, detail: null };
  if (integration.status === "error") return { status: "failed", lastUpdated: integration.lastSynced?.toISOString() ?? null, detail: integration.syncError };
  if (integration.status === "expired") return { status: "failed", lastUpdated: integration.lastSynced?.toISOString() ?? null, detail: "Token expired" };
  if (integration.status === "syncing") return { status: "running", lastUpdated: integration.lastSynced?.toISOString() ?? null, detail: "Syncing" };
  if (!integration.lastSynced) return { status: "awaiting_first_run", lastUpdated: null, detail: "Connected, awaiting first sync" };
  if (isStale(integration.lastSynced)) return { status: "stale", lastUpdated: integration.lastSynced.toISOString(), detail: "No recent sync" };
  return { status: "connected", lastUpdated: integration.lastSynced.toISOString(), detail: null };
}

function resolveConversionIntel(
  ga4: { connected: boolean; status: string; lastSynced: Date | null; syncError: string | null } | null,
  gsc: { connected: boolean; status: string; lastSynced: Date | null; syncError: string | null } | null,
  dataCount: number
): { status: SourceStatus; lastUpdated: string | null; detail: string | null } {
  const hasConnectedSource = (ga4?.connected && ga4.status !== "error") || (gsc?.connected && gsc.status !== "error");
  if (!hasConnectedSource && dataCount === 0) return { status: "not_connected", lastUpdated: null, detail: "Connect GA4 or GSC" };
  if (hasConnectedSource && dataCount === 0) return { status: "awaiting_first_run", lastUpdated: null, detail: "Connected, awaiting first sync" };
  if (!hasConnectedSource && dataCount > 0) return { status: "partially_available", lastUpdated: null, detail: "Historical data only" };
  return { status: "connected", lastUpdated: null, detail: `${dataCount} snapshots` };
}
