// Grocery Mentor Dashboard — frontend. Plain React via CDN + in-browser
// Babel (no build step — this is a low-traffic internal admin tool, not
// the public site, so the perf budget that governs grocerymentor.com
// itself doesn't apply here). Talks to /api/* (functions/api/[[path]].js)
// which commits straight to the grocery-mentor GitLab repo.
const { useState, useEffect, useCallback } = React;

const PILLARS = ['budget', 'prices-and-value', 'savings', 'meal-planning', 'lists-and-pantry', 'storage-and-waste'];
const PILLAR_LABELS = {
  budget: 'Budget',
  'prices-and-value': 'Prices & Value',
  savings: 'Savings',
  'meal-planning': 'Meal Planning',
  'lists-and-pantry': 'Lists & Pantry',
  'storage-and-waste': 'Storage & Waste',
};

function api(path, opts) {
  return fetch(`/api/${path}`, {
    ...opts,
    headers: { 'Content-Type': 'application/json', ...(opts && opts.headers) },
  }).then(async (res) => {
    const data = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(data.error || `Request failed (${res.status})`);
    return data;
  });
}

function todayISO() {
  return new Date().toISOString().slice(0, 10);
}

function Badge({ draft }) {
  return <span className={`badge ${draft ? 'badge-draft' : 'badge-live'}`}>{draft ? 'Draft' : 'Live'}</span>;
}

function Button({ children, onClick, variant = 'primary', type = 'button', disabled }) {
  const styles = {
    primary: 'clay-terra text-clay-cream',
    secondary: 'clay-2 text-ink',
    danger: 'bg-terra/10 text-terra border border-terra/30',
  };
  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled}
      className={`clay-press rounded-full px-5 py-2.5 text-sm font-extrabold disabled:opacity-50 ${styles[variant]}`}
    >
      {children}
    </button>
  );
}

function Field({ label, children, hint }) {
  return (
    <label className="block">
      <span className="eyebrow text-sage-deep">{label}</span>
      <div className="mt-1.5">{children}</div>
      {hint && <span className="mt-1 block text-xs text-moss/60">{hint}</span>}
    </label>
  );
}

function Toast({ message, kind, onClose }) {
  if (!message) return null;
  return (
    <div
      className={`fixed bottom-6 right-6 z-50 max-w-sm rounded-clay-lg px-5 py-4 text-sm font-semibold clay-3 ${
        kind === 'error' ? 'text-terra' : 'text-moss'
      }`}
      onClick={onClose}
    >
      {message}
    </div>
  );
}

