"use client";

import { useState } from "react";
import { Button, Card, PageHeader } from "@/components/ui";
import { Modal } from "@/components/features/library/modal";
import { Field, inputClass } from "@/components/ui/form";
import { StatusLine, useRun } from "@/components/features/accounts/use-run";
import { assignThemeAction, createThemeAction, deleteThemeAction, updateThemeAction } from "@/lib/actions/themes";
import { slugifyThemeKey } from "@/lib/themes/schema";
import type { ThemeRow, ThemeSite } from "@/lib/services/themes";

function SitePicker({ id, sites, value, onChange }: { id: string; sites: ThemeSite[]; value: string[]; onChange: (v: string[]) => void }) {
  if (sites.length === 0) return <p className="text-sm text-muted-foreground">No websites yet.</p>;
  return (
    <fieldset>
      <legend className="mb-1 text-xs font-medium">Websites using this theme</legend>
      <ul className="max-h-56 space-y-1 overflow-auto rounded-md border border-border p-2">
        {sites.map((s) => (
          <li key={s.id}>
            <label htmlFor={`${id}-${s.id}`} className="flex items-center gap-2 text-sm">
              <input id={`${id}-${s.id}`} type="checkbox" checked={value.includes(s.id)} onChange={(e) => onChange(e.target.checked ? [...value, s.id] : value.filter((x) => x !== s.id))} />
              {s.name}<span className="text-xs text-muted-foreground">· {s.organization}</span>
              {s.themeKey && !value.includes(s.id) ? <span className="text-xs text-muted-foreground">(currently {s.themeKey})</span> : null}
            </label>
          </li>
        ))}
      </ul>
    </fieldset>
  );
}

function Swatches({ t }: { t: Pick<ThemeRow, "primary" | "background" | "text"> }) {
  return (
    <span className="inline-flex overflow-hidden rounded-full border border-border" aria-hidden="true">
      {[t.primary, t.background, t.text].map((c, i) => <span key={i} className="h-5 w-5" style={{ background: c }} />)}
    </span>
  );
}

function EditThemeDialog({ theme, sites, onClose }: { theme: ThemeRow; sites: ThemeSite[]; onClose: () => void }) {
  const [e, setE] = useState({ name: theme.name, description: theme.description, primary: theme.primary, background: theme.background, text: theme.text, css: theme.css });
  const [ids, setIds] = useState<string[]>(theme.siteIds);
  const { pending, msg, errors, run } = useRun();
  const setField = (p: Partial<typeof e>) => setE((x) => ({ ...x, ...p }));
  const same = ids.slice().sort().join() === theme.siteIds.slice().sort().join();
  const k = theme.key;
  return (
    <Modal open onClose={onClose} title={`Edit ${theme.name}`}>
      <form className="space-y-3" onSubmit={(ev) => { ev.preventDefault(); run(async () => { const r = await updateThemeAction(k, e); if (!r.ok || same) return r; return assignThemeAction(k, ids); }, onClose); }}>
        <p className="text-xs text-muted-foreground">Folder <code>src/themes/{k}</code> (cannot be renamed).</p>
        <div className="grid gap-3 md:grid-cols-2">
          <Field id={`e-name-${k}`} label="Theme name" error={errors.name}><input id={`e-name-${k}`} value={e.name} maxLength={60} className={inputClass} onChange={(x) => setField({ name: x.target.value })} /></Field>
          <Field id={`e-desc-${k}`} label="Description" error={errors.description}><input id={`e-desc-${k}`} value={e.description} maxLength={200} className={inputClass} onChange={(x) => setField({ description: x.target.value })} /></Field>
        </div>
        <div className="grid gap-3 sm:grid-cols-3">
          {(["primary", "background", "text"] as const).map((c) => (
            <Field key={c} id={`e-${c}-${k}`} label={`Default ${c} colour`} error={errors[c]}>
              <input id={`e-${c}-${k}`} type="color" value={e[c]} className="h-10 w-full cursor-pointer rounded-md border border-border bg-card" onChange={(x) => setField({ [c]: x.target.value })} />
            </Field>
          ))}
        </div>
        <Field id={`e-css-${k}`} label="Extra CSS (theme.css)" help="Loaded on every website that uses this theme." error={errors.css}>
          <textarea id={`e-css-${k}`} rows={6} value={e.css} className={`${inputClass} font-mono`} onChange={(x) => setField({ css: x.target.value })} />
        </Field>
        <SitePicker id={`t-${k}`} sites={sites} value={ids} onChange={setIds} />
        <div className="flex items-center justify-end gap-3"><StatusLine msg={msg} /><Button variant="ghost" onClick={onClose}>Cancel</Button><Button type="submit" disabled={pending}>{pending ? "Saving…" : "Save theme"}</Button></div>
      </form>
    </Modal>
  );
}

const blank = { name: "", key: "", description: "" };

