'use client';

import { useMemo, useState } from 'react';
import { Pencil, X, Search, Wrench } from 'lucide-react';
import EngineModelPicker from '../engine-model-picker.jsx';
import { ToolIcon, getToolIcon } from '@/app/components/ui/tool-icons';
import { humanizeSchedule } from './format-helpers';

type Engine = {
  id: string;
  label: string;
  available?: boolean;
  default_model?: string;
  models?: { name: string }[];
};

type ToolDef = {
  name: string;
  title: string;
  description: string;
  category: string;
  risk_level: string;
  available: boolean;
  missing_env: string[];
};

type ServerAction = (formData: FormData) => Promise<void>;

type EditorKey = 'publish' | 'model' | 'schedule' | 'tools';

export function AgentQuickControls({
  agentId,
  engine,
  model,
  engines,
  scheduleRaw,
  lastRun,
  statusLabel,
  statusTone,
  defaultSpaceId,
  spaces,
  agentTools,
  availableTools,
  toolCategories,
  updateModelAction,
  updateScheduleAction,
  updateToolsAction,
  updateDefaultSpaceAction,
}: {
  agentId: string;
  engine: string;
  model: string;
  engines: Engine[];
  scheduleRaw: string;
  lastRun: string | null;
  statusLabel: string;
  statusTone: string;
  defaultSpaceId: string | null;
  spaces: { id: string; name: string }[];
  agentTools: string[];
  availableTools: ToolDef[];
  toolCategories: string[];
  updateModelAction: ServerAction;
  updateScheduleAction: ServerAction;
  updateToolsAction: ServerAction;
  updateDefaultSpaceAction: ServerAction;
}) {
  const [open, setOpen] = useState<EditorKey | null>(null);
  const toggle = (key: EditorKey) => setOpen((cur) => (cur === key ? null : key));

  const engineLabel = engines.find((e) => e.id === engine)?.label || engine || '—';
  const modelValue = model ? model : 'default';
  const spaceValue = spaces.find((s) => s.id === defaultSpaceId)?.name || 'Active space (default)';

  return (
    <div className="ad-controls">
      {/* Glanceable facts. Publish, Model + Schedule are tap-to-edit;
          Last run + Status are read-only. */}
      <div className="ad-facts">
        <EditableFact
          label="Publish artifacts to"
          value={spaceValue}
          active={open === 'publish'}
          onClick={() => toggle('publish')}
        />

        <EditableFact
          label="Model"
          value={`${engineLabel} · ${modelValue}`}
          active={open === 'model'}
          onClick={() => toggle('model')}
        />

        <EditableFact
          label="Schedule"
          value={humanizeSchedule(scheduleRaw)}
          active={open === 'schedule'}
          onClick={() => toggle('schedule')}
        />

        <div className="ad-fact ad-fact--static">
          <span className="ad-fact-label">Last run</span>
          <span className="ad-fact-value">{lastRun || 'Never run yet'}</span>
        </div>

        <div className="ad-fact ad-fact--static">
          <span className="ad-fact-label">Status</span>
          <span className={`ad-fact-value ad-fact-status tone-${statusTone}`}>
            <span className="ad-dot" aria-hidden />
            {statusLabel}
          </span>
        </div>
      </div>

      {/* Tools — shown as icons, editable in one place. */}
      <div className="ad-tools-strip">
        <span className="ad-fact-label">Tools</span>
        <div className="ad-tools-icons">
          {toolCategories.length ? (
            toolCategories.slice(0, 10).map((category) => {
              const entry = getToolIcon(category);
              return (
                <span key={category} className="ad-tool-chip" title={entry?.label || category}>
                  <ToolIcon category={category} size={14} />
                </span>
              );
            })
          ) : (
            <span className="ad-tools-empty">No tools yet</span>
          )}
        </div>
        <button
          type="button"
          className={`admin-button secondary ad-edit-btn ${open === 'tools' ? 'on' : ''}`}
          onClick={() => toggle('tools')}
        >
          <Wrench size={13} />
          {agentTools.length ? 'Edit tools' : 'Add tools'}
        </button>
      </div>

      {/* Shared editor drawer — one open at a time. */}
      <div className="ad-drawer" data-open={open ? 'true' : 'false'}>
        <div className="ad-drawer-inner">
          {open === 'publish' ? (
            <EditorPanel title="Where artifacts are saved" onClose={() => setOpen(null)}>
              <form action={updateDefaultSpaceAction} className="ad-editor-form">
                <input type="hidden" name="agent_id" value={agentId} />
                <label className="ad-field">
                  <span>Publish artifacts to</span>
                  <select
                    name="default_space_id"
                    defaultValue={defaultSpaceId || ''}
                    className="admin-input"
                  >
                    <option value="">Active space (default)</option>
                    {spaces.map((s) => (
                      <option key={s.id} value={s.id}>{s.name}</option>
                    ))}
                  </select>
                </label>
                <div className="ad-editor-actions">
                  <button type="submit" className="admin-button">Save destination</button>
                  <button type="button" className="admin-button secondary" onClick={() => setOpen(null)}>Cancel</button>
                </div>
              </form>
            </EditorPanel>
          ) : null}

          {open === 'model' ? (
            <EditorPanel title="Choose the model" onClose={() => setOpen(null)}>
              <form action={updateModelAction} className="ad-editor-form">
                <input type="hidden" name="agent_id" value={agentId} />
                <div className="ad-editor-row">
                  <EngineModelPicker engines={engines} initialEngine={engine} initialModel={model || ''} />
                </div>
                <div className="ad-editor-actions">
                  <button type="submit" className="admin-button">Save model</button>
                  <button type="button" className="admin-button secondary" onClick={() => setOpen(null)}>Cancel</button>
                </div>
              </form>
            </EditorPanel>
          ) : null}

          {open === 'schedule' ? (
            <EditorPanel title="Set the schedule" onClose={() => setOpen(null)}>
              <ScheduleComposer
                agentId={agentId}
                initial={scheduleRaw}
                action={updateScheduleAction}
                onCancel={() => setOpen(null)}
              />
            </EditorPanel>
          ) : null}

          {open === 'tools' ? (
            <EditorPanel title="Pick this agent's tools" onClose={() => setOpen(null)}>
              <ToolsPicker
                agentId={agentId}
                selected={agentTools}
                tools={availableTools}
                action={updateToolsAction}
                onCancel={() => setOpen(null)}
              />
            </EditorPanel>
          ) : null}
        </div>
      </div>
    </div>
  );
}

