/* Organization: settings and modules, members and roles, linked AI
   visibility reports, the audit log, restricted notes (HR flag only), and
   export / delete. */

function OrgModule({ ctx }) {
  const [tab, setTab] = React.useState('settings');
  const tabs = [['settings', 'Settings'], ['members', 'Members'], ['reports', 'AI visibility reports'], ['audit', 'Audit log'], ['data', 'Data']];
  if (ctx.flags.includes('hr_restricted')) tabs.splice(4, 0, ['restricted', 'Restricted (HR)']);
  return <div>
    <SubTabs value={tab} onChange={setTab} tabs={tabs} />
    {tab === 'settings' && <OrgSettings ctx={ctx} />}
    {tab === 'members' && <Members ctx={ctx} />}
    {tab === 'reports' && <LinkedReports ctx={ctx} />}
    {tab === 'audit' && <AuditLog ctx={ctx} />}
    {tab === 'restricted' && <Restricted ctx={ctx} />}
    {tab === 'data' && <DataPanel ctx={ctx} />}
  </div>;
}

function OrgSettings({ ctx }) {
  const org = ctx.orgData.org;
  const [f, setF] = React.useState({ name: org.name, industry: (org.profile || {}).industry || '', size_band: (org.profile || {}).size_band || '', revenue_band: (org.profile || {}).revenue_band || '', description: (org.profile || {}).description || '', ai_assist: (org.settings || {}).ai_assist !== false, currency: (org.settings || {}).currency || 'USD' });
  const [flash, setFlash] = React.useState('');
  const canEdit = !ctx.readOnly && ['owner', 'admin', 'operator'].includes(ctx.role);
  const save = async () => {
    const d = await lojo(ctx.token, { module: 'org', action: 'update', org: ctx.org, name: f.name, profile: { ...(org.profile || {}), industry: f.industry, size_band: f.size_band, revenue_band: f.revenue_band, description: f.description }, settings: { ...(org.settings || {}), ai_assist: f.ai_assist, currency: f.currency } });
    setFlash(d.ok ? 'Saved.' : (d.message || 'Not saved')); if (d.ok) ctx.reload();
  };
  return (
    <div style={{ maxWidth: 720 }}>
      <div className="app-grid cols-2">
        <Field label="Organization name"><Input value={f.name} onChange={(e) => setF({ ...f, name: e.target.value })} disabled={!canEdit} /></Field>
        <Field label="Industry"><Input value={f.industry} onChange={(e) => setF({ ...f, industry: e.target.value })} disabled={!canEdit} /></Field>
        <Field label="Headcount band"><Select value={f.size_band} onChange={(v) => setF({ ...f, size_band: v })} options={[['', 'Choose'], '1–25', '25–100', '100–250', '250–1,000', '1,000+']} disabled={!canEdit} /></Field>
        <Field label="Revenue band"><Select value={f.revenue_band} onChange={(v) => setF({ ...f, revenue_band: v })} options={[['', 'Choose'], 'Under $5M', '$5M–$25M', '$25M–$100M', '$100M–$500M', 'Over $500M']} disabled={!canEdit} /></Field>
      </div>
      <Field label="What the business does"><textarea className="app-input" rows={3} value={f.description} onChange={(e) => setF({ ...f, description: e.target.value })} disabled={!canEdit} /></Field>
      <div className="app-panel" style={{ marginBottom: 14 }}>
        <h3>AI assistance</h3>
        <label style={{ display: 'flex', gap: 10, alignItems: 'flex-start', fontSize: 13.5, lineHeight: 1.6 }}>
          <input type="checkbox" checked={f.ai_assist} onChange={(e) => setF({ ...f, ai_assist: e.target.checked })} disabled={!canEdit} style={{ marginTop: 4 }} />
          <span>Allow Claude to write explanations of recommendations and opportunities. It only sees the record and its evidence, cites evidence ids, and never changes a number. Restricted (HR) data is never sent. Customer data is never used to train shared models, with or without this setting.</span>
        </label>
      </div>
      <div className="app-panel" style={{ marginBottom: 14 }}>
        <h3>Modules</h3>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>{ctx.orgData.modules.map((m) => <span key={m.id} className="chip" style={m.status === 'enabled' ? { borderColor: 'var(--accent)', color: 'var(--accent)' } : {}}>{m.title} · {m.status}</span>)}</div>
        <div style={{ fontSize: 12.5, color: 'var(--fg-subtle)', marginTop: 8 }}>Preview modules describe what they will do; nothing in them is computed. The Lojo team enables modules per organization.</div>
      </div>
      {flash && <div className="flash good">{flash}</div>}
      {canEdit && <button className="app-btn primary" onClick={save}>Save</button>}
      {ctx.view === 'impl' && <div className="mono" style={{ fontSize: 11, color: 'var(--fg-subtle)', marginTop: 14 }}>org {org.id} · created {shortDate(org.created_at)} · your role {ctx.role || 'none'} · flags {ctx.flags.join(', ') || 'none'}</div>}
    </div>);
}

