"use client";

/**
 * Design kit explorer — persisted starter kit + user overrides per project.
 * See lib/design-kits/* and /api/projects/[id]/design-kit.
 */

import type { CSSProperties, ReactNode } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useParams } from "next/navigation";
import {
  ChevronRight,
  LayoutGrid,
  Loader2,
  Palette,
  RotateCcw,
  Save,
} from "lucide-react";
import { toast } from "sonner";
import type { DesignKitOverrides } from "@/lib/design-kits/types";
import {
  DEFAULT_DESIGN_KIT_ID,
  UI_FOUNDATION_LABELS,
} from "@/lib/design-kits/types";
import { STARTER_KITS, getStarterKit } from "@/lib/design-kits/registry";
import { mergeOverrides, resolveKitTokens } from "@/lib/design-kits/resolve";
import {
  DESIGN_KIT_SECTIONS,
  renderKitPanel,
} from "@/components/project/design-kit-panels";

export function DesignSystemExplorer() {
  const params = useParams();
  const projectId = params.projectId as string;

  const [kitId, setKitId] = useState<string>(DEFAULT_DESIGN_KIT_ID);
  const [perKit, setPerKit] = useState<Record<string, DesignKitOverrides>>({});
  const [draft, setDraft] = useState<DesignKitOverrides>({});
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [openIds, setOpenIds] = useState<Set<string>>(
    () => new Set(["c-accent"]),
  );
  const iframeRef = useRef<HTMLIFrameElement>(null);

  const kit = useMemo(
    () =>
      getStarterKit(kitId) ??
      getStarterKit(DEFAULT_DESIGN_KIT_ID) ??
      STARTER_KITS[0],
    [kitId],
  );
  const savedForKit = perKit[kitId] ?? {};
  const mergedDraft = useMemo(
    () => ({ ...savedForKit, ...draft }),
    [savedForKit, draft],
  );
  const tokens = useMemo(
    () => resolveKitTokens(kit, mergedDraft),
    [kit, mergedDraft],
  );

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    fetch(`/api/projects/${projectId}/design-kit`, { credentials: "include" })
      .then((r) => {
        if (!r.ok)
          throw new Error(
            r.status === 401
              ? "Sign in to load design kit"
              : `HTTP ${r.status}`,
          );
        return r.json();
      })
      .then(
        (d: {
          kitId?: string;
          perKit?: Record<string, DesignKitOverrides>;
        }) => {
          if (cancelled) return;
          if (d.kitId && getStarterKit(d.kitId)) setKitId(d.kitId);
          setPerKit(d.perKit && typeof d.perKit === "object" ? d.perKit : {});
          setDraft({});
        },
      )
      .catch((e: Error) => {
        if (!cancelled) toast.error(e.message || "Failed to load design kit");
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [projectId]);

  const persistKitId = useCallback(
    async (nextId: string) => {
      const res = await fetch(`/api/projects/${projectId}/design-kit`, {
        method: "PATCH",
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ kitId: nextId }),
      });
      if (!res.ok) throw new Error("Could not save kit");
      const data = await res.json();
      setKitId(data.kitId);
      setPerKit(data.perKit ?? {});
      setDraft({});
      toast.success("Starter kit saved", {
        description:
          "Ask Vibn in chat to apply this theme to your codebase (globals.css / Tailwind / theme provider). Large apps may need a token refactor first.",
      });
    },
    [projectId],
  );

  const persistOverrides = useCallback(async () => {
    setSaving(true);
    try {
      const res = await fetch(`/api/projects/${projectId}/design-kit`, {
        method: "PATCH",
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ overrides: draft }),
      });
      if (!res.ok) throw new Error("Could not save customization");
      const data = await res.json();
      setPerKit(data.perKit ?? {});
      setDraft({});
      toast.success("Theme saved", {
        description:
          "Saved to this project for the AI. Ask Vibn in chat to wire these tokens into your app. If colors are scattered across files, it may need a short refactor.",
      });
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Save failed");
    } finally {
      setSaving(false);
    }
  }, [projectId, draft]);

  const resetToKitDefaults = useCallback(() => {
    setDraft({});
    void (async () => {
      try {
        const defaults = kit.defaults;
        const res = await fetch(`/api/projects/${projectId}/design-kit`, {
          method: "PATCH",
          credentials: "include",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            overrides: {
              accentHex: defaults.accentHex,
              radiusMdPx: defaults.radiusMdPx,
              fontPreset: defaults.fontPreset,
              density: defaults.density,
            },
          }),
        });
        if (!res.ok) throw new Error("Reset failed");
        const data = await res.json();
        setPerKit(data.perKit ?? {});
        toast.message("Reset to starter defaults");
      } catch {
        toast.error("Reset failed");
      }
    })();
  }, [kit.defaults, projectId]);

  const toggle = useCallback((id: string) => {
    setOpenIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }, []);

  const effective = mergeOverrides(kit, mergedDraft);

  if (loading) {
    return (
      <div
        style={{
          ...page,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          gap: 12,
        }}
      >
        <Loader2
          className="animate-spin"
          style={{ width: 22, height: 22, color: "#9c9590" }}
        />
        <span style={{ fontSize: "0.85rem", color: "#71717a" }}>
          Loading design kit…
        </span>
      </div>
    );
  }

  return (
    <div style={page}>
      <header style={header}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <div style={headerIcon}>
            <LayoutGrid size={18} strokeWidth={2} />
          </div>
          <div>
            <h1
              style={{
                margin: 0,
                fontSize: "1.05rem",
                fontWeight: 600,
                color: "#18181b",
                letterSpacing: "-0.02em",
              }}
            >
              {kit.name}
            </h1>
            <p
              style={{
                margin: "4px 0 0",
                fontSize: "0.78rem",
                color: "#71717a",
              }}
            >
              {kit.tagline}
              <span
                style={{
                  display: "block",
                  marginTop: 4,
                  fontSize: "0.72rem",
                  color: "#a1a1aa",
                }}
              >
                {UI_FOUNDATION_LABELS[kit.uiFoundation]}
              </span>
            </p>
          </div>
        </div>
        <div
          style={{
            display: "flex",
            flexWrap: "wrap",
            alignItems: "center",
            gap: 10,
          }}
        >
          <label
            style={{
              fontSize: "0.72rem",
              color: "#71717a",
              display: "flex",
              alignItems: "center",
              gap: 8,
            }}
          >
            <Palette size={14} />
            Starter kit
          </label>
          <select
            value={kitId}
            onChange={(e) => {
              const next = e.target.value;
              void persistKitId(next).catch(() =>
                toast.error("Could not switch kit"),
              );
            }}
            style={selectStyle}
          >
            {STARTER_KITS.map((k) => (
              <option key={k.id} value={k.id}>
                {k.name}
              </option>
            ))}
          </select>
        </div>
      </header>

      {kitId === "flyonui" ? (
        <section
          style={{
            marginBottom: 24,
            borderRadius: 12,
            overflow: "hidden",
            border: "1px solid #e4e4e7",
            background: "#fff",
          }}
        >
          <div
            style={{
              padding: "12px 16px",
              borderBottom: "1px solid #e4e4e7",
              display: "flex",
              gap: 12,
              alignItems: "center",
              background: "#fafafa",
            }}
          >
            <span
              style={{ fontSize: "0.85rem", fontWeight: 500, color: "#18181b" }}
            >
              FlyonUI Themes:
            </span>
            {[
              "light",
              "dark",
              "cupcake",
              "retro",
              "cyberpunk",
              "synthwave",
              "valentine",
              "aqua",
            ].map((t) => (
              <button
                key={t}
                type="button"
                onClick={() =>
                  iframeRef.current?.contentWindow?.postMessage(
                    { type: "SET_THEME", theme: t },
                    "*",
                  )
                }
                style={{
                  padding: "6px 12px",
                  borderRadius: 6,
                  border: "1px solid #e4e4e7",
                  background: "#fff",
                  fontSize: "0.75rem",
                  cursor: "pointer",
                  color: "#18181b",
                }}
              >
                {t.charAt(0).toUpperCase() + t.slice(1)}
              </button>
            ))}
          </div>
          <iframe
            ref={iframeRef}
            src="/preview/daisyui"
            style={{
              width: "100%",
              height: 800,
              border: "none",
              display: "block",
            }}
            title="Theme Sandbox"
          />
        </section>
      ) : null}

      <aside style={customizeCard}>
        <div
          style={{
            fontSize: "0.72rem",
            fontWeight: 700,
            letterSpacing: "0.06em",
            color: "#71717a",
            marginBottom: 14,
          }}
        >
          CUSTOMIZE THIS KIT
        </div>
        <div
          style={{
            display: "grid",
            gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))",
            gap: 16,
          }}
        >
          {kit.customizeFields.includes("accent") ? (
            <label style={fieldLabel}>
              Accent color
              <input
                type="color"
                value={effective.accentHex}
                onChange={(e) =>
                  setDraft((d) => ({ ...d, accentHex: e.target.value }))
                }
                style={{
                  width: "100%",
                  height: 40,
                  padding: 4,
                  borderRadius: 8,
                  border: "1px solid #e4e4e7",
                  cursor: "pointer",
                }}
              />
              <input
                type="text"
                value={
                  draft.accentHex ??
                  savedForKit.accentHex ??
                  kit.defaults.accentHex ??
                  ""
                }
                onChange={(e) =>
                  setDraft((d) => ({ ...d, accentHex: e.target.value }))
                }
                style={textInput}
                placeholder="#5f6bf5"
              />
            </label>
          ) : null}
          {kit.customizeFields.includes("radius") ? (
            <label style={fieldLabel}>
              Radius (md) · {effective.radiusMdPx}px
              <input
                type="range"
                min={4}
                max={16}
                value={effective.radiusMdPx}
                onChange={(e) =>
                  setDraft((d) => ({
                    ...d,
                    radiusMdPx: Number(e.target.value),
                  }))
                }
                style={{ width: "100%", marginTop: 8 }}
              />
            </label>
          ) : null}
          {kit.customizeFields.includes("font") ? (
            <label style={fieldLabel}>
              Font
              <select
                value={effective.fontPreset}
                onChange={(e) =>
                  setDraft((d) => ({
                    ...d,
                    fontPreset: e.target
                      .value as DesignKitOverrides["fontPreset"],
                  }))
                }
                style={selectStyleFull}
              >
                <option value="inter">Inter (app default)</option>
                <option value="system">System UI</option>
              </select>
            </label>
          ) : null}
          {kit.customizeFields.includes("density") ? (
            <label style={fieldLabel}>
              Density
              <select
                value={effective.density}
                onChange={(e) =>
                  setDraft((d) => ({
                    ...d,
                    density: e.target.value as DesignKitOverrides["density"],
                  }))
                }
                style={selectStyleFull}
              >
                <option value="comfortable">Comfortable</option>
                <option value="compact">Compact</option>
              </select>
            </label>
          ) : null}
        </div>
        <div
          style={{ display: "flex", flexWrap: "wrap", gap: 10, marginTop: 18 }}
        >
          <button
            type="button"
            disabled={saving || Object.keys(draft).length === 0}
            onClick={() => void persistOverrides()}
            style={btnPrimary}
          >
            <Save size={14} />
            Save customization
          </button>
          <button type="button" onClick={resetToKitDefaults} style={btnGhost}>
            <RotateCcw size={14} />
            Reset to starter defaults
          </button>
        </div>
        <p
          style={{
            fontSize: "0.72rem",
            color: "#a1a1aa",
            marginTop: 14,
            lineHeight: 1.5,
          }}
        >
          Each starter kit keeps its own saved overrides. Switch kits anytime —
          nothing is lost. Next step: export these as CSS variables for codegen
          / dev container.
        </p>
      </aside>

      <div style={{ display: "flex", flexDirection: "column", gap: 28 }}>
        {kit.id === "flyonui" ? (
          <section>
            <div
              style={{
                display: "flex",
                alignItems: "center",
                gap: 12,
                marginBottom: 12,
                flexWrap: "wrap",
              }}
            >
              <span
                style={{
                  fontSize: "0.85rem",
                  fontWeight: 600,
                  color: "#18181b",
                }}
              >
                FlyonUI Themes:
              </span>
              {[
                "light",
                "dark",
                "cupcake",
                "retro",
                "cyberpunk",
                "synthwave",
                "valentine",
                "aqua",
              ].map((t) => (
                <button
                  key={t}
                  type="button"
                  onClick={() =>
                    iframeRef.current?.contentWindow?.postMessage(
                      { type: "SET_THEME", theme: t },
                      "*",
                    )
                  }
                  style={{
                    padding: "6px 12px",
                    borderRadius: 6,
                    border: "1px solid #e4e4e7",
                    background: "#fff",
                    fontSize: "0.75rem",
                    cursor: "pointer",
                    color: "#18181b",
                  }}
                >
                  {t.charAt(0).toUpperCase() + t.slice(1)}
                </button>
              ))}
            </div>
            <iframe
              ref={iframeRef}
              src="/preview/daisyui"
              style={{
                width: "100%",
                height: 800,
                border: "1px solid #e4e4e7",
                borderRadius: 12,
                background: "#fff",
              }}
            />
          </section>
        ) : null}

        {DESIGN_KIT_SECTIONS.map((section) => (
          <section key={section.title}>
            <h2 style={sectionTitle}>{section.title}</h2>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {section.items.map((item) => (
                <AccordionRow
                  key={item.id}
                  open={openIds.has(item.id)}
                  onToggle={() => toggle(item.id)}
                  title={item.title}
                  subtitle={item.subtitle}
                >
                  {renderKitPanel(item.panelKey, tokens)}
                </AccordionRow>
              ))}
            </div>
          </section>
        ))}
      </div>
    </div>
  );
}