function EditableFact({
  label,
  value,
  active,
  onClick,
}: {
  label: string;
  value: string;
  active: boolean;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      className={`ad-fact ad-fact--edit ${active ? 'is-active' : ''}`}
      onClick={onClick}
      aria-expanded={active}
    >
      <span className="ad-fact-label">{label}</span>
      <span className="ad-fact-value">{value}</span>
      <span className="ad-fact-edit" aria-hidden>
        <Pencil size={12} />
      </span>
    </button>
  );
}

function EditorPanel({
  title,
  onClose,
  children,
}: {
  title: string;
  onClose: () => void;
  children: React.ReactNode;
}) {
  return (
    <section className="ad-editor">
      <header className="ad-editor-head">
        <h3>{title}</h3>
        <button type="button" className="ad-editor-close" aria-label="Close" onClick={onClose}>
          <X size={14} />
        </button>
      </header>
      {children}
    </section>
  );
}

/* ---- Schedule composer ------------------------------------------------- */

type Freq = 'ondemand' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'advanced';

const WEEKDAYS = [
  ['mon', 'Monday'], ['tue', 'Tuesday'], ['wed', 'Wednesday'], ['thu', 'Thursday'],
  ['fri', 'Friday'], ['sat', 'Saturday'], ['sun', 'Sunday'],
] as const;