function Members({ ctx }) {
  const [d, error, reload] = useLojo(ctx, { module: 'org', action: 'members' });
  const [f, setF] = React.useState({ email: '', role: 'viewer', hr: false });
  const [flash, setFlash] = React.useState('');
  const canManage = !ctx.readOnly && ['owner', 'admin', 'operator'].includes(ctx.role);
  if (error) return <div className="empty">{error}</div>;
  if (!d) return <div style={{ color: 'var(--fg-subtle)' }}>Loading…</div>;
  const invite = async () => { const x = await lojo(ctx.token, { module: 'org', action: 'invite', org: ctx.org, email: f.email, role: f.role, flags: f.hr ? ['hr_restricted'] : [] }); setFlash(x.ok ? (x.member ? 'Added as a member.' : x.message) : (x.message || 'Could not invite')); if (x.ok) setF({ email: '', role: 'viewer', hr: false }); reload(); };
  const setRole = async (m, role, flags) => { const x = await lojo(ctx.token, { module: 'org', action: 'set-role', org: ctx.org, user_id: m.user_id, role, flags }); if (!x.ok) setFlash(x.message || 'Not changed'); reload(); };
  const remove = async (m) => { if (!window.confirm(`Remove ${m.name || m.email}?`)) return; const x = await lojo(ctx.token, { module: 'org', action: 'remove', org: ctx.org, user_id: m.user_id }); if (!x.ok) setFlash(x.message || 'Not removed'); reload(); };
  return (
    <div style={{ maxWidth: 860 }}>
      <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginBottom: 12 }}>Owners and admins manage members and approve opportunities; editors change the inventory, assessments and roadmap; viewers read. The HR flag is separate from the role: only members with it can see restricted (HR and compensation) data, whatever their role.</div>
      {flash && <div className="flash good">{flash}</div>}
      <table className="app-table"><thead><tr><th>Member</th><th>Role</th><th>HR flag</th><th>Joined</th><th></th></tr></thead><tbody>
        {d.members.map((m) => <tr key={m.id}><td><div style={{ fontWeight: 600 }}>{m.name || '—'}</div><div style={{ fontSize: 12.5, color: 'var(--fg-muted)' }}>{m.email}</div></td>
          <td>{canManage ? <Select value={m.role} onChange={(v) => setRole(m, v, m.flags || [])} options={['owner', 'admin', 'editor', 'viewer']} style={{ width: 120 }} /> : <Pill tone="accent">{m.role}</Pill>}</td>
          <td>{canManage ? <input type="checkbox" checked={(m.flags || []).includes('hr_restricted')} onChange={(e) => setRole(m, m.role, e.target.checked ? ['hr_restricted'] : [])} /> : ((m.flags || []).includes('hr_restricted') ? 'yes' : '—')}</td>
          <td className="mono" style={{ fontSize: 12 }}>{shortDate(m.joined_at)}</td><td>{canManage && <button className="app-btn small danger" onClick={() => remove(m)}>Remove</button>}</td></tr>)}
        {d.invites.map((i) => <tr key={i.id}><td><div style={{ fontWeight: 600, color: 'var(--fg-muted)' }}>Invited</div><div style={{ fontSize: 12.5, color: 'var(--fg-muted)' }}>{i.email}</div></td><td><Pill tone="fg-subtle">{i.role}</Pill></td><td>{(i.flags || []).includes('hr_restricted') ? 'yes' : '—'}</td><td className="mono" style={{ fontSize: 12 }}>pending</td><td></td></tr>)}
      </tbody></table>
      {canManage && <div className="app-panel" style={{ marginTop: 16 }}><h3>Invite someone</h3>
        <div className="app-grid cols-3">
          <Field label="Work email"><Input type="email" value={f.email} onChange={(e) => setF({ ...f, email: e.target.value })} /></Field>
          <Field label="Role"><Select value={f.role} onChange={(v) => setF({ ...f, role: v })} options={['admin', 'editor', 'viewer']} /></Field>
          <Group label="Restricted (HR) data"><label style={{ display: 'flex', gap: 8, alignItems: 'center', fontSize: 13.5, paddingTop: 8 }}><input type="checkbox" checked={f.hr} onChange={(e) => setF({ ...f, hr: e.target.checked })} /> may see it</label></Group>
        </div>
        <button className="app-btn primary" onClick={invite} disabled={!f.email}>Invite</button>
        <div style={{ fontSize: 12, color: 'var(--fg-subtle)', marginTop: 8 }}>An existing Lojo user is added at once; anyone else becomes a member when they sign up with this email.</div></div>}
    </div>);
}