// ---------------------------------------------------------------------
// Guide / Page editor (shared shape, guides have extra fields)
// ---------------------------------------------------------------------
function Editor({ kind, lang, slug, onDone, onToast }) {
  const isNew = slug === '__new__';
  const [loading, setLoading] = useState(!isNew);
  const [saving, setSaving] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [data, setData] = useState({
    slug: '',
    title: '',
    h1: '',
    description: '',
    pillar: PILLARS[0],
    takeaway: '',
    published: todayISO(),
    updated: todayISO(),
    draft: true,
    relatedTools: '',
    relatedGuides: '',
    faqs: [],
    body: '',
  });

  useEffect(() => {
    if (isNew) return;
    api(`${kind}/${lang}/${slug}`).then((entry) => {
      setData({
        ...entry,
        relatedTools: (entry.relatedTools || []).join(', '),
        relatedGuides: (entry.relatedGuides || []).join(', '),
        faqs: entry.faqs || [],
      });
      setLoading(false);
    }).catch((e) => { onToast(e.message, 'error'); setLoading(false); });
  }, [kind, lang, slug]);

  function set(field, value) {
    setData((d) => ({ ...d, [field]: value }));
  }

  function setFaq(i, field, value) {
    setData((d) => {
      const faqs = [...d.faqs];
      faqs[i] = { ...faqs[i], [field]: value };
      return { ...d, faqs };
    });
  }

  function addFaq() {
    setData((d) => ({ ...d, faqs: [...d.faqs, { q: '', a: '' }] }));
  }

  function removeFaq(i) {
    setData((d) => ({ ...d, faqs: d.faqs.filter((_, idx) => idx !== i) }));
  }

  async function save() {
    setSaving(true);
    try {
      const payload = {
        title: data.title,
        h1: data.h1 || undefined,
        description: data.description,
        draft: data.draft,
        body: data.body,
      };
      if (kind === 'guides') {
        payload.pillar = data.pillar;
        payload.takeaway = data.takeaway;
        payload.published = data.published;
        payload.updated = data.updated;
        payload.author = 'sk-jabedul-haque';
        payload.relatedTools = data.relatedTools.split(',').map((s) => s.trim()).filter(Boolean);
        payload.relatedGuides = data.relatedGuides.split(',').map((s) => s.trim()).filter(Boolean);
        payload.faqs = data.faqs.filter((f) => f.q && f.a);
      }
      if (isNew) {
        if (!data.slug) throw new Error('Slug is required');
        await api(`${kind}/${lang}`, { method: 'POST', body: JSON.stringify({ slug: data.slug, ...payload }) });
      } else {
        await api(`${kind}/${lang}/${slug}`, { method: 'PUT', body: JSON.stringify(payload) });
      }
      onToast(isNew ? 'Created — deploy starting.' : 'Saved — deploy starting.', 'ok');
      onDone();
    } catch (e) {
      onToast(e.message, 'error');
    } finally {
      setSaving(false);
    }
  }

  async function remove() {
    if (!confirm(`Delete "${data.title}"? This commits a delete to main.`)) return;
    setDeleting(true);
    try {
      await api(`${kind}/${lang}/${slug}`, { method: 'DELETE' });
      onToast('Deleted — deploy starting.', 'ok');
      onDone();
    } catch (e) {
      onToast(e.message, 'error');
      setDeleting(false);
    }
  }

  if (loading) return <div className="p-10 text-center text-moss/60">Loading…</div>;

  return (
    <div className="mx-auto max-w-3xl">
      <div className="flex items-center justify-between">
        <h2 className="display text-2xl text-ink">
          {isNew ? `New ${kind === 'guides' ? 'guide' : 'page'}` : data.title}
        </h2>
        <div className="flex gap-2">
          {!isNew && (
            <Button variant="danger" onClick={remove} disabled={deleting}>
              {deleting ? 'Deleting…' : 'Delete'}
            </Button>
          )}
          <Button variant="secondary" onClick={onDone}>Cancel</Button>
          <Button onClick={save} disabled={saving}>{saving ? 'Saving…' : 'Save'}</Button>
        </div>
      </div>

      <div className="mt-6 grid gap-5 rounded-clay-xl p-6 clay-2 sm:p-8">
        {isNew && (
          <Field label="Slug (URL-safe, lowercase-kebab-case)" hint="Cannot be changed after creation.">
            <input className="calc-input" value={data.slug} onChange={(e) => set('slug', e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, '-'))} />
          </Field>
        )}

        <div className="flex items-center gap-3 rounded-clay-lg p-4 clay-1">
          <input type="checkbox" checked={!data.draft} onChange={(e) => set('draft', !e.target.checked)} className="h-5 w-5 accent-moss" />
          <div>
            <p className="text-sm font-extrabold text-ink">Published (uncheck to save as draft)</p>
            <p className="text-xs text-moss/60">Draft pages/guides never get a live URL — safe to save anytime.</p>
          </div>
          <Badge draft={data.draft} />
        </div>

        <Field label="Title"><input className="calc-input" value={data.title} onChange={(e) => set('title', e.target.value)} /></Field>
        <Field label="H1 (optional — falls back to Title)"><input className="calc-input" value={data.h1 || ''} onChange={(e) => set('h1', e.target.value)} /></Field>
        <Field label={`Meta description (${data.description.length}/165)`}>
          <textarea className="calc-input" rows={2} value={data.description} onChange={(e) => set('description', e.target.value)} />
        </Field>

        {kind === 'guides' && (
          <>
            <Field label="Pillar">
              <select className="calc-input" value={data.pillar} onChange={(e) => set('pillar', e.target.value)}>
                {PILLARS.map((p) => <option key={p} value={p}>{PILLAR_LABELS[p]}</option>)}
              </select>
            </Field>
            <Field label="Takeaway / quick answer">
              <textarea className="calc-input" rows={2} value={data.takeaway} onChange={(e) => set('takeaway', e.target.value)} />
            </Field>
            <div className="grid grid-cols-2 gap-4">
              <Field label="Published date"><input type="date" className="calc-input" value={data.published} onChange={(e) => set('published', e.target.value)} /></Field>
              <Field label="Updated date"><input type="date" className="calc-input" value={data.updated} onChange={(e) => set('updated', e.target.value)} /></Field>
            </div>
            <Field label="Related tool keys (comma-separated)" hint="e.g. grocery-budget, unit-price"><input className="calc-input" value={data.relatedTools} onChange={(e) => set('relatedTools', e.target.value)} /></Field>
            <Field label="Related guide slugs (comma-separated)"><input className="calc-input" value={data.relatedGuides} onChange={(e) => set('relatedGuides', e.target.value)} /></Field>

            <div>
              <span className="eyebrow text-sage-deep">FAQs</span>
              <div className="mt-2 grid gap-3">
                {data.faqs.map((f, i) => (
                  <div key={i} className="rounded-clay-lg p-4 clay-1">
                    <div className="flex items-center justify-between">
                      <span className="text-xs font-bold text-moss/60">FAQ {i + 1}</span>
                      <button onClick={() => removeFaq(i)} className="text-xs font-bold text-terra">Remove</button>
                    </div>
                    <input className="calc-input mt-2" placeholder="Question" value={f.q} onChange={(e) => setFaq(i, 'q', e.target.value)} />
                    <textarea className="calc-input mt-2" rows={2} placeholder="Answer" value={f.a} onChange={(e) => setFaq(i, 'a', e.target.value)} />
                  </div>
                ))}
              </div>
              <button onClick={addFaq} className="mt-3 text-sm font-extrabold text-terra">+ Add FAQ</button>
            </div>
          </>
        )}

        <Field label="Body (Markdown)">
          <textarea className="calc-input font-mono" rows={16} value={data.body} onChange={(e) => set('body', e.target.value)} />
        </Field>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------
// List view
// ---------------------------------------------------------------------
function ListView({ kind, lang, onEdit, onToast }) {
  const [items, setItems] = useState(null);
  const [filter, setFilter] = useState('');
  const [pillarFilter, setPillarFilter] = useState('all');

  const load = useCallback(() => {
    setItems(null);
    api(`${kind}/${lang}`).then(setItems).catch((e) => onToast(e.message, 'error'));
  }, [kind, lang]);

  useEffect(load, [load]);

  const filtered = (items || []).filter((it) => {
    if (pillarFilter !== 'all' && it.pillar !== pillarFilter) return false;
    if (filter && !it.title.toLowerCase().includes(filter.toLowerCase())) return false;
    return true;
  });

  return (
    <div>
      <div className="flex flex-wrap items-center justify-between gap-3">
        <h2 className="display text-2xl text-ink">
          {kind === 'guides' ? 'Guides' : 'Pages'} — {lang === 'en' ? 'English' : 'Español'}
        </h2>
        <div className="flex items-center gap-2">
          <button onClick={load} className="clay-press rounded-full px-4 py-2 text-xs font-extrabold clay-1 text-moss">Refresh</button>
          <Button onClick={() => onEdit('__new__')}>+ New {kind === 'guides' ? 'guide' : 'page'}</Button>
        </div>
      </div>

      <div className="mt-4 flex flex-wrap gap-3">
        <input className="calc-input max-w-xs" placeholder="Search title…" value={filter} onChange={(e) => setFilter(e.target.value)} />
        {kind === 'guides' && (
          <select className="calc-input max-w-xs" value={pillarFilter} onChange={(e) => setPillarFilter(e.target.value)}>
            <option value="all">All pillars</option>
            {PILLARS.map((p) => <option key={p} value={p}>{PILLAR_LABELS[p]}</option>)}
          </select>
        )}
      </div>

      {items === null && <div className="mt-8 text-center text-moss/60">Loading…</div>}
      {items && filtered.length === 0 && <div className="mt-8 text-center text-moss/60">Nothing here yet.</div>}

      <div className="mt-5 grid gap-3">
        {filtered.map((it) => (
          <button
            key={it.slug}
            onClick={() => onEdit(it.slug)}
            className="clay-lift flex items-center justify-between gap-4 rounded-clay-lg p-5 text-left clay-1"
          >
            <div className="min-w-0">
              <p className="display truncate text-lg text-ink">{it.title}</p>
              <p className="mt-1 truncate text-sm text-moss/70">{it.description}</p>
              <p className="mt-1 text-xs text-moss/50">
                {it.pillar && `${PILLAR_LABELS[it.pillar]} · `}Updated {it.updated || '—'}
              </p>
            </div>
            <Badge draft={it.draft} />
          </button>
        ))}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------
// Deploys panel
// ---------------------------------------------------------------------
function DeploysView() {
  const [deploys, setDeploys] = useState(null);
  const [err, setErr] = useState(null);

  useEffect(() => {
    api('deploys').then(setDeploys).catch((e) => setErr(e.message));
  }, []);

  return (
    <div>
      <h2 className="display text-2xl text-ink">Recent deploys</h2>
      <p className="mt-1 text-sm text-moss/60">grocerymentor.com — Cloudflare Pages</p>
      {err && <p className="mt-4 text-terra">{err}</p>}
      {!deploys && !err && <div className="mt-8 text-center text-moss/60">Loading…</div>}
      <div className="mt-5 grid gap-3">
        {(deploys || []).map((d) => (
          <div key={d.id} className="rounded-clay-lg p-5 clay-1">
            <div className="flex items-center justify-between">
              <span className="text-sm font-extrabold text-ink">
                {d.deployment_trigger?.metadata?.commit_message || d.id}
              </span>
              <span className={`badge ${d.latest_stage?.status === 'success' ? 'badge-live' : 'badge-draft'}`}>
                {d.latest_stage?.status || d.stage || '—'}
              </span>
            </div>
            <p className="mt-1 text-xs text-moss/50">{new Date(d.created_on).toLocaleString()}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------
// App shell
// ---------------------------------------------------------------------
const NAV = [
  { key: 'guides-en', label: 'Guides · EN', kind: 'guides', lang: 'en' },
  { key: 'guides-es', label: 'Guides · ES', kind: 'guides', lang: 'es' },
  { key: 'pages-en', label: 'Pages · EN', kind: 'pages', lang: 'en' },
  { key: 'pages-es', label: 'Pages · ES', kind: 'pages', lang: 'es' },
  { key: 'deploys', label: 'Deploys', kind: 'deploys' },
];

function App() {
  const [nav, setNav] = useState('guides-en');
  const [editingSlug, setEditingSlug] = useState(null);
  const [toast, setToast] = useState({ message: '', kind: 'ok' });

  function showToast(message, kind) {
    setToast({ message, kind });
    setTimeout(() => setToast({ message: '', kind: 'ok' }), 3500);
  }

  const active = NAV.find((n) => n.key === nav);

  return (
    <div className="min-h-screen">
      <header className="clay-ink px-6 py-5">
        <div className="mx-auto flex max-w-6xl items-center justify-between">
          <span className="display text-xl text-pale">Grocery <span className="text-terra">Mentor</span> <span className="text-mist">/ dashboard</span></span>
          <a href="https://grocerymentor.com" target="_blank" className="text-xs font-bold text-mist hover:text-pale">View live site →</a>
        </div>
      </header>

      <div className="mx-auto flex max-w-6xl gap-6 px-6 py-8">
        <nav className="w-48 shrink-0">
          <div className="grid gap-1.5">
            {NAV.map((n) => (
              <button
                key={n.key}
                onClick={() => { setNav(n.key); setEditingSlug(null); }}
                className={`rounded-clay-lg px-4 py-2.5 text-left text-sm font-extrabold transition ${
                  nav === n.key ? 'clay-2 text-ink' : 'text-moss/60 hover:text-ink'
                }`}
              >
                {n.label}
              </button>
            ))}
          </div>
        </nav>

        <main className="flex-1">
          {active.kind === 'deploys' && <DeploysView />}
          {active.kind !== 'deploys' && editingSlug === null && (
            <ListView kind={active.kind} lang={active.lang} onEdit={setEditingSlug} onToast={showToast} />
          )}
          {active.kind !== 'deploys' && editingSlug !== null && (
            <Editor
              kind={active.kind}
              lang={active.lang}
              slug={editingSlug}
              onDone={() => setEditingSlug(null)}
              onToast={showToast}
            />
          )}
        </main>
      </div>

      <Toast message={toast.message} kind={toast.kind} onClose={() => setToast({ message: '', kind: 'ok' })} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