function parseSchedule(raw: string): {
  freq: Freq; time: string; day: string; dom: string; everyN: number; advanced: string;
} {
  const s = String(raw || '').trim().toLowerCase();
  const base = { freq: 'ondemand' as Freq, time: '09:00', day: 'mon', dom: '1', everyN: 1, advanced: s };
  if (!s || ['on demand', 'manual', 'event based', 'live'].includes(s)) return base;
  let m;
  if ((m = s.match(/^every\s+(\d+)\s*h$/))) return { ...base, freq: 'hourly', everyN: Number(m[1]) };
  if ((m = s.match(/^daily\s+(\d{1,2}):(\d{2})$/))) return { ...base, freq: 'daily', time: `${m[1].padStart(2, '0')}:${m[2]}` };
  if ((m = s.match(/^weekly\s+(\w+)\s+(\d{1,2}):(\d{2})$/))) return { ...base, freq: 'weekly', day: m[1].slice(0, 3), time: `${m[2].padStart(2, '0')}:${m[3]}` };
  if ((m = s.match(/^monthly\s+(last|\d{1,2})\s+(\d{1,2}):(\d{2})$/))) return { ...base, freq: 'monthly', dom: m[1], time: `${m[2].padStart(2, '0')}:${m[3]}` };
  return { ...base, freq: 'advanced', advanced: s };
}

function composeSchedule(state: {
  freq: Freq; time: string; day: string; dom: string; everyN: number; advanced: string;
}): string {
  switch (state.freq) {
    case 'ondemand': return 'on demand';
    case 'hourly': return `every ${Math.max(1, state.everyN)}h`;
    case 'daily': return `daily ${state.time}`;
    case 'weekly': return `weekly ${state.day} ${state.time}`;
    case 'monthly': return `monthly ${state.dom} ${state.time}`;
    case 'advanced': return state.advanced.trim() || 'on demand';
  }
}

function ScheduleComposer({
  agentId,
  initial,
  action,
  onCancel,
}: {
  agentId: string;
  initial: string;
  action: ServerAction;
  onCancel: () => void;
}) {
  const [state, setState] = useState(() => parseSchedule(initial));
  const set = (patch: Partial<typeof state>) => setState((s) => ({ ...s, ...patch }));
  const schedule = composeSchedule(state);

  return (
    <form action={action} className="ad-editor-form">
      <input type="hidden" name="agent_id" value={agentId} />
      <input type="hidden" name="schedule" value={schedule} />

      <div className="ad-sched-grid">
        <label className="ad-field">
          <span>Frequency</span>
          <select value={state.freq} onChange={(e) => set({ freq: e.target.value as Freq })} className="admin-input">
            <option value="ondemand">On demand</option>
            <option value="hourly">Hourly</option>
            <option value="daily">Daily</option>
            <option value="weekly">Weekly</option>
            <option value="monthly">Monthly</option>
            <option value="advanced">Advanced…</option>
          </select>
        </label>

        {state.freq === 'hourly' ? (
          <label className="ad-field">
            <span>Every</span>
            <span className="ad-inline-num">
              <input
                type="number" min={1} max={24} value={state.everyN}
                onChange={(e) => set({ everyN: Number(e.target.value) })}
                className="admin-input"
              />
              <em>hours</em>
            </span>
          </label>
        ) : null}

        {(state.freq === 'daily' || state.freq === 'weekly' || state.freq === 'monthly') ? (
          <label className="ad-field">
            <span>At</span>
            <input type="time" value={state.time} onChange={(e) => set({ time: e.target.value })} className="admin-input" />
          </label>
        ) : null}

        {state.freq === 'weekly' ? (
          <label className="ad-field">
            <span>On</span>
            <select value={state.day} onChange={(e) => set({ day: e.target.value })} className="admin-input">
              {WEEKDAYS.map(([v, l]) => <option key={v} value={v}>{l}</option>)}
            </select>
          </label>
        ) : null}

        {state.freq === 'monthly' ? (
          <label className="ad-field">
            <span>Day</span>
            <select value={state.dom} onChange={(e) => set({ dom: e.target.value })} className="admin-input">
              {Array.from({ length: 28 }, (_, i) => String(i + 1)).map((d) => (
                <option key={d} value={d}>{d}</option>
              ))}
              <option value="last">Last day</option>
            </select>
          </label>
        ) : null}

        {state.freq === 'advanced' ? (
          <label className="ad-field ad-field--wide">
            <span>Schedule expression</span>
            <input
              type="text" value={state.advanced}
              onChange={(e) => set({ advanced: e.target.value })}
              placeholder="e.g. every 5m · daily 07:30 · weekly fri 17:00"
              className="admin-input"
            />
          </label>
        ) : null}
      </div>

      <p className="ad-sched-preview">{humanizeSchedule(schedule)}</p>

      <div className="ad-editor-actions">
        <button type="submit" className="admin-button">Save schedule</button>
        <button type="button" className="admin-button secondary" onClick={onCancel}>Cancel</button>
      </div>
    </form>
  );
}