function LinkedReports({ ctx }) {
  const [slug, setSlug] = React.useState('');
  const [flash, setFlash] = React.useState('');
  const linked = ctx.orgData.linked_reports || [];
  const canEdit = !ctx.readOnly && ['owner', 'admin', 'operator'].includes(ctx.role);
  const link = async (action, s) => { const d = await lojo(ctx.token, { module: 'org', action, org: ctx.org, slug: s }); setFlash(d.ok ? 'Updated.' : (d.message || 'No report with that id')); if (d.ok) { setSlug(''); ctx.reload(); } };
  return (
    <div style={{ maxWidth: 760 }}>
      <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginBottom: 12 }}>The AI visibility reports Lojo has run for this organization. Linking keeps them in one place; the report page itself still opens with its access code. The report id is the <span className="mono">c=</span> part of its link.</div>
      {linked.length === 0 ? <div className="empty">No reports linked yet.</div> :
      <table className="app-table"><thead><tr><th>Report</th><th>Domain</th><th>Full report</th><th></th></tr></thead><tbody>
        {linked.map((r) => <tr key={r.slug}><td><a href={r.url} target="_blank" rel="noreferrer" style={{ color: 'var(--accent)', fontWeight: 600 }}>{r.client || r.slug}</a></td><td style={{ color: 'var(--fg-muted)' }}>{r.domain}</td><td><Pill tone={r.full_status === 'ready' ? 'good' : 'fg-subtle'}>{r.full_status}</Pill></td><td>{canEdit && <button className="app-btn small" onClick={() => link('unlink-report', r.slug)}>Unlink</button>}</td></tr>)}
      </tbody></table>}
      {canEdit && <div style={{ display: 'flex', gap: 8, marginTop: 14, alignItems: 'flex-end' }}><Field label="Report id (from /r/?c=…)"><Input value={slug} onChange={(e) => setSlug(e.target.value)} placeholder="e.g. stetco" /></Field><button className="app-btn" style={{ marginBottom: 12 }} onClick={() => link('link-report', slug)} disabled={!slug}>Link</button></div>}
      {flash && <div className="flash good">{flash}</div>}
      <div style={{ marginTop: 10 }}><a href="/" style={{ color: 'var(--accent)', fontSize: 13.5 }}>Run a free AI visibility report →</a></div>
    </div>);
}