function AccordionRow({
  open,
  onToggle,
  title,
  subtitle,
  children,
}: {
  open: boolean;
  onToggle: () => void;
  title: string;
  subtitle?: string;
  children: ReactNode;
}) {
  return (
    <div style={accordionOuter}>
      <button type="button" onClick={onToggle} style={accordionTrigger}>
        <ChevronRight
          size={16}
          strokeWidth={2}
          style={{
            color: "#8c8580",
            flexShrink: 0,
            transform: open ? "rotate(90deg)" : "none",
            transition: "transform 0.15s ease",
          }}
        />
        <div style={{ flex: 1, minWidth: 0, textAlign: "left" }}>
          <div
            style={{ fontSize: "0.875rem", fontWeight: 600, color: "#18181b" }}
          >
            {title}
          </div>
          {subtitle && open ? (
            <div
              style={{
                fontSize: "0.72rem",
                color: "#71717a",
                marginTop: 4,
                fontWeight: 400,
              }}
            >
              {subtitle}
            </div>
          ) : null}
        </div>
        <span
          title="Live preview from your tokens"
          style={{
            width: 7,
            height: 7,
            borderRadius: "50%",
            background: "#3d5afe",
            flexShrink: 0,
          }}
        />
      </button>
      {open ? <div style={accordionBody}>{children}</div> : null}
    </div>
  );
}