/* ---- Tools picker ------------------------------------------------------ */

function ToolsPicker({
  agentId,
  selected,
  tools,
  action,
  onCancel,
}: {
  agentId: string;
  selected: string[];
  tools: ToolDef[];
  action: ServerAction;
  onCancel: () => void;
}) {
  const [chosen, setChosen] = useState<Set<string>>(() => new Set(selected));
  const [query, setQuery] = useState('');

  const toggle = (name: string) =>
    setChosen((cur) => {
      const next = new Set(cur);
      if (next.has(name)) next.delete(name); else next.add(name);
      return next;
    });

  // Group available tools by category; keep currently-selected tools visible
  // even if they're filtered out by search.
  const groups = useMemo(() => {
    const q = query.trim().toLowerCase();
    const byCat = new Map<string, ToolDef[]>();
    for (const tool of tools) {
      const match = !q
        || tool.title.toLowerCase().includes(q)
        || tool.name.toLowerCase().includes(q)
        || tool.description.toLowerCase().includes(q);
      if (!match && !chosen.has(tool.name)) continue;
      const cat = tool.category || 'core';
      if (!byCat.has(cat)) byCat.set(cat, []);
      byCat.get(cat)!.push(tool);
    }
    return [...byCat.entries()].sort((a, b) => a[0].localeCompare(b[0]));
  }, [tools, query, chosen]);

  return (
    <form action={action} className="ad-editor-form">
      <input type="hidden" name="agent_id" value={agentId} />
      {[...chosen].map((name) => <input key={name} type="hidden" name="tool" value={name} />)}

      <div className="ad-tools-search">
        <Search size={14} aria-hidden />
        <input
          type="text" value={query} onChange={(e) => setQuery(e.target.value)}
          placeholder="Search tools" aria-label="Search tools"
        />
        <span className="ad-tools-count">{chosen.size} selected</span>
      </div>

      <div className="ad-tools-groups">
        {groups.length ? groups.map(([cat, list]) => {
          const entry = getToolIcon(cat);
          return (
            <div key={cat} className="ad-tools-group">
              <div className="ad-tools-group-head">
                <ToolIcon category={cat} size={13} />
                <span>{entry?.label || cat}</span>
              </div>
              <div className="ad-tools-options">
                {list.map((tool) => {
                  const on = chosen.has(tool.name);
                  const unavailable = !tool.available;
                  return (
                    <button
                      key={tool.name}
                      type="button"
                      className={`ad-tool-option ${on ? 'is-on' : ''}`}
                      onClick={() => toggle(tool.name)}
                      title={tool.description}
                      aria-pressed={on}
                    >
                      <span className="ad-tool-option-name">{tool.title}</span>
                      {tool.risk_level !== 'low' ? (
                        <span className="ad-tool-tag">approval</span>
                      ) : null}
                      {unavailable ? <span className="ad-tool-tag warn">setup</span> : null}
                    </button>
                  );
                })}
              </div>
            </div>
          );
        }) : (
          <p className="ad-tools-noresult">No tools match “{query}”.</p>
        )}
      </div>

      <div className="ad-editor-actions">
        <button type="submit" className="admin-button">Save tools</button>
        <button type="button" className="admin-button secondary" onClick={onCancel}>Cancel</button>
      </div>
    </form>
  );
}
