/* Phase 7: script/style/shared-loader wiring is in docs/phase7-wiring.md. */
(() => {
  const O = window.AreteOperations;
  function Chips({ title, items }) {
    return <><div className="k">{title}</div><div className="chips">{items?.length
      ? items.map((item, i) => <span className="chip" key={i}>{title === 'Scheduled' && <Icon name="clock" size={14} />}{item}</span>)
      : <span className="muted">None listed</span>}</div></>;
  }
  function AgentDetails({ node }) {
    return <><div className="hd"><span className="ini agent-initial" aria-hidden="true">{node.name.slice(0, 1)}</span>
      <div><div className="nm">{node.name}</div><div className="rl">{node.role}</div></div></div>
      {node.does?.length > 0 && <ul className="does">{node.does.map((line, i) => <li key={i}>{line}</li>)}</ul>}
      <Chips title="Skills" items={node.skills} /><Chips title="Scheduled" items={node.scheduled_tasks} /></>;
  }
  function OrgBranch({ node }) {
    return <><article className="ocard"><AgentDetails node={node} /></article>
      {node.children.length > 0 && <div className="orgrow">{node.children.map(child => <article className="dept" key={child.id}>
        {child.kind === 'department' ? <><div className="dn">{child.name}</div>
          {child.children.length ? child.children.map(agent => <div className="dept-agent" key={agent.id}><AgentDetails node={agent} /></div>)
            : <div className="dl">{child.role}</div>}
          {child.does?.length > 0 && <ul className="does">{child.does.map((line, i) => <li key={i}>{line}</li>)}</ul>}
          {child.skills.length > 0 && <Chips title="Skills" items={child.skills} />}
          {!child.children.length && <Chips title="Scheduled" items={child.scheduled_tasks} />}
        </> : <AgentDetails node={child} />}
      </article>)}</div>}</>;
  }
  function OrgPage() {
    const t = useTables(['org']);
    if (t.status === 'loading') return <Loading />;
    if (t.status === 'error') return <LoadError error={t.error} onRetry={t.reload} />;
    if (!t.data.org?.length) return <NoData>The org chart has not been pushed yet.</NoData>;
    let roots;
    try { roots = O.orgTree(t.data.org); } catch (e) { return <LoadError error={e.message} onRetry={t.reload} />; }
    return <div className="phase7"><div className="org">
      <article className="ocard owners"><div className="hd"><span className="ini" aria-hidden="true">RB</span>
        <div><div className="nm">Ryan &amp; Addie</div><div className="rl">Owners · final say on money, messages and live changes</div></div></div></article>
      <div className="vline" aria-hidden="true" />{roots.map(root => <OrgBranch node={root} key={root.id} />)}
    </div></div>;
  }
  function Runner({ value }) { return <span className={'runner ' + value}><span className="rd" aria-hidden="true" />{O.RUNNERS[value]}</span>; }
  function LastRun({ routine, runs }) {
    const result = O.runStatus(routine, runs, { now: new Date().toISOString() });
    return <span>{result.at && <><time dateTime={result.at}>{O.formatRun(result.at)}</time> · </>}
      <span className={result.tone}>{result.label}</span></span>;
  }
  const DAY_HELP = { daily: 'Daily chores need no day.', weekly: '0 = Sun, 1 = Mon, … 6 = Sat. Separate days with commas.',
    monthly: 'Day of month, 1–31. Months without that day are skipped.', quarterly: 'Day of Jan, Apr, Jul and Oct, 1–31.', yearly: 'Month and day as MM-DD, for example 04-30.' };
  function ChoreForm({ row, busy, onSave, onClose }) {
    const [form, setForm] = React.useState(row || { name: '', cadence: 'monthly', day: '1', time: '', owner: '', notes: '', last_run_at: null, last_ok: null });
    const [error, setError] = React.useState('');
    const nameRef = React.useRef(null);
    React.useEffect(() => { nameRef.current?.focus(); }, []);
    const set = (key, value) => setForm(f => ({ ...f, [key]: value }));
    const submit = e => { e.preventDefault(); try { const params = O.choreParams(form); setError(''); onSave(params); } catch (err) { setError(err.message); } };
    return <form className="chore-form" onSubmit={submit} aria-label={row ? 'Edit chore' : 'Add a chore'}>
      <h2>{row ? 'Edit chore' : 'Add a chore'}</h2>
      {error && <p role="alert">{error}</p>}
      <fieldset disabled={busy}><div className="form-grid">
        <label>Name<input ref={nameRef} value={form.name} required maxLength={200} onChange={e => set('name', e.target.value)} /></label>
        <label>Owner<input value={form.owner} maxLength={200} onChange={e => set('owner', e.target.value)} placeholder="Who will do it?" /></label>
        <label>Repeat<select value={form.cadence} onChange={e => setForm(f => ({ ...f, cadence: e.target.value,
          day: e.target.value === 'daily' ? '' : e.target.value === 'yearly' ? '01-01' : '1' }))}>
          {O.CADENCES.map(c => <option key={c} value={c}>{c[0].toUpperCase() + c.slice(1)}</option>)}</select></label>
        <label>Day<input value={form.day} disabled={form.cadence === 'daily'} aria-describedby="chore-day-help" onChange={e => set('day', e.target.value)} />
          <span id="chore-day-help" className="help">{DAY_HELP[form.cadence]}</span></label>
        <label>Time (New York)<input value={form.time} aria-describedby="chore-time-help" onChange={e => set('time', e.target.value)} placeholder="09:30" />
          <span id="chore-time-help" className="help">24-hour HH:MM. Separate times with commas, or leave blank.</span></label>
        <div><label>Last result<select value={form.last_ok === null ? 'unknown' : form.last_ok ? 'ok' : 'bad'} onChange={e => set('last_ok', e.target.value === 'unknown' ? null : e.target.value === 'ok')}>
          <option value="unknown">Not recorded</option><option value="ok">OK</option><option value="bad">Not OK</option></select>
          </label><span className="help">Last run: {O.formatRun(form.last_run_at)}</span><div className="chore-actions">
          <button type="button" className="linkbtn" onClick={() => setForm(f => ({ ...f, last_run_at: new Date().toISOString(), last_ok: true }))}>Mark done now</button>
          {form.last_run_at && <button type="button" className="linkbtn" onClick={() => setForm(f => ({ ...f, last_run_at: null, last_ok: null }))}>Clear last run</button>}</div></div>
        <label className="wide">Notes<textarea value={form.notes} maxLength={4000} rows={3} onChange={e => set('notes', e.target.value)} /></label>
      </div><div className="chore-actions"><button className="btn primary" type="submit">{busy ? 'Saving…' : 'Save chore'}</button>
        <button className="btn ghost" type="button" onClick={onClose}>Cancel</button></div></fieldset>
    </form>;
  }
  function RecurringPage() {
    const routines = useTables(['routines']);
    const runs = useTables(['job_runs_latest']);
    const [editing, setEditing] = React.useState(undefined);
    const [busy, setBusy] = React.useState(false);
    const [writeError, setWriteError] = React.useState('');
    const [message, setMessage] = React.useState('');
    const [deleting, setDeleting] = React.useState(null);
    const addRef = React.useRef(null);
    const preview = window.isPreview();
    const close = () => { setEditing(undefined); addRef.current?.focus(); };
    const mutate = async (fn, params, message) => {
      if (preview || busy) return;
      setBusy(true); setWriteError(''); setMessage('');
      try {
        const { error } = await window.supaClient.rpc(fn, params);
        if (error) throw error;
        close(); setDeleting(null); setMessage(message); routines.reload();
      } catch (_) { setWriteError('Could not save this change. Check your connection and membership, then try again.'); }
      finally { setBusy(false); }
    };
    if (routines.status === 'loading') return <Loading />;
    if (routines.status === 'error') return <LoadError error={routines.error} onRetry={routines.reload} />;
    const list = routines.data.routines || [];
    const calendar = O.week(list, todayNY());
    const lastCell = r => runs.status === 'error' && r.runner === 'site' ? <span>Run status unavailable</span>
      : runs.status === 'loading' && r.runner === 'site' ? <span role="status">Loading run…</span>
      : <LastRun routine={r} runs={runs.data.job_runs_latest || []} />;
    const unknownJobs = [...O.latestRuns(runs.data.job_runs_latest || []).keys()].filter(job => !job.startsWith('push_') && !list.some(r => r.job === job));
    return <div className="phase7">
      <div className="secthead"><h2>This week</h2><span className="dd">{calendar.label}</span><div className="right">
        <button ref={addRef} className="btn ghost" disabled={preview || busy} onClick={() => { setEditing(null); setWriteError(''); }}>Add a chore</button></div></div>
      {preview && <p className="muted">Preview is read-only. Sign in on the live site to change chores.</p>}
      <p className="sr">Times are in New York unless marked UTC.</p>
      {writeError && <div className="notice" role="alert">{writeError}</div>}
      {message && <p role="status">{message}</p>}
      {editing !== undefined && <ChoreForm key={editing?.id || 'new'} row={editing} busy={busy} onClose={close}
        onSave={params => mutate('arete_upsert_chore', params, 'Chore saved.')} />}
      {runs.status === 'error' && <LoadError error="Site job results could not be loaded." onRetry={runs.reload} />}
      {!list.length && <NoData>No recurring tasks yet. Add a chore to start.</NoData>}
      <div className="everyday"><b>Every day</b>{calendar.daily.length ? calendar.daily.map(r => <span key={r.id}>{r.name} <i>{O.scheduleTime(r)} · {O.RUNNERS[r.runner]}</i></span>) : <span>No daily tasks</span>}</div>
      <div className="week" role="region" tabIndex={0} aria-label="Week at a glance, scroll for more days">{calendar.days.map(day => <div key={day.date} className={'day' + (day.today ? ' today' : '')}>
        <div className="dn"><span>{day.day}{day.today && <span className="muted"> · today</span>}</span><time dateTime={day.date}>{day.number}</time></div>
        {day.rows.length ? day.rows.map(r => <div className="ev" key={r.id}>{r.name}<i>{O.RUNNERS[r.runner]} · {O.scheduleTime(r)}</i></div>)
          : <div className="muted day-empty">{calendar.daily.length ? 'Only daily jobs' : 'No tasks'}</div>}</div>)}</div>
      <div className="runner-legend"><Runner value="site" /><Runner value="claude" /><Runner value="person" /><span>New York time unless marked UTC</span></div>
      {O.groups(list).map(group => <section key={group.cadence} aria-label={group.label}><h2 className="monthhead">{group.label}</h2>
        {!group.rows.length ? <NoData>No {group.cadence} tasks.</NoData> : <div className="tcard"><table className="tbl stack fixed">
          <caption className="sr">{group.label} recurring tasks</caption><colgroup><col style={{ width: '34%' }} /><col style={{ width: '20%' }} /><col style={{ width: '24%' }} /><col style={{ width: '22%' }} /></colgroup>
          <thead className="sr"><tr><th>Task</th><th>Who</th><th>When</th><th>Last run</th></tr></thead>
          <tbody>{group.rows.map(r => <tr key={r.id}><td data-l="Task"><div className="task-name">{r.name}{r.enabled === false && <span className="muted"> · Paused</span>}</div>
            {r.notes && <details><summary>Notes</summary><p>{r.notes}</p></details>}
            {O.canEdit(r) && <div className="chore-actions"><button className="linkbtn" disabled={preview || busy} aria-label={'Edit ' + r.name} onClick={() => { setEditing(r); setWriteError(''); }}>Edit</button>
              <button className="linkbtn" disabled={preview || busy} aria-label={'Delete ' + r.name} onClick={() => setDeleting(r.id)}>Delete</button>
              {deleting === r.id && <div role="group" aria-label={'Delete ' + r.name + '?'}><span>Delete this chore? </span>
                <button className="linkbtn" disabled={busy} onClick={() => mutate('arete_delete_chore', { p_id: r.id }, 'Chore deleted.')}>Delete chore</button>
                <button className="linkbtn" disabled={busy} onClick={() => setDeleting(null)}>Keep chore</button></div>}</div>}</td>
            <td data-l="Who"><Runner value={r.runner} /></td><td data-l="When" className="muted">{O.when(r)}</td><td data-l="Last run" className="r">{lastCell(r)}</td></tr>)}</tbody>
        </table></div>}</section>)}
      {unknownJobs.length > 0 && <section><h2 className="monthhead">Other site jobs</h2><div className="tcard"><table className="tbl stack"><thead><tr><th>Job</th><th>Last run</th></tr></thead>
        <tbody>{unknownJobs.sort().map(job => <tr key={job}><td data-l="Job">{job}</td><td data-l="Last run">{lastCell({ runner: 'site', job })}</td></tr>)}</tbody></table></div></section>}
    </div>;
  }
  window.ARETE_PAGES = Object.assign(window.ARETE_PAGES || {}, { 'operations/org': OrgPage, 'operations/recurring': RecurringPage });
})();