const page: CSSProperties = {
  flex: 1,
  minHeight: 0,
  width: "100%",
  overflow: "auto",
  boxSizing: "border-box",
  padding: "28px 36px 48px",
  background: "#fafafa",
  fontFamily: "var(--font-inter), ui-sans-serif, system-ui, sans-serif",
};

const header: CSSProperties = {
  display: "flex",
  flexWrap: "wrap",
  justifyContent: "space-between",
  alignItems: "flex-start",
  gap: 16,
  marginBottom: 22,
  paddingBottom: 20,
  borderBottom: "1px solid #e4e4e7",
};

const headerIcon: CSSProperties = {
  width: 40,
  height: 40,
  borderRadius: 10,
  background: "#fff",
  border: "1px solid #e4e4e7",
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  color: "#52525b",
};

const selectStyle: CSSProperties = {
  padding: "8px 12px",
  borderRadius: 8,
  border: "1px solid #e4e4e7",
  fontSize: "0.82rem",
  background: "#fff",
  color: "#18181b",
  minWidth: 220,
};

const customizeCard: CSSProperties = {
  marginBottom: 28,
  padding: 20,
  borderRadius: 12,
  border: "1px solid #e4e4e7",
  background: "#fff",
  boxShadow: "0 1px 3px rgba(0,0,0,0.04)",
};

