'use client';

import { useState } from 'react';
import { Plus, Trash2, Pencil, Loader2 } from 'lucide-react';

interface T {
  id: string;
  name: string;
  description: string | null;
  systemPrompt: string;
  userPromptTemplate: string;
  isBuiltIn: boolean;
  isMine: boolean;
}

export default function TemplatesList({
  initialTemplates,
  isAdmin,
}: {
  initialTemplates: T[];
  isAdmin: boolean;
}) {
  const [templates, setTemplates] = useState(initialTemplates);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [creating, setCreating] = useState(false);

  const refresh = async () => {
    const r = await fetch('/api/ai/templates');
    if (r.ok) {
      const list = (await r.json()) as Array<T & { userId: string | null }>;
      // Mark isMine on the client by checking who owns each.
      // The API already returns built-ins + this user's own — we
      // can distinguish them by isBuiltIn flag.
      setTemplates(
        list.map((t) => ({
          ...t,
          isMine: !t.isBuiltIn,
        })),
      );
    }
  };

  return (
    <div className="space-y-4">
      <div className="flex justify-end">
        <button
          type="button"
          onClick={() => setCreating(true)}
          className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded bg-white text-black font-bold text-xs uppercase tracking-wider hover:bg-gray-100"
        >
          <Plus className="w-3.5 h-3.5" />
          New template
        </button>
      </div>

      {creating && (
        <TemplateEditor
          mode="create"
          onClose={() => setCreating(false)}
          onSaved={() => {
            setCreating(false);
            refresh();
          }}
        />
      )}

      <ul className="space-y-3">
        {templates.map((t) => {
          const editable = t.isMine || (t.isBuiltIn && isAdmin);
          if (editingId === t.id) {
            return (
              <li key={t.id}>
                <TemplateEditor
                  mode="edit"
                  template={t}
                  onClose={() => setEditingId(null)}
                  onSaved={() => {
                    setEditingId(null);
                    refresh();
                  }}
                />
              </li>
            );
          }
          return (
            <li
              key={t.id}
              className="bg-zinc-900 border border-zinc-800 rounded p-4"
            >
              <div className="flex items-start justify-between gap-3">
                <div className="min-w-0">
                  <h3 className="text-base font-semibold text-white">
                    {t.name}
                    {t.isBuiltIn && (
                      <span className="ml-2 text-[10px] uppercase tracking-wider bg-zinc-800 text-zinc-300 px-1.5 py-0.5 rounded font-normal">
                        built-in
                      </span>
                    )}
                  </h3>
                  {t.description && (
                    <p className="text-xs text-zinc-500 mt-1">
                      {t.description}
                    </p>
                  )}
                </div>
                <div className="flex items-center gap-1">
                  {editable && (
                    <button
                      type="button"
                      onClick={() => setEditingId(t.id)}
                      className="p-1.5 text-zinc-400 hover:text-white"
                      title="Edit"
                    >
                      <Pencil className="w-3.5 h-3.5" />
                    </button>
                  )}
                  {editable && (
                    <DeleteButton
                      templateId={t.id}
                      isBuiltIn={t.isBuiltIn}
                      onDeleted={() => refresh()}
                    />
                  )}
                </div>
              </div>
              <details className="mt-2">
                <summary className="cursor-pointer text-[11px] text-zinc-500 uppercase tracking-wider">
                  Show prompt
                </summary>
                <div className="mt-2 space-y-2 text-xs">
                  <div>
                    <p className="text-zinc-500 uppercase tracking-wider mb-1">
                      System
                    </p>
                    <pre className="bg-zinc-950 border border-zinc-800 rounded p-2 whitespace-pre-wrap text-zinc-300">
                      {t.systemPrompt}
                    </pre>
                  </div>
                  <div>
                    <p className="text-zinc-500 uppercase tracking-wider mb-1">
                      User template
                    </p>
                    <pre className="bg-zinc-950 border border-zinc-800 rounded p-2 whitespace-pre-wrap text-zinc-300">
                      {t.userPromptTemplate}
                    </pre>
                  </div>
                </div>
              </details>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

function DeleteButton({
  templateId,
  isBuiltIn,
  onDeleted,
}: {
  templateId: string;
  isBuiltIn: boolean;
  onDeleted: () => void;
}) {
  const [busy, setBusy] = useState(false);
  return (
    <button
      type="button"
      disabled={busy}
      onClick={async () => {
        if (
          !confirm(
            isBuiltIn
              ? 'Delete this built-in template? It will be re-created from the package JSON on next boot unless you also remove it from prisma/aiTemplates.seed.json.'
              : 'Delete this template?',
          )
        )
          return;
        setBusy(true);
        const r = await fetch(`/api/ai/templates/${templateId}`, {
          method: 'DELETE',
        });
        setBusy(false);
        if (r.ok) onDeleted();
        else {
          const b = await r.json().catch(() => ({}));
          alert(b.error ?? `HTTP ${r.status}`);
        }
      }}
      className="p-1.5 text-red-400 hover:text-red-300"
      title="Delete"
    >
      {busy ? (
        <Loader2 className="w-3.5 h-3.5 animate-spin" />
      ) : (
        <Trash2 className="w-3.5 h-3.5" />
      )}
    </button>
  );
}

function TemplateEditor({
  mode,
  template,
  onClose,
  onSaved,
}: {
  mode: 'create' | 'edit';
  template?: T;
  onClose: () => void;
  onSaved: () => void;
}) {
  const [name, setName] = useState(template?.name ?? '');
  const [description, setDescription] = useState(template?.description ?? '');
  const [systemPrompt, setSystemPrompt] = useState(template?.systemPrompt ?? '');
  const [userPromptTemplate, setUserPromptTemplate] = useState(
    template?.userPromptTemplate ?? '{{userInput}}',
  );
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleSave = async () => {
    if (!name.trim() || !systemPrompt.trim() || !userPromptTemplate.trim()) {
      setError('Name, system prompt, and user prompt template are required.');
      return;
    }
    setBusy(true);
    setError(null);
    try {
      const body = {
        name,
        description: description || null,
        systemPrompt,
        userPromptTemplate,
      };
      const url =
        mode === 'create'
          ? '/api/ai/templates'
          : `/api/ai/templates/${template!.id}`;
      const method = mode === 'create' ? 'POST' : 'PATCH';
      const r = await fetch(url, {
        method,
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(body),
      });
      if (!r.ok) {
        const b = await r.json().catch(() => ({}));
        throw new Error(b.error ?? `HTTP ${r.status}`);
      }
      onSaved();
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="bg-zinc-900 border border-emerald-900 rounded p-4 space-y-3">
      <h3 className="text-sm font-semibold text-white uppercase tracking-wider">
        {mode === 'create' ? 'New template' : `Edit: ${template!.name}`}
      </h3>
      <Field label="Name">
        <input
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="My hypertrophy block"
          className={inputClass}
        />
      </Field>
      <Field label="Description (optional)">
        <input
          value={description}
          onChange={(e) => setDescription(e.target.value)}
          placeholder="What this template is for"
          className={inputClass}
        />
      </Field>
      <Field label="System prompt (the role / constraints sent to the model)">
        <textarea
          value={systemPrompt}
          onChange={(e) => setSystemPrompt(e.target.value)}
          rows={6}
          className={inputClass}
        />
      </Field>
      <Field label="User prompt template (use {{userInput}} for the user's specifics)">
        <textarea
          value={userPromptTemplate}
          onChange={(e) => setUserPromptTemplate(e.target.value)}
          rows={3}
          className={inputClass}
        />
      </Field>
      {error && (
        <div className="rounded bg-red-900/50 px-3 py-2 border border-red-800 text-xs text-red-400">
          {error}
        </div>
      )}
      <div className="flex gap-2">
        <button
          type="button"
          onClick={handleSave}
          disabled={busy}
          className="px-4 py-2 rounded bg-white text-black font-bold text-xs uppercase tracking-wider hover:bg-gray-100 disabled:bg-zinc-700"
        >
          {busy ? (
            <>
              <Loader2 className="inline w-3.5 h-3.5 animate-spin mr-1" />
              Saving...
            </>
          ) : (
            'Save'
          )}
        </button>
        <button
          type="button"
          onClick={onClose}
          disabled={busy}
          className="px-4 py-2 rounded border border-zinc-700 text-zinc-300 hover:bg-zinc-800 text-xs uppercase tracking-wider disabled:opacity-50"
        >
          Cancel
        </button>
      </div>
    </div>
  );
}

const inputClass =
  'w-full px-3 py-2 text-sm rounded border border-zinc-700 bg-zinc-800 text-white placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-white/30';

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <label className="block">
      <span className="text-[11px] font-semibold text-zinc-400 uppercase tracking-wider block mb-1">
        {label}
      </span>
      {children}
    </label>
  );
}