function AuditLog({ ctx }) {
  const [d, error] = useLojo(ctx, { module: 'org', action: 'audit', limit: 200 });
  if (error) return <div className="empty">{error}</div>;
  if (!d) return <div style={{ color: 'var(--fg-subtle)' }}>Loading…</div>;
  return (
    <div>
      <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginBottom: 12 }}>Every change, by whom and why, newest first. Reads of restricted data are logged too. Append-only.</div>
      <div className="app-table-wrap"><table className="app-table"><thead><tr><th>When</th><th>Who</th><th>Action</th><th>Resource</th><th>Reason</th>{ctx.view === 'impl' && <th>Change</th>}</tr></thead><tbody>
        {d.audit.map((e) => <tr key={e.id}><td className="mono" style={{ fontSize: 11.5, whiteSpace: 'nowrap' }}>{String(e.at).slice(0, 16).replace('T', ' ')}</td><td style={{ fontSize: 13 }}>{(e.actor || {}).name || (e.actor || {}).id || (e.actor || {}).type}<div style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>{(e.actor || {}).type}</div></td>
          <td className="mono" style={{ fontSize: 12 }}>{e.action}</td><td className="mono" style={{ fontSize: 11.5, color: 'var(--fg-muted)' }}>{(e.resource || {}).type}/{String((e.resource || {}).id || '').slice(0, 18)}</td><td style={{ fontSize: 12.5, color: 'var(--fg-muted)' }}>{e.reason}</td>
          {ctx.view === 'impl' && <td className="mono" style={{ fontSize: 10.5, color: 'var(--fg-subtle)', maxWidth: 320, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.after ? Object.entries(e.after).filter(([k, v]) => !e.before || e.before[k] !== v).map(([k, v]) => `${k}: ${v}`).join(' · ') : ''}</td>}</tr>)}
      </tbody></table></div>
    </div>);
}

function Restricted({ ctx }) {
  const [d, error, reload] = useLojo(ctx, { module: 'restricted', action: 'notes' });
  const [edit, setEdit] = React.useState(null);
  if (error) return <div className="empty">{error}</div>;
  if (!d) return <div style={{ color: 'var(--fg-subtle)' }}>Loading…</div>;
  const fields = [['title', 'Title', 'text'], ['category', 'Category', 'select', ['hr', 'compensation', 'contract', 'legal', 'other']], ['body', 'Body', 'textarea']];
  return (
    <div>
      <div className="flash warn" style={{ marginBottom: 12 }}>Restricted store: encrypted at rest, visible only to members with the HR flag, every read logged. Nothing here feeds recommendations or AI explanations, and Lojo never makes individual employment decisions from it.</div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 10 }}>{!ctx.readOnly && <button className="app-btn primary" onClick={() => setEdit({})}>Add a note</button>}</div>
      {d.notes.length === 0 ? <div className="empty">Nothing stored.</div> :
      <table className="app-table"><thead><tr><th>Title</th><th>Category</th><th>Updated</th></tr></thead><tbody>
        {d.notes.map((n) => <tr key={n.id} className="clickable" onClick={() => setEdit(n)}><td style={{ fontWeight: 600 }}>{n.title}</td><td>{n.category}</td><td className="mono" style={{ fontSize: 12 }}>{shortDate(n.updated_at)}</td></tr>)}
      </tbody></table>}
      {edit && <RestrictedDrawer ctx={ctx} record={edit} fields={fields} onClose={() => { setEdit(null); reload(); }} />}
    </div>);
}

