"use client";

/**
 * smart-search-value-modal.jsx — minimalist inline "set a value" modal launched
 * from smart search. Renders ONE field from a SETTING_ACTIONS entry, submits to
 * that entry's audited endpoint via resolveWrite(), and shows current status.
 *
 * Security: for secrets the value is write-only — it is POSTed straight to the
 * admin-gated /api/secrets route and never echoed back. The modal only ever
 * displays status (set / unset), never a stored secret value.
 */

import { useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { resolveWrite } from '@/lib/help/registry.js';

function currentLabel(action, current) {
  if (!current) return null;
  if (action.kind === 'secret') return current.status === 'set' ? 'Currently set' : 'Not set';
  if (current.value != null) {
    const opt = action.field.options?.find((o) => o.value === current.value);
    return `Currently: ${opt ? opt.label : current.value}`;
  }
  return null;
}

export default function SmartSearchValueModal({ action, current, onClose, onSaved }) {
  const router = useRouter();
  const firstRef = useRef(null);
  const field = action.field;
  const [value, setValue] = useState(field.type === 'select' ? current?.value || field.options?.[0]?.value || '' : '');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');
  const [done, setDone] = useState(false);

  useEffect(() => {
    const t = window.setTimeout(() => firstRef.current?.focus(), 0);
    return () => window.clearTimeout(t);
  }, []);

  useEffect(() => {
    function onKey(e) {
      if (e.key === 'Escape') { e.preventDefault(); onClose(); }
    }
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  async function submit(e) {
    e.preventDefault();
    if (busy) return;
    const trimmed = String(value).trim();
    if (!trimmed) { setError('Enter a value.'); return; }
    setBusy(true);
    setError('');
    try {
      const { endpoint, method, body } = resolveWrite(action, trimmed);
      const res = await fetch(endpoint, {
        method,
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(body),
      });
      if (!res.ok) {
        if (res.status === 403) {
          setError('You need admin or owner access to change this.');
        } else if (res.status === 401) {
          setError('Sign in to change this setting.');
        } else {
          // Routes return either a JSON { error } body or a plain-text message.
          const raw = await res.text().catch(() => '');
          let message = raw;
          try { message = JSON.parse(raw)?.error || raw; } catch { /* plain text */ }
          setError(message || `Failed (${res.status}).`);
        }
        setBusy(false);
        return;
      }
      setDone(true);
      setBusy(false);
      onSaved?.(action);
      window.setTimeout(() => onClose(), 700);
    } catch (err) {
      setError(err?.message || 'Network error.');
      setBusy(false);
    }
  }

  const label = currentLabel(action, current);

  return (
    <div className="help-value-overlay" role="presentation" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <form className="help-value-modal" role="dialog" aria-modal="true" aria-label={action.title} onSubmit={submit}>
        <header className="help-value-head">
          <div>
            <small>{action.category}</small>
            <h2>{action.title}</h2>
          </div>
          <button type="button" className="help-value-close" onClick={onClose} aria-label="Close">esc</button>
        </header>

        <div className="help-value-body">
          <label className="help-value-field">
            <span className="help-value-label">{field.label}{label ? <em className="help-value-status">{label}</em> : null}</span>
            {field.type === 'select' ? (
              <select ref={firstRef} value={value} onChange={(e) => setValue(e.target.value)} disabled={busy || done}>
                {field.options.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
              </select>
            ) : (
              <input
                ref={firstRef}
                type={field.type === 'password' ? 'password' : 'text'}
                value={value}
                placeholder={field.placeholder || ''}
                onChange={(e) => setValue(e.target.value)}
                disabled={busy || done}
                autoComplete="off"
                spellCheck={false}
              />
            )}
          </label>
          {field.help ? <p className="help-value-help">{field.help}</p> : null}
          {error ? <p className="help-value-error" role="alert">{error}</p> : null}
          {done ? <p className="help-value-ok" role="status">Saved.</p> : null}
        </div>

        <footer className="help-value-foot">
          <div className="help-value-links">
            <a href={action.settingsHref} onClick={onClose}>Open full settings</a>
            {action.docSlug ? <a href={`/help/${action.docSlug}`} onClick={onClose}>Read the guide</a> : null}
          </div>
          <div className="help-value-actions">
            <button type="button" className="help-value-btn ghost" onClick={onClose} disabled={busy}>Cancel</button>
            <button type="submit" className="help-value-btn primary" disabled={busy || done}>{busy ? 'Saving…' : 'Save'}</button>
          </div>
        </footer>
      </form>
    </div>
  );
}
