/**
 * Lightweight regeneration / creative analytics (JSON store).
 * Tracks regenerations, layouts, industries, and QA outcomes.
 */

import { promises as fs } from "fs";
import path from "path";
import type { BannerLayoutId } from "@/lib/generation/banner-layouts";
import type { GenerationQaScores } from "@/lib/generation/generation-qa";

const DATA_DIR = path.join(process.cwd(), "data");
const ANALYTICS_FILE = path.join(DATA_DIR, "regeneration-analytics.json");

export interface RegenerationAnalyticsEvent {
  id: string;
  timestamp: string;
  type: "generate" | "regenerate";
  postId: string;
  projectId: string;
  industry: string;
  mediaAssetId: string;
  layoutId: BannerLayoutId;
  layoutSeed: number;
  ctaLabel: string;
  qaScores: GenerationQaScores;
  qaPassed: boolean;
  version: number;
  imageUrl: string | null;
  videoUrl: string | null;
  /** Placeholder until player instrumentation lands. */
  videoWatchPercentage: number | null;
}

export interface RegenerationAnalyticsSummary {
  totalEvents: number;
  regenerations: number;
  generations: number;
  regenerationsByPost: Record<string, number>;
  layoutCounts: Record<string, number>;
  layoutPassRate: Record<string, { total: number; passed: number }>;
  ctaCounts: Record<string, number>;
  industryCounts: Record<string, number>;
  averageOverallScore: number;
  averageWatchPercentage: number | null;
}

interface AnalyticsStore {
  events: RegenerationAnalyticsEvent[];
}

async function ensureStore(): Promise<AnalyticsStore> {
  await fs.mkdir(DATA_DIR, { recursive: true });
  try {
    const raw = await fs.readFile(ANALYTICS_FILE, "utf-8");
    const parsed = JSON.parse(raw) as AnalyticsStore;
    return { events: Array.isArray(parsed.events) ? parsed.events : [] };
  } catch {
    const empty: AnalyticsStore = { events: [] };
    await fs.writeFile(ANALYTICS_FILE, JSON.stringify(empty, null, 2), "utf-8");
    return empty;
  }
}

async function writeStore(store: AnalyticsStore): Promise<void> {
  // Cap growth — keep newest 5k events.
  if (store.events.length > 5000) {
    store.events = store.events.slice(-5000);
  }
  await fs.writeFile(ANALYTICS_FILE, JSON.stringify(store, null, 2), "utf-8");
}

export async function trackGenerationAnalytics(
  event: Omit<RegenerationAnalyticsEvent, "id" | "timestamp">,
): Promise<RegenerationAnalyticsEvent> {
  const store = await ensureStore();
  const full: RegenerationAnalyticsEvent = {
    ...event,
    id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
    timestamp: new Date().toISOString(),
  };
  store.events.push(full);
  await writeStore(store);
  return full;
}

export async function summarizeRegenerationAnalytics(): Promise<RegenerationAnalyticsSummary> {
  const store = await ensureStore();
  const regenerationsByPost: Record<string, number> = {};
  const layoutCounts: Record<string, number> = {};
  const layoutPassRate: Record<string, { total: number; passed: number }> = {};
  const ctaCounts: Record<string, number> = {};
  const industryCounts: Record<string, number> = {};
  let regenerations = 0;
  let generations = 0;
  let scoreSum = 0;
  let watchSum = 0;
  let watchN = 0;

  for (const e of store.events) {
    if (e.type === "regenerate") {
      regenerations += 1;
      regenerationsByPost[e.postId] = (regenerationsByPost[e.postId] ?? 0) + 1;
    } else {
      generations += 1;
    }
    layoutCounts[e.layoutId] = (layoutCounts[e.layoutId] ?? 0) + 1;
    const pass = layoutPassRate[e.layoutId] ?? { total: 0, passed: 0 };
    pass.total += 1;
    if (e.qaPassed) pass.passed += 1;
    layoutPassRate[e.layoutId] = pass;

    const cta = e.ctaLabel.trim() || "(none)";
    ctaCounts[cta] = (ctaCounts[cta] ?? 0) + 1;
    const industry = e.industry.trim() || "Unknown";
    industryCounts[industry] = (industryCounts[industry] ?? 0) + 1;
    scoreSum += e.qaScores.overall;
    if (e.videoWatchPercentage != null) {
      watchSum += e.videoWatchPercentage;
      watchN += 1;
    }
  }

  return {
    totalEvents: store.events.length,
    regenerations,
    generations,
    regenerationsByPost,
    layoutCounts,
    layoutPassRate,
    ctaCounts,
    industryCounts,
    averageOverallScore: store.events.length
      ? Math.round((scoreSum / store.events.length) * 10) / 10
      : 0,
    averageWatchPercentage: watchN ? Math.round((watchSum / watchN) * 10) / 10 : null,
  };
}
