// src/lib/keywords/theme-context.tsx
"use client";

import { createContext, useContext, useEffect, useMemo, useState } from "react";
import {
  createThemeAction,
  fetchThemesForSiteAction,
  renameThemeAction,
} from "./actions";
import { useActiveSite } from "./site-context";
import type { KeywordTheme } from "./types";

interface ThemeLabelsValue {
  /** Ordered themes (per active site) with their current labels. */
  themes: { id: KeywordTheme; label: string }[];
  labelOf: (id: KeywordTheme) => string;
  rename: (id: KeywordTheme, label: string) => void;
  /** Create a per-site category; returns its id, or null if invalid. */
  create: (label: string) => Promise<KeywordTheme | null>;
}

const ThemeLabelsContext = createContext<ThemeLabelsValue | null>(null);

export function ThemeLabelsProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const { activeSiteId } = useActiveSite();
  const [themes, setThemes] = useState<{ id: KeywordTheme; label: string }[]>(
    [],
  );

  useEffect(() => {
    // No active site (org with zero sites) → nothing to fetch. This provider
    // wraps the whole (app) layout, so skipping the empty-id call avoids a
    // pointless round trip on every page.
    if (!activeSiteId) {
      setThemes([]);
      return;
    }
    let cancelled = false;
    fetchThemesForSiteAction(activeSiteId)
      .then((rows) => {
        if (cancelled) return;
        setThemes(
          rows.map((r) => ({ id: r.slug as KeywordTheme, label: r.label })),
        );
      })
      .catch(() => {});
    return () => {
      cancelled = true;
    };
  }, [activeSiteId]);

  const value = useMemo<ThemeLabelsValue>(
    () => ({
      themes,
      labelOf: (id) => themes.find((t) => t.id === id)?.label ?? id,
      rename: (id, label) => {
        const trimmed = label.trim();
        if (!trimmed) return;
        setThemes((prev) =>
          prev.map((t) => (t.id === id ? { ...t, label: trimmed } : t)),
        );
        void renameThemeAction(activeSiteId, id, trimmed).catch(() => {});
      },
      create: async (label) => {
        const res = await createThemeAction(activeSiteId, label).catch(
          () => null,
        );
        if (!res) return null;
        const id = res.slug as KeywordTheme;
        setThemes((prev) =>
          prev.some((t) => t.id === id)
            ? prev
            : [...prev, { id, label: res.label }],
        );
        return id;
      },
    }),
    [themes, activeSiteId],
  );

  return <ThemeLabelsContext value={value}>{children}</ThemeLabelsContext>;
}

export function useThemeLabels(): ThemeLabelsValue {
  const ctx = useContext(ThemeLabelsContext);
  if (!ctx)
    throw new Error("useThemeLabels must be used within ThemeLabelsProvider");
  return ctx;
}
