import { prisma } from "@/lib/prisma";
import {
  lookupEnrichment,
  inferCategoryFromKey,
  type IntegrationCategory,
} from "@/lib/site-tag/integration-signatures";

// Single-plugin record -- extracted from either the new plugins[] array or
// the legacy flat metadata shape.
interface SinglePluginEntry {
  plugin: string;
  plugin_key: string;
  category: string | null;
  version: string | null;
}

// Normalize metadata into an array of single-plugin entries.
// New payload: { plugins: [{plugin, plugin_key, category, version}, ...] }
// Legacy payload: { plugin: "...", plugin_key: "...", category: "...", version: "..." }
function extractPluginEntries(meta: Record<string, unknown>): SinglePluginEntry[] {
  if (Array.isArray(meta.plugins)) {
    return (meta.plugins as unknown[])
      .filter((p): p is Record<string, unknown> => typeof p === "object" && p !== null)
      .map((p) => ({
        plugin: typeof p.plugin === "string" ? p.plugin : "",
        plugin_key: typeof p.plugin_key === "string" ? p.plugin_key : "",
        category: typeof p.category === "string" ? p.category : null,
        version: typeof p.version === "string" && p.version ? p.version.slice(0, 30) : null,
      }))
      .filter((p) => p.plugin.length > 0);
  }
  // Legacy single-plugin flat shape
  const plugin = typeof meta.plugin === "string" ? meta.plugin : null;
  if (!plugin) return [];
  return [{
    plugin,
    plugin_key: typeof meta.plugin_key === "string" ? meta.plugin_key : "",
    category: typeof meta.category === "string" ? meta.category : null,
    version: typeof meta.version === "string" && meta.version ? meta.version.slice(0, 30) : null,
  }];
}

export async function upsertDetectedIntegration(args: {
  brandId: string;
  eventType: string;
  metadata: Record<string, unknown> | undefined;
  pageUrl: string;
  timestamp: Date;
}): Promise<void> {
  if (args.eventType !== "plugin_detected") return;

  const meta = args.metadata ?? {};
  const entries = extractPluginEntries(meta);
  if (entries.length === 0) return;

  // Upsert each plugin entry independently -- same logic as before, now
  // applied per entry so the consolidated array payload works correctly.
  for (const entry of entries) {
    await upsertSinglePlugin({
      brandId: args.brandId,
      pageUrl: args.pageUrl,
      timestamp: args.timestamp,
      entry,
    });
  }
}

async function upsertSinglePlugin(args: {
  brandId: string;
  pageUrl: string;
  timestamp: Date;
  entry: SinglePluginEntry;
}): Promise<void> {
  const { brandId, pageUrl, timestamp, entry } = args;
  const { plugin, plugin_key: pluginKey, category: metaCategory, version: metaVersion } = entry;

  const enrichment = pluginKey ? lookupEnrichment(pluginKey) : null;
  const category = (
    metaCategory ||
    enrichment?.category ||
    (pluginKey ? inferCategoryFromKey(pluginKey) : "other")
  ) as IntegrationCategory;

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const di = (prisma as any).detectedIntegration;

  const existing = await di.findUnique({
    where: { brandId_name: { brandId, name: plugin } },
    select: { lastDetectedAt: true, samplePages: true, pageCount: true },
  }) as { lastDetectedAt: Date; samplePages: string[]; pageCount: number } | null;

  if (!existing) {
    await di.create({
      data: {
        brandId,
        name: plugin,
        category,
        vendor: enrichment?.vendor ?? null,
        version: metaVersion,
        firstDetectedAt: timestamp,
        lastDetectedAt: timestamp,
        detectionSources: pluginKey ? [pluginKey] : [],
        pageCount: 1,
        samplePages: pageUrl ? [pageUrl] : [],
        evidence: { plugin_key: pluginKey, category: metaCategory },
        status: "active",
        isActive: true,
      },
    });
    return;
  }

  // Rate limit: skip update if fewer than 60 seconds have elapsed.
  const secondsSinceLast = (timestamp.getTime() - existing.lastDetectedAt.getTime()) / 1000;
  if (secondsSinceLast < 60) return;

  const prevPages: string[] = Array.isArray(existing.samplePages) ? existing.samplePages : [];
  const pageAlreadySeen = prevPages.includes(pageUrl);
  const newPages = pageAlreadySeen
    ? prevPages
    : [...prevPages, pageUrl].slice(-10);
  const newPageCount = pageAlreadySeen ? existing.pageCount : existing.pageCount + 1;

  await di.update({
    where: { brandId_name: { brandId, name: plugin } },
    data: {
      lastDetectedAt: timestamp,
      samplePages: newPages,
      pageCount: newPageCount,
      vendor: enrichment?.vendor ?? null,
      ...(metaVersion ? { version: metaVersion } : {}),
      status: "active",
      isActive: true,
    },
  });
}
