'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import type { PaginationState } from '@tanstack/react-table';
import { api } from '@/lib/api';
import { useAuth } from '@/components/auth-context';
import { useRequirePermission } from '@/lib/useRequirePermission';
import { DataTable } from '@/components/data-table/DataTable';
import {
  FILTER_LABEL_TEXT,
  FILTER_PANEL,
  CLEAR_FILTERS_BTN,
} from '@/components/data-table/DataTableToolbar';
import { toast } from 'react-toastify';
import { showConfirmDelete } from '@/lib/confirm';

/** One agent as returned by Hunar (via /ai-calls/agents/). All read-only here
 *  except the writable fields collected in the form below. */
interface VoiceAgent {
  id: string;
  name: string;
  voice_persona: string;
  persona_name?: string;
  voice_name?: string;
  summary?: string;
  status?: string;
  logo?: string | null;
  language: string;
  custom_variables?: string[];
  result_schema?: Record<string, unknown>;
  agent_code?: string;
  result_variables?: string[];
  required_variables?: string[];
  // detail-only
  created_at?: string;
  agent_prompt?: string;
  introduction?: string;
  objective?: string;
  silence_response?: string;
  conclusion?: string;
  result_prompt?: string;
}

/** The nine fields Hunar accepts on create/update. */
interface AgentForm {
  name: string;
  language: string;
  voice_persona: string;
  persona_name: string;
  objective: string;
  introduction: string;
  agent_prompt: string;
  result_prompt: string;
  result_schema: string;   // raw JSON text in the textarea
  status: string;          // DRAFT | ACTIVE | INACTIVE
}

const EMPTY_FORM: AgentForm = {
  name: '', language: 'ENGLISH', voice_persona: 'NEHA', persona_name: '',
  objective: '', introduction: '', agent_prompt: '', result_prompt: '',
  result_schema: '{\n  "interest_status": ""\n}',
  status: 'DRAFT',
};

/** Fallbacks only — the authoritative lists come from /ai-calls/agents/options/. */
const FALLBACK_LANGUAGES = [
  'ENGLISH', 'HINDI', 'TAMIL', 'TELUGU', 'KANNADA', 'MARATHI', 'MALAYALAM',
  'GUJARATI', 'BENGALI', 'TURKISH', 'ARABIC', 'SPANISH',
];
const FALLBACK_PERSONAS = ['NEHA', 'ROY', 'ZOE', 'SAM', 'MIRA', 'EESHA'];
const FALLBACK_STATUSES = ['DRAFT', 'ACTIVE', 'INACTIVE'];

const SELECT_CLS =
  'mt-1 text-xs px-2 py-1.5 border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 text-slate-800 dark:text-white focus:outline-none focus:border-indigo-500 normal-case tracking-normal font-semibold cursor-pointer';

const INPUT_CLS =
  'w-full px-3 py-2.5 text-sm border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-slate-800 dark:text-white focus:outline-none focus:border-[#405189]';

const FIELD_LABEL = 'block text-xs font-bold uppercase tracking-wide text-slate-500 mb-1';

const required = (label: string) => (
  <span className="inline-flex items-center gap-1"><span>{label}</span><span className="text-red-500">*</span></span>
);

/** Status badge, matching the Draft/Active/Inactive treatment used throughout the app. */
function StatusBadge({ status }: { status?: string }) {
  const s = (status || '').toUpperCase();
  const meta: Record<string, { label: string; cls: string }> = {
    ACTIVE: { label: 'Active', cls: 'bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-900/40' },
    DRAFT: { label: 'Draft', cls: 'bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-950/40 dark:text-amber-300 dark:border-amber-900/40' },
    INACTIVE: { label: 'Inactive', cls: 'bg-rose-50 text-rose-700 border-rose-200 dark:bg-rose-950/40 dark:text-rose-300 dark:border-rose-900/40' },
  };
  const m = meta[s] || { label: s || '—', cls: 'bg-slate-100 text-slate-600 border-slate-200 dark:bg-slate-800 dark:text-slate-300' };
  return (
    <span className={`text-[10px] px-2 py-0.5 rounded-full font-bold border ${m.cls}`}>
      {m.label}
    </span>
  );
}