function AddThemeDialog({ sites, onClose }: { sites: ThemeSite[]; onClose: () => void }) {
  const [f, setF] = useState(blank);
  const [keyTouched, setKeyTouched] = useState(false);
  const [ids, setIds] = useState<string[]>([]);
  const { pending, msg, errors, run } = useRun();
  const set = (p: Partial<typeof blank>) => setF((x) => ({ ...x, ...p }));
  return (
    <Modal open onClose={onClose} title="Add new theme">
      <form className="space-y-4" onSubmit={(e) => { e.preventDefault(); run(() => createThemeAction(f, ids), onClose); }}>
        <p className="text-xs text-muted-foreground">Creates a new folder <code>src/themes/&lt;folder&gt;</code> in the codebase with <code>theme.json</code>, <code>theme.css</code> and a README. A website that uses this theme keeps its own Site Settings, with the theme&apos;s CSS on top.</p>
        <div className="grid gap-4 md:grid-cols-2">
          <Field id="th-name" label="Theme name" error={errors.name}><input id="th-name" value={f.name} maxLength={60} className={inputClass} onChange={(e) => set({ name: e.target.value, ...(keyTouched ? {} : { key: slugifyThemeKey(e.target.value) }) })} placeholder="e.g. Summer Expo" /></Field>
          <Field id="th-key" label="Folder name" error={errors.key}><input id="th-key" value={f.key} maxLength={40} className={`${inputClass} font-mono`} onChange={(e) => { setKeyTouched(true); set({ key: e.target.value }); }} /></Field>
        </div>
        <Field id="th-desc" label="Description (optional)" error={errors.description}><input id="th-desc" value={f.description} maxLength={200} className={inputClass} onChange={(e) => set({ description: e.target.value })} /></Field>
        <SitePicker id="th-new" sites={sites} value={ids} onChange={setIds} />
        <div className="flex items-center justify-end gap-3"><StatusLine msg={msg} /><Button variant="ghost" onClick={onClose}>Cancel</Button><Button type="submit" disabled={pending || f.name.trim().length < 2 || !f.key}>{pending ? "Creating…" : "Create theme"}</Button></div>
      </form>
    </Modal>
  );
}

/** Themes list (name, number of websites, Edit, Delete) with an Add new theme button. */
export function ThemesManager({ themes, sites }: { themes: ThemeRow[]; sites: ThemeSite[] }) {
  const [adding, setAdding] = useState(false);
  const [editing, setEditing] = useState<string | null>(null);
  const [armed, setArmed] = useState<string | null>(null);
  const { pending, msg, run } = useRun();
  const editTheme = themes.find((t) => t.key === editing);
  return (
    <>
      <PageHeader title="Themes" description="Each theme is a folder in the codebase (src/themes). Add a new one, edit it, and choose which websites use it." actions={<Button onClick={() => setAdding(true)}>Add new theme</Button>} />
      <div className="mb-3"><StatusLine msg={msg} /></div>
      <Card>
        <table className="w-full text-left text-sm">
          <thead className="border-b border-border text-xs text-muted-foreground"><tr><th scope="col" className="px-4 py-2 font-medium">Theme</th><th scope="col" className="px-4 py-2 font-medium">Websites</th><th scope="col" className="px-4 py-2"><span className="sr-only">Actions</span></th></tr></thead>
          <tbody className="divide-y divide-border">
            {themes.map((t) => (
              <tr key={t.key}>
                <td className="px-4 py-3"><span className="flex items-center gap-2"><Swatches t={t} /><span className="font-medium">{t.name}</span></span></td>
                <td className="px-4 py-3">{t.siteIds.length}</td>
                <td className="space-x-2 px-4 py-3 text-right">
                  <Button variant="secondary" onClick={() => setEditing(t.key)} aria-label={`Edit ${t.name}`}>Edit</Button>
                  {armed === t.key ? (
                    <>
                      <Button variant="danger" disabled={pending} onClick={() => run(() => deleteThemeAction(t.key), () => setArmed(null))}>Confirm delete</Button>
                      <Button variant="ghost" onClick={() => setArmed(null)}>Cancel</Button>
                    </>
                  ) : <Button variant="secondary" onClick={() => setArmed(t.key)} aria-label={`Delete ${t.name}`}>Delete</Button>}
                </td>
              </tr>
            ))}
            {themes.length === 0 ? <tr><td colSpan={3} className="px-4 py-8 text-center text-muted-foreground">No themes yet. Add the first one.</td></tr> : null}
          </tbody>
        </table>
      </Card>
      {adding ? <AddThemeDialog sites={sites} onClose={() => setAdding(false)} /> : null}
      {editTheme ? <EditThemeDialog key={`${editTheme.key}:${editTheme.siteIds.join()}`} theme={editTheme} sites={sites} onClose={() => setEditing(null)} /> : null}
    </>
  );
}