function RestrictedDrawer({ ctx, record, fields, onClose }) {
  const [f, setF] = React.useState({ title: record.title || '', category: record.category || 'hr', body: record.body || '' });
  const [error, setError] = React.useState('');
  const save = async () => { const d = await lojo(ctx.token, { module: 'restricted', action: 'note-save', org: ctx.org, id: record.id, ...f }); if (!d.ok) { setError(d.message || 'Not saved'); return; } onClose(); };
  const del = async () => { if (!window.confirm('Delete this note?')) return; await lojo(ctx.token, { module: 'restricted', action: 'note-delete', org: ctx.org, id: record.id }); onClose(); };
  return <Drawer title={record.id ? record.title : 'New restricted note'} onClose={onClose} width={560}>
    <Field label="Title"><Input value={f.title} onChange={(e) => setF({ ...f, title: e.target.value })} /></Field>
    <Field label="Category"><Select value={f.category} onChange={(v) => setF({ ...f, category: v })} options={['hr', 'compensation', 'contract', 'legal', 'other']} /></Field>
    <Field label="Body"><textarea className="app-input" rows={8} value={f.body} onChange={(e) => setF({ ...f, body: e.target.value })} /></Field>
    {error && <div className="flash warn">{error}</div>}
    <div style={{ display: 'flex', gap: 8 }}><button className="app-btn primary" onClick={save} disabled={!f.title}>Save</button>{record.id && <button className="app-btn danger" onClick={del}>Delete</button>}</div>
  </Drawer>;
}

function DataPanel({ ctx }) {
  const [flash, setFlash] = React.useState('');
  const [confirm, setConfirm] = React.useState('');
  const canAdmin = !ctx.readOnly && ['owner', 'admin', 'operator'].includes(ctx.role);
  const isOwner = !ctx.readOnly && ['owner', 'operator'].includes(ctx.role);
  const exportAll = async () => { const d = await lojo(ctx.token, { module: 'org', action: 'export', org: ctx.org, include_restricted: ctx.flags.includes('hr_restricted') }); if (!d.ok) { setFlash(d.message || 'Could not export'); return; } downloadText(`lojo-${ctx.org}-export.json`, JSON.stringify(d.export, null, 2), 'application/json'); };
  const del = async () => { const d = await lojo(ctx.token, { module: 'org', action: 'delete', org: ctx.org, confirm, reason: 'deleted from the workspace' }); if (!d.ok) { setFlash(d.message || 'Not deleted'); return; } window.location.assign('/app/'); };
  return (
    <div style={{ maxWidth: 720 }}>
      <div className="app-panel" style={{ marginBottom: 14 }}>
        <h3>Export</h3>
        <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginBottom: 10 }}>Everything in this organization as one JSON file: records, versions are not included, the audit log is. Restricted notes are included only for members with the HR flag. The export itself is logged.</div>
        {canAdmin && <button className="app-btn" onClick={exportAll}>Download export</button>}
      </div>
      <div className="app-panel" style={{ marginBottom: 14 }}>
        <h3>Retention</h3>
        <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6 }}>Data stays until the organization is deleted. Evidence files are kept with their hash so a finding can always be checked against what was uploaded. A per-organization retention period is a setting the Lojo team applies on request.</div>
      </div>
      {isOwner && <div className="app-panel" style={{ borderColor: 'color-mix(in oklab, var(--crit) 40%, transparent)' }}>
        <h3 style={{ color: 'var(--crit)' }}>Delete this organization</h3>
        <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginBottom: 10 }}>Removes every record, evidence file, version and audit entry under it, and every member's access. There is no undo. Type <span className="mono">{ctx.org}</span> to confirm.</div>
        <div style={{ display: 'flex', gap: 8 }}><Input value={confirm} onChange={(e) => setConfirm(e.target.value)} style={{ maxWidth: 260 }} /><button className="app-btn danger" disabled={confirm !== ctx.org} onClick={del}>Delete permanently</button></div>
      </div>}
      {flash && <div className="flash warn" style={{ marginTop: 10 }}>{flash}</div>}
    </div>);
}

Object.assign(window, { OrgModule });
