/**
 * Analytics Adapter
 * ------------------
 * Gates analytics data behind real connected integration status.
 * No data is returned unless the source integration is connected
 * and has real (non-seed) data.
 *
 * This is the single entry point for any page or API that needs
 * conversion, traffic, or channel analytics data.
 */

import { prisma } from "@/lib/prisma";
import { getConversionData } from "./conversions";
import type { DateRange, CompareMode } from "./date-utils";

export type AnalyticsStatus = "connected" | "not_connected" | "no_data";

export interface AnalyticsResult<T> {
  status: AnalyticsStatus;
  /** Which integrations are connected */
  sources: { ga4: boolean; gsc: boolean };
  /** The data (null if not connected or no data) */
  data: T | null;
}

/**
 * Check which analytics integrations are connected for a brand.
 */
export async function getConnectedSources(brandId: string): Promise<{ ga4: boolean; gsc: boolean }> {
  const integrations = await prisma.brandIntegration.findMany({
    where: { brandId, integrationId: { in: ["ga4", "gsc"] }, connected: true },
    select: { integrationId: true, status: true },
  });

  return {
    ga4: integrations.some((i) => i.integrationId === "ga4" && i.status === "connected"),
    gsc: integrations.some((i) => i.integrationId === "gsc" && i.status === "connected"),
  };
}

/**
 * Get conversion intelligence data, gated behind connected sources.
 * Returns real data only when GA4 or GSC is connected AND real data exists.
 */
export async function getConversionIntelligence(
  brandId: string,
  range: DateRange = "30d",
  compare: CompareMode = "previous"
): Promise<AnalyticsResult<Awaited<ReturnType<typeof getConversionData>>>> {
  const sources = await getConnectedSources(brandId);

  if (!sources.ga4 && !sources.gsc) {
    return { status: "not_connected", sources, data: null };
  }

  // Check that real (non-seed) data exists — require source from a connected integration
  const realSources = ["ga4", "gsc"];
  const realEventCount = await prisma.conversionEvent.count({
    where: { brandId, source: { in: realSources } },
  });

  const realMetricCount = await prisma.metricSnapshot.count({
    where: { brandId, source: { in: realSources } },
  });

  if (realEventCount === 0 && realMetricCount === 0) {
    return { status: "no_data", sources, data: null };
  }

  const data = await getConversionData(brandId, range, compare, { sourceFilter: realSources });
  return { status: "connected", sources, data };
}

/**
 * Get a quick traffic summary, gated behind connected GA4.
 */
export async function getTrafficSummary(brandId: string): Promise<AnalyticsResult<{
  sessions: number;
  users: number;
  conversions: number;
  revenue: number;
  channels: Array<{ channel: string; sessions: number; conversions: number }>;
}>> {
  const sources = await getConnectedSources(brandId);

  if (!sources.ga4) {
    return { status: "not_connected", sources, data: null };
  }

  // Only use real source data
  const now = new Date();
  const thirtyDaysAgo = new Date(now.getTime() - 30 * 86400000);

  const snapshots = await prisma.metricSnapshot.findMany({
    where: { brandId, date: { gte: thirtyDaysAgo, lte: now }, source: { in: ["ga4", "gsc"] } },
  });

  if (snapshots.length === 0) {
    return { status: "no_data", sources, data: null };
  }

  const sessions = snapshots.reduce((s, m) => s + m.sessions, 0);
  const users = snapshots.reduce((s, m) => s + m.users, 0);
  const conversions = snapshots.reduce((s, m) => s + m.conversions, 0);
  const revenue = snapshots.reduce((s, m) => s + m.revenue, 0);

  // Channel breakdown — filter by real sources only
  const channelMetrics = await prisma.channelMetric.findMany({
    where: { brandId, date: { gte: thirtyDaysAgo, lte: now }, source: { in: ["ga4", "gsc"] } },
  });

  const channelMap: Record<string, { sessions: number; conversions: number }> = {};
  for (const m of channelMetrics) {
    if (!channelMap[m.channel]) channelMap[m.channel] = { sessions: 0, conversions: 0 };
    channelMap[m.channel].sessions += m.sessions;
    channelMap[m.channel].conversions += m.conversions;
  }

  return {
    status: "connected",
    sources,
    data: {
      sessions,
      users,
      conversions,
      revenue: Math.round(revenue),
      channels: Object.entries(channelMap).map(([channel, d]) => ({ channel, ...d })).sort((a, b) => b.sessions - a.sessions),
    },
  };
}