export default function VoiceAgentsPage() {
  useRequirePermission('ai_calls.view_voiceagent');
  const { user } = useAuth();

  const isAdmin = user?.role === 'ADMIN';
  const canCreate = isAdmin || (user?.permissions?.includes('ai_calls.add_voiceagent') ?? false);
  const canEdit = isAdmin || (user?.permissions?.includes('ai_calls.change_voiceagent') ?? false);

  const [rows, setRows] = useState<VoiceAgent[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 20 });

  // Filters — exactly the query params the Hunar Agents API accepts.
  const [languageFilter, setLanguageFilter] = useState('ALL');
  const [personaFilter, setPersonaFilter] = useState('ALL');
  const [statusFilter, setStatusFilter] = useState('ALL');

  const [options, setOptions] = useState<{ languages: string[]; voice_personas: string[]; statuses: string[] }>({
    languages: FALLBACK_LANGUAGES, voice_personas: FALLBACK_PERSONAS, statuses: FALLBACK_STATUSES,
  });

  // Detail viewer + create/edit form
  const [viewing, setViewing] = useState<VoiceAgent | null>(null);
  const [formOpen, setFormOpen] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [form, setForm] = useState<AgentForm>(EMPTY_FORM);
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});
  const [submitting, setSubmitting] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  /** The agent being edited, as Hunar currently has it — used to detect a real
   *  persona/language change (which requires sending all nine fields). */
  const [original, setOriginal] = useState<VoiceAgent | null>(null);

  const activeFilterCount =
    (languageFilter !== 'ALL' ? 1 : 0) + (personaFilter !== 'ALL' ? 1 : 0) + (statusFilter !== 'ALL' ? 1 : 0);

  useEffect(() => {
    (async () => {
      try {
        const res = (await api.get('/ai-calls/agents/options/')) as any;
        if (res?.data) setOptions(res.data);
      } catch { /* fallbacks already in state */ }
    })();
  }, []);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const params = new URLSearchParams({
        page: String(pagination.pageIndex + 1),
        page_size: String(pagination.pageSize),
      });
      if (languageFilter !== 'ALL') params.set('language', languageFilter);
      if (personaFilter !== 'ALL') params.set('voice_persona', personaFilter);
      if (statusFilter !== 'ALL') params.set('status', statusFilter);

      const res = (await api.get(`/ai-calls/agents/?${params.toString()}`)) as any;
      const d = res?.data ?? {};
      setRows(Array.isArray(d.results) ? d.results : (Array.isArray(d) ? d : []));
      setTotal(typeof d.count === 'number' ? d.count : (Array.isArray(d) ? d.length : 0));
    } catch (err: any) {
      setRows([]); setTotal(0);
      toast.error(err?.data?.message || err?.message || 'Could not load voice agents.');
    } finally {
      setLoading(false);
    }
  }, [pagination, languageFilter, personaFilter, statusFilter]);

  useEffect(() => { load(); }, [load]);

  // Reset to page 1 whenever a filter changes.
  useEffect(() => {
    setPagination((p) => (p.pageIndex === 0 ? p : { ...p, pageIndex: 0 }));
  }, [languageFilter, personaFilter, statusFilter]);

  const clearFilters = () => { setLanguageFilter('ALL'); setPersonaFilter('ALL'); setStatusFilter('ALL'); };

  const openView = async (agent: VoiceAgent) => {
    setViewing(agent);
    setDetailLoading(true);
    try {
      const res = (await api.get(`/ai-calls/agents/${agent.id}/`)) as any;
      if (res?.data) setViewing(res.data);
    } catch (err: any) {
      toast.error(err?.data?.message || 'Could not load agent details.');
    } finally { setDetailLoading(false); }
  };

  const openCreate = () => {
    setEditingId(null); setOriginal(null); setForm(EMPTY_FORM);
    setFieldErrors({}); setFormOpen(true);
  };

  const openEdit = async (agent: VoiceAgent) => {
    setEditingId(agent.id); setFieldErrors({}); setFormOpen(true);
    setSubmitting(true);
    try {
      const res = (await api.get(`/ai-calls/agents/${agent.id}/`)) as any;
      const a: VoiceAgent = res?.data ?? agent;
      setOriginal(a);
      setForm({
        name: a.name || '',
        language: a.language || 'ENGLISH',
        voice_persona: a.voice_persona || 'NEHA',
        persona_name: a.persona_name || '',
        objective: a.objective || '',
        introduction: a.introduction || '',
        agent_prompt: a.agent_prompt || '',
        result_prompt: a.result_prompt || '',
        result_schema: JSON.stringify(a.result_schema ?? {}, null, 2),
        status: (a.status || 'DRAFT').toUpperCase(),
      });
    } catch (err: any) {
      toast.error(err?.data?.message || 'Could not load the agent for editing.');
      setFormOpen(false);
    } finally { setSubmitting(false); }
  };

  const handleDeleteAgent = async (agent: VoiceAgent) => {
    const res = await showConfirmDelete(
      'Are you sure you want to delete this Voice Agent? This action cannot be undone.'
    );
    if (!res.isConfirmed) return;

    try {
      await api.delete(`/ai-calls/agents/${agent.id}/`);
      toast.success('Voice agent deleted successfully.');
      await load();
    } catch (err: any) {
      toast.error(err?.data?.message || err?.message || 'Could not delete the voice agent.');
    }
  };

  const setField = (k: keyof AgentForm, v: string) => {
    setForm((f) => ({ ...f, [k]: v }));
    setFieldErrors((e) => { const { [k]: _drop, ...rest } = e; return rest; });
  };

  /** Client-side mirror of the documented rules, so the obvious mistakes never
   *  cost a round trip. The backend enforces the same rules authoritatively. */
  const validate = (): Record<string, string> => {
    const errs: Record<string, string> = {};
    const name = form.name.trim();
    if (name.length < 3 || name.length > 64) errs.name = 'Name must be 3–64 characters.';
    if (!form.language) errs.language = 'Language is required.';
    if (!form.voice_persona) errs.voice_persona = 'Voice persona is required.';
    for (const k of ['objective', 'introduction', 'agent_prompt', 'result_prompt'] as const) {
      if (!form[k].trim()) errs[k] = 'This field is required.';
    }
    let parsed: unknown = undefined;
    try {
      parsed = JSON.parse(form.result_schema || 'null');
    } catch {
      errs.result_schema = 'Result schema must be valid JSON.';
    }
    if (!errs.result_schema && (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))) {
      errs.result_schema = 'Result schema must be a JSON object, e.g. {"interest_status": ""}.';
    }
    // result_prompt + result_schema must be provided together.
    if (form.result_prompt.trim() && errs.result_schema) {
      errs.result_schema = errs.result_schema + ' It is required alongside Result Prompt.';
    }
    return errs;
  };

  /** True when the edit changes voice_persona or language — Hunar then requires
   *  all nine fields in the same request, so we always send the full set. */
  const personaOrLanguageChanged = useMemo(() => {
    if (!editingId || !original) return false;
    return (
      (form.voice_persona || '') !== (original.voice_persona || '')
      || (form.language || '') !== (original.language || '')
    );
  }, [editingId, original, form.voice_persona, form.language]);

  const save = async (ev: React.FormEvent) => {
    ev.preventDefault();
    const errs = validate();
    if (Object.keys(errs).length) {
      setFieldErrors(errs);
      toast.error('Please fix the highlighted fields.');
      return;
    }
    setSubmitting(true);
    setFieldErrors({});
    try {
      const payload: Record<string, unknown> = {
        name: form.name.trim(),
        language: form.language,
        voice_persona: form.voice_persona,
        objective: form.objective.trim(),
        introduction: form.introduction.trim(),
        agent_prompt: form.agent_prompt.trim(),
        result_prompt: form.result_prompt.trim(),
        result_schema: JSON.parse(form.result_schema),
        status: (form.status || 'DRAFT').toUpperCase(),
      };
      // persona_name is optional; Hunar requires it in the full set when the
      // persona or language changes, so fall back to the persona's own name.
      const personaName = form.persona_name.trim();
      if (personaName) payload.persona_name = personaName;
      else if (personaOrLanguageChanged) {
        payload.persona_name = form.voice_persona.charAt(0) + form.voice_persona.slice(1).toLowerCase();
      }

      if (editingId) await api.put(`/ai-calls/agents/${editingId}/`, payload);
      else await api.post('/ai-calls/agents/', payload);

      toast.success(`Voice agent ${editingId ? 'updated' : 'created'} successfully.`);
      setFormOpen(false);
      await load();
    } catch (err: any) {
      // Surface per-field errors from our serializer or from Hunar's `details`.
      const errors = err?.data?.errors;
      const mapped: Record<string, string> = {};
      if (errors && typeof errors === 'object') {
        for (const [k, v] of Object.entries(errors)) {
          if (k === 'details') continue;
          mapped[k] = Array.isArray(v) ? String(v[0]) : String(v);
        }
      }
      if (Object.keys(mapped).length) setFieldErrors(mapped);
      toast.error(err?.data?.message || err?.message || 'Could not save the voice agent.');
    } finally { setSubmitting(false); }
  };

  const columns = useMemo(() => [
    {
      accessorKey: 'name', header: 'Agent',
      cell: ({ row }: any) => (
        <button onClick={() => openView(row.original)} className="text-left cursor-pointer group">
          <p className="font-extrabold text-slate-800 dark:text-white text-sm group-hover:text-[#405189] dark:group-hover:text-indigo-400">
            {row.original.name}
          </p>
          {row.original.summary && (
            <p className="text-[11px] text-slate-400 truncate max-w-[260px]">{row.original.summary}</p>
          )}
        </button>
      ),
    },
    {
      accessorKey: 'agent_code', header: 'Agent Code',
      cell: ({ row }: any) => (
        <span className="text-xs font-mono text-slate-600 dark:text-slate-400">{row.original.agent_code || '—'}</span>
      ),
    },
    {
      accessorKey: 'voice_persona', header: 'Voice Persona',
      cell: ({ row }: any) => (
        <div>
          <p className="text-xs font-bold text-slate-700 dark:text-slate-200">{row.original.voice_persona || '—'}</p>
          {row.original.persona_name && (
            <p className="text-[10px] text-slate-400">as “{row.original.persona_name}”</p>
          )}
        </div>
      ),
    },
    {
      accessorKey: 'language', header: 'Language',
      cell: ({ row }: any) => <span className="text-xs text-slate-600 dark:text-slate-400">{row.original.language || '—'}</span>,
    },
    {
      accessorKey: 'status', header: 'Status',
      cell: ({ row }: any) => <StatusBadge status={row.original.status} />,
    },
    {
      id: 'result_variables', header: 'Result Vars',
      cell: ({ row }: any) => (
        <span className="text-xs text-slate-600 dark:text-slate-400">
          {Array.isArray(row.original.result_variables) ? row.original.result_variables.length : 0}
        </span>
      ),
    },
    {
      id: 'actions', header: () => <div className="text-right">Actions</div>,
      cell: ({ row }: any) => (
        <div className="flex items-center justify-end gap-2">
          <button onClick={() => openView(row.original)} title="View details"
            className="w-8 h-8 flex items-center justify-center border border-slate-200 dark:border-slate-700 text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
            <i className="fa-solid fa-eye text-xs" />
          </button>
          {canEdit && (
            <button onClick={() => openEdit(row.original)} title="Edit agent"
              className="w-8 h-8 flex items-center justify-center border border-slate-200 dark:border-slate-700 text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
              <i className="fa-solid fa-pen text-xs" />
            </button>
          )}
          {canEdit && (
            <button onClick={() => handleDeleteAgent(row.original)} title="Delete agent"
              className="w-8 h-8 flex items-center justify-center border border-rose-200 dark:border-rose-900/50 text-rose-600 dark:text-rose-400 hover:bg-rose-50 dark:hover:bg-rose-950/40 transition cursor-pointer">
              <i className="fa-solid fa-trash text-xs" />
            </button>
          )}
        </div>
      ),
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
  ], [canEdit]);

  const err = (k: string) => fieldErrors[k]
    ? <p className="text-[11px] text-rose-600 dark:text-rose-400 mt-1">{fieldErrors[k]}</p>
    : null;

  return (
    <>
      <main className="flex-1 p-8 overflow-y-auto w-full space-y-5">
        <div className="flex items-start justify-between gap-3 flex-wrap">
          <div>
            <h1 className="text-lg font-black text-slate-800 dark:text-white">Voice Agents</h1>
            <p className="text-sm text-slate-500 dark:text-slate-400 mt-0.5">
              AI voice agents used for outbound calling. Managed on the Hunar platform — this
              page reads and writes them live.
            </p>
          </div>
          {canCreate && (
            <button onClick={openCreate}
              className="px-4 py-2 bg-[#405189] text-white font-bold text-sm hover:bg-[#334267] transition cursor-pointer">
              <i className="fa-solid fa-plus mr-2" />Create Agent
            </button>
          )}
        </div>

        {/* Filters — the three the Hunar Agents API supports. */}
        <div className={FILTER_PANEL}>
          <div className="flex flex-wrap items-end gap-3">
            <label className={`flex flex-col ${FILTER_LABEL_TEXT}`}>
              Language
              <select value={languageFilter} onChange={(e) => setLanguageFilter(e.target.value)} className={SELECT_CLS}>
                <option value="ALL">All Languages</option>
                {options.languages.map((l) => <option key={l} value={l}>{l}</option>)}
              </select>
            </label>
            <label className={`flex flex-col ${FILTER_LABEL_TEXT}`}>
              Voice Persona
              <select value={personaFilter} onChange={(e) => setPersonaFilter(e.target.value)} className={SELECT_CLS}>
                <option value="ALL">All Personas</option>
                {options.voice_personas.map((p) => <option key={p} value={p}>{p}</option>)}
              </select>
            </label>
            <label className={`flex flex-col ${FILTER_LABEL_TEXT}`}>
              Status
              <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)} className={SELECT_CLS}>
                <option value="ALL">All Statuses</option>
                {options.statuses.map((s) => <option key={s} value={s}>{s}</option>)}
              </select>
            </label>
            {activeFilterCount > 0 && (
              <button onClick={clearFilters} className={CLEAR_FILTERS_BTN}>
                <i className="fa-solid fa-xmark" /> Clear ({activeFilterCount})
              </button>
            )}
          </div>
        </div>

        <DataTable
          columns={columns as any}
          data={rows}
          loading={loading}
          compact
          searchPlaceholder="Search agents on this page..."
          emptyStateTitle="No voice agents"
          emptyStateDescription="No agents matched these filters. Create one to get started."
          pageCount={Math.max(1, Math.ceil(total / pagination.pageSize))}
          controlledPagination={pagination}
          onPaginationChange={setPagination}
        />
      </main>

      {/* ===== Detail viewer ===== */}
      {viewing && (
        <div className="fixed inset-0 z-[150] flex items-center justify-center p-4">
          <div className="fixed inset-0 bg-slate-950/40 dark:bg-slate-950/80 backdrop-blur-sm" onClick={() => setViewing(null)} />
          <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 w-full max-w-2xl relative z-10 shadow-2xl flex flex-col max-h-[90vh]">
            <div className="flex items-center justify-between px-6 pt-5 pb-4 border-b border-slate-100 dark:border-slate-800 shrink-0">
              <div className="flex items-center gap-3">
                <div className="w-10 h-10 bg-[#405189]/10 text-[#405189] dark:text-indigo-400 flex items-center justify-center">
                  <i className="fa-solid fa-microphone-lines" />
                </div>
                <div>
                  <h3 className="text-base font-bold text-slate-900 dark:text-white leading-tight">{viewing.name}</h3>
                  <p className="text-xs text-slate-400 mt-0.5">
                    {viewing.agent_code || '—'} · {viewing.language} · {viewing.voice_persona}
                  </p>
                </div>
                <StatusBadge status={viewing.status} />
              </div>
              <button onClick={() => setViewing(null)}
                className="w-8 h-8 flex items-center justify-center text-slate-400 hover:text-slate-700 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
                <i className="fa-solid fa-xmark" />
              </button>
            </div>

            <div className="px-6 py-4 overflow-y-auto custom-scrollbar flex-1 min-h-0 space-y-4">
              {detailLoading && (
                <p className="text-xs text-slate-400 flex items-center gap-2">
                  <i className="fa-solid fa-spinner fa-spin" /> Loading details…
                </p>
              )}

              <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
                {([
                  ['Persona Name', viewing.persona_name || '—'],
                  ['Voice Name', viewing.voice_name || '—'],
                  ['Created', viewing.created_at ? new Date(viewing.created_at).toLocaleString() : '—'],
                ] as [string, string][]).map(([k, v]) => (
                  <div key={k} className="border border-slate-200 dark:border-slate-800 p-3">
                    <p className="text-[9px] uppercase tracking-wider text-slate-400 font-bold">{k}</p>
                    <p className="text-sm font-bold text-slate-800 dark:text-white mt-1 break-words">{v}</p>
                  </div>
                ))}
              </div>

              {([
                ['Objective', viewing.objective],
                ['Introduction', viewing.introduction],
                ['Agent Prompt', viewing.agent_prompt],
                ['Result Prompt', viewing.result_prompt],
                ['Silence Response', viewing.silence_response],
                ['Conclusion', viewing.conclusion],
              ] as [string, string | undefined][]).map(([label, value]) => value ? (
                <div key={label}>
                  <p className="text-[10px] uppercase tracking-wider font-extrabold text-slate-400 mb-1">{label}</p>
                  <p className="text-xs text-slate-700 dark:text-slate-300 whitespace-pre-line border border-slate-200 dark:border-slate-800 p-3">{value}</p>
                </div>
              ) : null)}

              {([
                ['Custom Variables', viewing.custom_variables],
                ['Result Variables', viewing.result_variables],
                ['Required Variables', viewing.required_variables],
              ] as [string, string[] | undefined][]).map(([label, list]) => (list && list.length) ? (
                <div key={label}>
                  <p className="text-[10px] uppercase tracking-wider font-extrabold text-slate-400 mb-1.5">{label}</p>
                  <div className="flex flex-wrap gap-1.5">
                    {list.map((v) => (
                      <span key={v} className="text-[10px] font-mono font-bold bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 px-2 py-0.5">{v}</span>
                    ))}
                  </div>
                </div>
              ) : null)}

              {viewing.result_schema && (
                <div>
                  <p className="text-[10px] uppercase tracking-wider font-extrabold text-slate-400 mb-1">Result Schema</p>
                  <pre className="text-[11px] font-mono text-slate-600 dark:text-slate-300 bg-slate-50 dark:bg-slate-950/60 border border-slate-200 dark:border-slate-800 p-3 overflow-x-auto">
{JSON.stringify(viewing.result_schema, null, 2)}
                  </pre>
                </div>
              )}
            </div>

            <div className="flex justify-end gap-3 px-6 py-4 border-t border-slate-100 dark:border-slate-800 shrink-0">
              {canEdit && (
                <button onClick={() => { const a = viewing; setViewing(null); if (a) openEdit(a); }}
                  className="px-4 py-2 border border-slate-200 dark:border-slate-700 text-sm font-semibold text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800 transition cursor-pointer">
                  <i className="fa-solid fa-pen mr-1.5 text-xs" />Edit
                </button>
              )}
              <button onClick={() => setViewing(null)}
                className="bg-[#405189] hover:bg-[#334267] text-white text-sm font-semibold px-5 py-2.5 transition cursor-pointer">
                Close
              </button>
            </div>
          </div>
        </div>
      )}

      {/* ===== Create / Edit form ===== */}
      {formOpen && (
        <div className="fixed inset-0 z-[160] flex items-center justify-center p-4">
          <div className="fixed inset-0 bg-slate-950/40 dark:bg-slate-950/80 backdrop-blur-sm" onClick={() => !submitting && setFormOpen(false)} />
          <form onSubmit={save}
            className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 w-full max-w-2xl relative z-10 shadow-2xl flex flex-col max-h-[92vh]">
            <div className="flex items-center justify-between px-6 pt-5 pb-4 border-b border-slate-100 dark:border-slate-800 shrink-0">
              <div>
                <h3 className="text-base font-bold text-slate-900 dark:text-white leading-tight">
                  {editingId ? 'Edit Voice Agent' : 'Create Voice Agent'}
                </h3>
                <p className="text-xs text-slate-400 mt-0.5">
                  Use <code className="px-1 bg-slate-100 dark:bg-slate-800 text-[11px]">{'{persona_name}'}</code> in prompts
                  to insert the persona name at call time. Custom variables are filled from each call&apos;s data.
                </p>
              </div>
              <button type="button" onClick={() => setFormOpen(false)} disabled={submitting}
                className="w-8 h-8 flex items-center justify-center text-slate-400 hover:text-slate-700 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer disabled:opacity-50">
                <i className="fa-solid fa-xmark" />
              </button>
            </div>

            <div className="px-6 py-4 overflow-y-auto custom-scrollbar flex-1 min-h-0 space-y-4">
              {personaOrLanguageChanged && (
                <p className="text-xs text-amber-700 dark:text-amber-300 border border-amber-200 dark:border-amber-900/40 bg-amber-50/60 dark:bg-amber-950/20 p-3">
                  <i className="fa-solid fa-circle-info mr-1.5" />
                  You changed the voice persona or language. All agent fields will be submitted
                  together, as the Hunar API requires for this change.
                </p>
              )}

              <div>
                <label className={FIELD_LABEL}>{required('Agent Name')}</label>
                <input value={form.name} onChange={(e) => setField('name', e.target.value)}
                  placeholder="e.g. Packet Core L1 Screening Agent" className={INPUT_CLS} />
                {err('name')}
              </div>

              <div className="grid grid-cols-1 sm:grid-cols-4 gap-3">
                <div>
                  <label className={FIELD_LABEL}>{required('Language')}</label>
                  <select value={form.language} onChange={(e) => setField('language', e.target.value)} className={INPUT_CLS}>
                    {options.languages.map((l) => <option key={l} value={l}>{l}</option>)}
                  </select>
                  {err('language')}
                </div>
                <div>
                  <label className={FIELD_LABEL}>{required('Voice Persona')}</label>
                  <select value={form.voice_persona} onChange={(e) => setField('voice_persona', e.target.value)} className={INPUT_CLS}>
                    {options.voice_personas.map((p) => <option key={p} value={p}>{p}</option>)}
                  </select>
                  {err('voice_persona')}
                </div>
                <div>
                  <label className={FIELD_LABEL}>Persona Name</label>
                  <input value={form.persona_name} onChange={(e) => setField('persona_name', e.target.value)}
                    placeholder="Defaults to the persona" className={INPUT_CLS} />
                  {err('persona_name')}
                </div>
                <div>
                  <label className={FIELD_LABEL}>Status</label>
                  <select value={form.status} onChange={(e) => setField('status', e.target.value)} className={INPUT_CLS}>
                    <option value="DRAFT">Draft</option>
                    <option value="ACTIVE">Active</option>
                    <option value="INACTIVE">Inactive</option>
                  </select>
                  {err('status')}
                </div>
              </div>

              <div>
                <label className={FIELD_LABEL}>{required('Objective')}</label>
                <input value={form.objective} onChange={(e) => setField('objective', e.target.value)}
                  placeholder="The business objective guiding the agent's responses" className={INPUT_CLS} />
                {err('objective')}
              </div>

              <div>
                <label className={FIELD_LABEL}>{required('Introduction')}</label>
                <textarea value={form.introduction} onChange={(e) => setField('introduction', e.target.value)} rows={2}
                  placeholder="Hi! This is {persona_name} from …" className={`${INPUT_CLS} resize-y`} />
                {err('introduction')}
              </div>

              <div>
                <label className={FIELD_LABEL}>{required('Agent Prompt')}</label>
                <textarea value={form.agent_prompt} onChange={(e) => setField('agent_prompt', e.target.value)} rows={5}
                  placeholder="System prompt defining the agent's behaviour and conversation style" className={`${INPUT_CLS} resize-y`} />
                {err('agent_prompt')}
              </div>

              <div>
                <label className={FIELD_LABEL}>{required('Result Prompt')}</label>
                <textarea value={form.result_prompt} onChange={(e) => setField('result_prompt', e.target.value)} rows={2}
                  placeholder="Instructions for generating structured results from the conversation" className={`${INPUT_CLS} resize-y`} />
                {err('result_prompt')}
              </div>

              <div>
                <label className={FIELD_LABEL}>{required('Result Schema (JSON)')}</label>
                <textarea value={form.result_schema} onChange={(e) => setField('result_schema', e.target.value)} rows={6}
                  spellCheck={false} className={`${INPUT_CLS} font-mono text-xs resize-y`} />
                <p className="text-[11px] text-slate-400 mt-1">
                  A JSON object whose keys are the values to collect. Required together with Result Prompt.
                </p>
                {err('result_schema')}
              </div>

              {fieldErrors.detail && <p className="text-xs text-rose-600">{fieldErrors.detail}</p>}
            </div>

            <div className="flex justify-end gap-3 px-6 py-4 border-t border-slate-100 dark:border-slate-800 shrink-0">
              <button type="button" onClick={() => setFormOpen(false)} disabled={submitting}
                className="px-4 py-2 border border-slate-200 dark:border-slate-700 text-sm font-semibold text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800 transition cursor-pointer disabled:opacity-50">
                Cancel
              </button>
              <button type="submit" disabled={submitting}
                className="bg-[#405189] hover:bg-[#334267] disabled:opacity-50 text-white text-sm font-semibold px-6 py-2.5 transition cursor-pointer flex items-center gap-2">
                {submitting && <i className="fa-solid fa-spinner fa-spin text-xs" />}
                {submitting ? 'Saving…' : editingId ? 'Save Changes' : 'Create Agent'}
              </button>
            </div>
          </form>
        </div>
      )}
    </>
  );
}
