import { useRef } from "react";
import { X } from "lucide-react";
import { useStore } from "../store";
import { MG_THEME_LIST, MG_ACCENTS } from "../remotion/mg/templates";
import { MG_BACKGROUNDS, MG_ANIMATIONS, MG_FONTS, MG_FONTS_AR } from "../remotion/mg/catalog.mjs";
import { AccentControls } from "./SceneInspector";

// Bulk styling for a multi-selection of scenes. Mirrors the SceneInspector look controls,
// but every control writes the chosen property onto ALL selected scenes at once (one undo step
// per change) via applyLook({ <prop>: value }, selectedIds).
export function BulkStylePanel() {
  const selectedIds = useStore((s) => s.selectedIds);
  const clearSelection = useStore((s) => s.clearSelection);
  const applyLook = useStore((s) => s.applyLook);
  const pushHistory = useStore((s) => s.pushHistory);
  const updateMotion = useStore((s) => s.updateMotion);
  const motion = useStore((s) => s.motion); // stable ref; filter in render (a selector that .filter()s returns a NEW array each call → infinite re-render loop)
  const lang = useStore((s) => s.lang);
  // only template scenes are styleable; keep store order
  const scenes = motion.filter((m) => m.template && selectedIds.includes(m.id));
  const n = scenes.length;
  // live color drag → snapshot once on pointerdown, then live-write to every selected scene (no per-event history)
  const armed = useRef(false);
  const accentArm = () => { armed.current = true; };
  const accentLive = (c: string) => { if (armed.current) { pushHistory(); armed.current = false; } for (const m of scenes) updateMotion(m.id, { accent: c }); };

  // a property is "active" only when every selected scene shares the same value (else: mixed)
  const shared = (get: (m: (typeof scenes)[number]) => string | undefined, dflt: string): string | null => {
    if (!n) return dflt;
    const first = get(scenes[0]) || dflt;
    return scenes.every((m) => (get(m) || dflt) === first) ? first : null;
  };
  const theme = shared((m) => m.theme, "dark");
  const accent = shared((m) => m.accent, MG_ACCENTS[0]);
  const bg = shared((m) => m.bg, "mesh");
  const anim = shared((m) => m.anim, "rise");
  const font = shared((m) => m.font, "editorial");

  const set = (patch: Record<string, string>) => applyLook(patch, selectedIds);

  const eq = (a: string | null, b: string) => a != null && a.toLowerCase() === b.toLowerCase();

  return (
    <div className="flex h-full flex-col">
      <div className="flex items-center gap-2 border-b border-border px-3 py-2">
        <span className="eyebrow !text-fg">Styling {n} scene{n === 1 ? "" : "s"}</span>
        <span className="rounded bg-[var(--color-tl-motion)] px-1.5 py-0.5 text-[10px] font-medium text-white">Bulk</span>
        <div className="flex-1" />
        <button onClick={clearSelection} title="Clear selection" className="flex items-center gap-1 rounded px-1.5 py-0.5 text-[11px] text-fg-muted hover:bg-white/5 hover:text-fg"><X size={12} /> Clear</button>
      </div>

      <div className="min-h-0 flex-1 space-y-4 overflow-y-auto p-3">
        <div className="text-[11px] text-fg-subtle">Changes apply to all {n} selected scenes.</div>

        {/* theme */}
        <div>
          <div className="eyebrow mb-1.5">Theme</div>
          <div className="flex flex-wrap gap-1.5">
            {MG_THEME_LIST.map((t) => (
              <button key={t.id} onClick={() => set({ theme: t.id })} title={t.label}
                className={"h-8 w-8 rounded-md border-2 " + (theme === t.id ? "border-primary" : "border-transparent")}
                style={{ background: t.swatch }} />
            ))}
          </div>
        </div>

        {/* accent — presets + custom color, identical to the inspector */}
        <div>
          <div className="eyebrow mb-1.5">Accent {accent == null && <span className="ml-1 text-fg-subtle">· mixed</span>}</div>
          <AccentControls accent={accent || ""} onPick={(c) => set({ accent: c })} onArm={accentArm} onLive={accentLive} />
        </div>

        {/* background */}
        <div>
          <div className="eyebrow mb-1.5">Background</div>
          <div className="grid grid-cols-6 gap-1.5">
            {MG_BACKGROUNDS.map((bgo) => (
              <button key={bgo.id} onClick={() => set({ bg: bgo.id })} title={`${bgo.label} — ${bgo.blurb}`}
                className={"aspect-square overflow-hidden rounded-md border-2 " + (bg === bgo.id ? "border-primary" : "border-border/60 hover:border-primary/50")}
                style={{ background: bgo.swatch }} />
            ))}
          </div>
        </div>

        {/* animation */}
        <div>
          <div className="eyebrow mb-1.5">Animation</div>
          <div className="flex flex-wrap gap-1.5">
            {MG_ANIMATIONS.map((a) => (
              <button key={a.id} onClick={() => set({ anim: a.id })} title={a.blurb}
                className={"rounded-md border px-2 py-1 text-[11px] " + (anim === a.id ? "border-primary bg-primary/10 text-fg" : "border-border text-fg-muted hover:border-primary/50")}>{a.label}</button>
            ))}
          </div>
        </div>

        {/* font */}
        {(() => {
          const ar = lang === "ar";
          const fonts = ar ? MG_FONTS_AR : MG_FONTS;
          return (
            <div>
              <div className="eyebrow mb-1.5 flex items-center gap-1.5">Font{ar && <span className="rounded bg-primary/15 px-1.5 py-px text-[9px] font-semibold text-primary">عربي</span>}</div>
              <div className="grid grid-cols-3 gap-1.5">
                {fonts.map((f) => (
                  <button key={f.id} onClick={() => set({ font: f.id })} title={f.blurb}
                    className={"rounded-md border px-2 py-1.5 text-left " + (eq(font, f.id) ? "border-primary bg-primary/10" : "border-border hover:border-primary/50")}>
                    <div className="truncate text-[18px] leading-none text-fg" style={{ fontFamily: f.preview, direction: ar ? "rtl" : undefined }}>{ar ? "أبجد" : "Ag"}</div>
                    <div className="mt-1 truncate text-[10px] text-fg-subtle">{f.label}</div>
                  </button>
                ))}
              </div>
            </div>
          );
        })()}
      </div>
    </div>
  );
}