const fieldLabel: CSSProperties = {
  display: "flex",
  flexDirection: "column",
  gap: 6,
  fontSize: "0.72rem",
  fontWeight: 600,
  color: "#52525b",
};

const textInput: CSSProperties = {
  padding: "8px 10px",
  borderRadius: 8,
  border: "1px solid #e4e4e7",
  fontSize: "0.82rem",
  fontFamily: "var(--font-ibm-plex-mono), monospace",
};

const selectStyleFull: CSSProperties = {
  padding: "8px 12px",
  borderRadius: 8,
  border: "1px solid #e4e4e7",
  fontSize: "0.82rem",
  background: "#fff",
  color: "#18181b",
  minWidth: "100%",
  marginTop: 4,
};

const btnPrimary: CSSProperties = {
  display: "inline-flex",
  alignItems: "center",
  gap: 8,
  padding: "10px 16px",
  borderRadius: 10,
  border: "none",
  background: "#18181b",
  color: "#fff",
  fontSize: "0.82rem",
  fontWeight: 500,
  cursor: "pointer",
};

const btnGhost: CSSProperties = {
  display: "inline-flex",
  alignItems: "center",
  gap: 8,
  padding: "10px 16px",
  borderRadius: 10,
  border: "1px solid #e4e4e7",
  background: "#fafafa",
  color: "#52525b",
  fontSize: "0.82rem",
  fontWeight: 500,
  cursor: "pointer",
};

const sectionTitle: CSSProperties = {
  margin: "0 0 12px",
  fontSize: "0.72rem",
  fontWeight: 700,
  letterSpacing: "0.08em",
  color: "#a1a1aa",
  textTransform: "uppercase",
};

const accordionOuter: CSSProperties = {
  borderRadius: 10,
  border: "1px solid #e4e4e7",
  background: "#fff",
  overflow: "hidden",
};

const accordionTrigger: CSSProperties = {
  width: "100%",
  display: "flex",
  alignItems: "flex-start",
  gap: 10,
  padding: "14px 16px",
  border: "none",
  background: "#fff",
  cursor: "pointer",
  boxSizing: "border-box",
};

const accordionBody: CSSProperties = {
  padding: "16px 16px 18px 44px",
  borderTop: "1px solid #f4f4f5",
  background: "#fafafa",
};
