// admin-sheets.jsx — Modal sheets for admin write actions (PRODUCTION)
// All sheets share a right-side panel shell and call real API endpoints.

function SheetShell({ theme, title, subtitle, onClose, children, footer }) {
  return (
    <>
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, background: 'rgba(8,18,40,0.45)',
        zIndex: 200,
      }}/>
      <div style={{
        position: 'fixed', top: 0, right: 0, bottom: 0,
        width: 'min(520px, 96vw)',
        background: theme.canvas, zIndex: 201,
        display: 'flex', flexDirection: 'column',
        boxShadow: '-20px 0 60px rgba(0,0,0,0.25)',
      }}>
        <div style={{
          padding: '18px 24px 14px',
          borderBottom: `1px solid ${theme.rule}`,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          background: theme.raised,
        }}>
          <div>
            <div style={{ fontSize: 10, color: theme.inkMute, fontWeight: 600, letterSpacing: 1.6, textTransform: 'uppercase' }}>{subtitle || 'Action'}</div>
            <h2 className="serif" style={{ fontSize: 22, fontWeight: 500, color: theme.ink, margin: '4px 0 0', letterSpacing: -0.3, lineHeight: 1.1 }}>{title}</h2>
          </div>
          <button onClick={onClose} style={{
            width: 32, height: 32, borderRadius: 8,
            background: theme.canvas2, border: `1px solid ${theme.rule}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}><Icon name="x" size={14} color={theme.ink}/></button>
        </div>
        <div className="scroll" style={{ flex: 1, overflowY: 'auto', padding: '20px 24px 24px' }}>
          {children}
        </div>
        {footer && (
          <div style={{
            padding: '14px 24px',
            borderTop: `1px solid ${theme.rule}`,
            background: theme.raised,
            display: 'flex', gap: 10, justifyContent: 'flex-end',
          }}>{footer}</div>
        )}
      </div>
    </>
  );
}

// ─────────────────────────────────────────────────────────────
// Form primitives
// ─────────────────────────────────────────────────────────────
function Field({ label, hint, children }) {
  return (
    <div style={{ marginBottom: 16 }}>
      <label style={{ display: 'block', fontSize: 11, fontWeight: 600, letterSpacing: 0.7, textTransform: 'uppercase', color: '#7A88A6', marginBottom: 6 }}>
        {label}
      </label>
      {children}
      {hint && <div style={{ fontSize: 11.5, color: '#7A88A6', marginTop: 5 }}>{hint}</div>}
    </div>
  );
}

function TextInput({ theme, value, onChange, placeholder, mono, type = 'text' }) {
  return (
    <input
      type={type}
      value={value || ''} onChange={e => onChange(e.target.value)}
      placeholder={placeholder}
      style={{
        width: '100%', padding: '10px 12px',
        background: theme.raised, border: `1px solid ${theme.rule}`,
        borderRadius: 9, fontSize: 13.5, color: theme.ink,
        fontFamily: mono ? 'JetBrains Mono, monospace' : 'inherit',
        outline: 'none',
      }}
      onFocus={e => e.target.style.borderColor = theme.surface}
      onBlur={e => e.target.style.borderColor = theme.rule}
    />
  );
}

function TextArea({ theme, value, onChange, placeholder, rows = 4 }) {
  return (
    <textarea
      value={value || ''} onChange={e => onChange(e.target.value)}
      placeholder={placeholder}
      rows={rows}
      style={{
        width: '100%', padding: '10px 12px',
        background: theme.raised, border: `1px solid ${theme.rule}`,
        borderRadius: 9, fontSize: 13.5, color: theme.ink,
        fontFamily: 'inherit', resize: 'vertical',
        outline: 'none', lineHeight: 1.45,
      }}
      onFocus={e => e.target.style.borderColor = theme.surface}
      onBlur={e => e.target.style.borderColor = theme.rule}
    />
  );
}

function Select({ theme, value, onChange, options }) {
  return (
    <select
      value={value} onChange={e => onChange(e.target.value)}
      style={{
        width: '100%', padding: '10px 12px',
        background: theme.raised, border: `1px solid ${theme.rule}`,
        borderRadius: 9, fontSize: 13.5, color: theme.ink,
        outline: 'none', appearance: 'none',
        backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23667' stroke-width='2'><path d='M5 9l7 7 7-7'/></svg>")`,
        backgroundRepeat: 'no-repeat', backgroundPosition: 'right 12px center', backgroundSize: 14,
        paddingRight: 36,
      }}
    >
      {options.map(o => (
        <option key={o.value || o} value={o.value || o}>{o.label || o}</option>
      ))}
    </select>
  );
}

function PillSegment({ theme, value, onChange, options }) {
  return (
    <div style={{
      display: 'inline-flex', gap: 0,
      background: theme.canvas2, border: `1px solid ${theme.rule}`,
      borderRadius: 9, padding: 2,
    }}>
      {options.map(o => (
        <button key={o.value} onClick={() => onChange(o.value)} style={{
          padding: '7px 14px', borderRadius: 7,
          fontSize: 12.5, fontWeight: 600,
          background: value === o.value ? theme.surface : 'transparent',
          color:      value === o.value ? theme.onSurface : theme.inkDim,
        }}>{o.label}</button>
      ))}
    </div>
  );
}

function VisibilityToggle({ theme, value, onChange }) {
  const options = [
    { value: 'public',   label: 'Internal + Client', icon: 'eye',  hint: "Posted to the client's casefile" },
    { value: 'internal', label: 'Internal only',     icon: 'lock', hint: 'Hidden from client; visible to team' },
  ];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      {options.map(o => {
        const selected = value === o.value;
        return (
          <button key={o.value} onClick={() => onChange(o.value)} style={{
            display: 'flex', alignItems: 'center', gap: 12,
            padding: '12px 14px', borderRadius: 10,
            background: selected ? (o.value === 'internal' ? '#FAF6EC' : '#EAF1FB') : '#FFFFFF',
            border: selected ? `2px solid ${o.value === 'internal' ? '#D9B262' : '#4A85E0'}` : `1px solid ${theme.rule}`,
            textAlign: 'left', width: '100%',
            margin: 0, marginLeft: selected ? -1 : 0, cursor: 'pointer',
          }}>
            <div style={{
              width: 32, height: 32, borderRadius: 99, flexShrink: 0,
              background: o.value === 'internal' ? '#F0DDB2' : '#D9E5F4',
              color: o.value === 'internal' ? '#7A5A1B' : '#1F4A8B',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}><Icon name={o.icon} size={14} color={o.value === 'internal' ? '#7A5A1B' : '#1F4A8B'}/></div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13.5, fontWeight: 600, color: theme.ink }}>{o.label}</div>
              <div style={{ fontSize: 11.5, color: theme.inkMute, marginTop: 2 }}>{o.hint}</div>
            </div>
            {selected && <Icon name="check" size={16} color={o.value === 'internal' ? '#7A5A1B' : '#1F4A8B'} strokeWidth={2.5}/>}
          </button>
        );
      })}
    </div>
  );
}

// Error banner
function SheetError({ msg }) {
  if (!msg) return null;
  return (
    <div style={{
      marginBottom: 16, padding: '10px 14px',
      background: '#FEF2F2', border: '1px solid #FECACA',
      borderRadius: 8, fontSize: 13, color: '#DC2626',
    }}>{msg}</div>
  );
}

// ─────────────────────────────────────────────────────────────
// 1) ADD EVENT
// ─────────────────────────────────────────────────────────────
function AddEventSheet({ theme, client, onClose }) {
  const [type, setType]             = React.useState('negotiation');
  const [title, setTitle]           = React.useState('');
  const [body, setBody]             = React.useState('');
  const [amount, setAmount]         = React.useState('');
  const [relatedLender, setLender]  = React.useState('');
  const [visibility, setVisibility] = React.useState('public');
  const [loading, setLoading]       = React.useState(false);
  const [error, setError]           = React.useState('');

  const lenders = lendersForClient(client.id);

  const submit = async () => {
    if (!title.trim()) { setError('Title is required.'); return; }
    setLoading(true); setError('');
    try {
      const amt = amount ? Math.round(parseFloat(amount.replace(/[^0-9.]/g, '')) * 100) : null;
      await api.admin.createEvent(client.id, {
        type, title: title.trim(), body: body.trim() || null,
        amount: amt, lender_id: relatedLender || null, visibility,
      });
      onClose(true);
    } catch (e) {
      setError(e.message || 'Failed to post event.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Add casefile event" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Posting…' : 'Post event'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <Field label="Event type">
        <PillSegment theme={theme} value={type} onChange={setType} options={[
          { value: 'negotiation', label: 'Negotiation' },
          { value: 'offer',       label: 'Offer' },
          { value: 'settled',     label: 'Settled' },
          { value: 'message',     label: 'Note' },
          { value: 'document',    label: 'Document' },
        ]}/>
      </Field>

      <Field label="Related lender (optional)">
        <Select theme={theme} value={relatedLender} onChange={setLender} options={[
          { value: '', label: '— No lender association —' },
          ...lenders.map(l => ({ value: l.id, label: l.name })),
        ]}/>
      </Field>

      <Field label="Title" hint="Shown as the headline in the casefile.">
        <TextInput theme={theme} value={title} onChange={setTitle} placeholder="e.g. Kanon Funding underwriter assigned"/>
      </Field>

      <Field label="Detail">
        <TextArea theme={theme} value={body} onChange={setBody} rows={5} placeholder="What happened, next steps, expectations…"/>
      </Field>

      {(type === 'offer' || type === 'settled') && (
        <Field label="Amount" hint="Settlement / offer amount in USD.">
          <TextInput theme={theme} value={amount} onChange={setAmount} placeholder="$0" mono/>
        </Field>
      )}

      <div style={{ marginTop: 22, paddingTop: 18, borderTop: `1px dashed ${theme.rule}` }}>
        <Field label="Visibility" hint="You can change this later. Internal notes never appear on the client's app.">
          <VisibilityToggle theme={theme} value={visibility} onChange={setVisibility}/>
        </Field>
      </div>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 2) UPLOAD DOCUMENT
// ─────────────────────────────────────────────────────────────
function UploadDocSheet({ theme, client, onClose }) {
  const [file, setFile]             = React.useState(null);
  const [folder, setFolder]         = React.useState('Settlement Agreements');
  const [tag, setTag]               = React.useState('');
  const [visibility, setVisibility] = React.useState('public');
  const [notify, setNotify]         = React.useState(true);
  const [loading, setLoading]       = React.useState(false);
  const [error, setError]           = React.useState('');

  const submit = async () => {
    if (!file) { setError('Please select a file.'); return; }
    setLoading(true); setError('');
    try {
      await api.admin.uploadDocument(client.id, file, { folder, tag: tag || null, visibility });
      onClose(true);
    } catch (e) {
      setError(e.message || 'Upload failed.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Upload document" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading || !file} style={btn(theme, 'primary')}>{loading ? 'Uploading…' : 'Upload'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <Field label="File">
        <label htmlFor="dl-file-pick" style={{
          display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
          padding: '32px 24px', borderRadius: 12,
          background: theme.raised, border: `2px dashed ${theme.rule}`,
          cursor: 'pointer',
        }}>
          <Icon name="upload" size={20} color={theme.inkDim}/>
          <div style={{ fontSize: 13, fontWeight: 600, color: theme.ink }}>
            {file ? file.name : 'Drag PDF here or click to browse'}
          </div>
          <div style={{ fontSize: 11, color: theme.inkMute }}>PDF up to 25 MB</div>
          <input
            id="dl-file-pick" type="file" accept=".pdf" hidden
            onChange={e => setFile(e.target.files[0])}
          />
        </label>
      </Field>

      <Field label="Folder">
        <Select theme={theme} value={folder} onChange={setFolder} options={[
          'Settlement Agreements', 'Statements', 'ID & Compliance', 'Internal Notes',
        ]}/>
      </Field>

      <Field label="Tag (optional)">
        <Select theme={theme} value={tag} onChange={setTag} options={[
          { value: '', label: '— None —' },
          'Signed', 'Submitted', 'Draft', 'Countersigned', 'Hardship', 'Internal',
        ]}/>
      </Field>

      <div style={{ marginTop: 22, paddingTop: 18, borderTop: `1px dashed ${theme.rule}` }}>
        <Field label="Visibility" hint="Internal documents stay in your team's vault.">
          <VisibilityToggle theme={theme} value={visibility} onChange={setVisibility}/>
        </Field>
      </div>

      {visibility === 'public' && (
        <label style={{
          display: 'flex', alignItems: 'center', gap: 10,
          padding: '12px 14px', borderRadius: 10,
          background: theme.canvas2, border: `1px solid ${theme.rule}`,
          marginTop: 6, cursor: 'pointer',
        }}>
          <input type="checkbox" checked={notify} onChange={e => setNotify(e.target.checked)} style={{ accentColor: theme.surface, width: 15, height: 15 }}/>
          <div>
            <div style={{ fontSize: 13, fontWeight: 600, color: theme.ink }}>Notify client</div>
            <div style={{ fontSize: 11.5, color: theme.inkMute, marginTop: 2 }}>Send a push + email when this is uploaded.</div>
          </div>
        </label>
      )}
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 3) LOG OFFER (update lender status)
// ─────────────────────────────────────────────────────────────
function LogOfferSheet({ theme, client, onClose }) {
  const lenders = lendersForClient(client.id);
  const [lenderId, setLenderId] = React.useState(lenders[0]?.id || '');
  const [amount, setAmount]     = React.useState('');
  const [kind, setKind]         = React.useState('lump');
  const [status, setStatus]     = React.useState('Offer Received');
  const [expires, setExpires]   = React.useState('');
  const [note, setNote]         = React.useState('');
  const [visibility, setVis]    = React.useState('public');
  const [loading, setLoading]   = React.useState(false);
  const [error, setError]       = React.useState('');

  const lender = lenders.find(l => l.id === lenderId);
  const balance = lender?.balance || 0;
  const amt = parseFloat(amount.replace(/[^0-9.]/g, '')) || 0;
  const discount = balance > 0 ? Math.max(0, Math.round(100 - (amt / balance) * 100)) : 0;

  const submit = async () => {
    if (!lenderId) { setError('Select a lender.'); return; }
    setLoading(true); setError('');
    try {
      // Update lender status + settlement amount
      const patch = { status };
      if (amt > 0) patch.settlement_amount = Math.round(amt * 100);
      if (status === 'Settled') patch.signed_date = new Date().toISOString().split('T')[0];
      await api.admin.updateLender(lenderId, patch);

      // Also post an event
      const eventTitle = status === 'Settled'
        ? `${lender.name} settled at $${amt.toLocaleString()} (${discount}% off)`
        : `Offer received from ${lender.name} — $${amt.toLocaleString()}`;
      await api.admin.createEvent(client.id, {
        type: status === 'Settled' ? 'settled' : 'offer',
        title: eventTitle,
        body: note || null,
        amount: amt ? Math.round(amt * 100) : null,
        lender_id: lenderId,
        visibility,
      });

      onClose(true);
    } catch (e) {
      setError(e.message || 'Failed to record offer.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Log lender offer" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Recording…' : 'Record offer'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <Field label="Lender">
        <Select theme={theme} value={lenderId} onChange={setLenderId} options={lenders.map(l => ({ value: l.id, label: l.name }))}/>
      </Field>

      <Field label="Update status to">
        <Select theme={theme} value={status} onChange={setStatus} options={[
          { value: 'Negotiating',    label: 'Negotiating' },
          { value: 'Offer Received', label: 'Offer Received' },
          { value: 'Settled',        label: 'Settled' },
        ]}/>
      </Field>

      <Field label="Offer type">
        <PillSegment theme={theme} value={kind} onChange={setKind} options={[
          { value: 'lump',        label: 'Lump sum' },
          { value: 'installment', label: 'Installments' },
        ]}/>
      </Field>

      <Field label="Settlement amount" hint={amt > 0 && balance > 0 ? `${discount}% discount off $${balance.toLocaleString()} balance` : ''}>
        <TextInput theme={theme} value={amount} onChange={setAmount} placeholder="$0" mono/>
      </Field>

      <Field label="Offer expires">
        <TextInput theme={theme} value={expires} onChange={setExpires} placeholder="e.g. Jun 7, 2026"/>
      </Field>

      <Field label="Negotiation note">
        <TextArea theme={theme} value={note} onChange={setNote} placeholder="Underwriter rationale, leverage points, fallback positions…"/>
      </Field>

      <div style={{ marginTop: 12, paddingTop: 18, borderTop: `1px dashed ${theme.rule}` }}>
        <Field label="Visibility">
          <VisibilityToggle theme={theme} value={visibility} onChange={setVis}/>
        </Field>
      </div>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 4) ADD LENDER (new)
// ─────────────────────────────────────────────────────────────
function AddLenderSheet({ theme, client, onClose }) {
  const [name, setName]           = React.useState('');
  const [shortCode, setShortCode] = React.useState('');
  const [balance, setBalance]     = React.useState('');
  const [status, setStatus]       = React.useState('Contacted');
  const [contact, setContact]     = React.useState('');
  const [phone, setPhone]         = React.useState('');
  const [loading, setLoading]     = React.useState(false);
  const [error, setError]         = React.useState('');

  const submit = async () => {
    if (!name.trim()) { setError('Lender name is required.'); return; }
    if (!balance || parseFloat(balance.replace(/[^0-9.]/g, '')) <= 0) { setError('Balance is required.'); return; }
    setLoading(true); setError('');
    try {
      const balanceCents = Math.round(parseFloat(balance.replace(/[^0-9.]/g, '')) * 100);
      await api.admin.createLender(client.id, {
        name: name.trim(),
        short_code: shortCode.trim() || name.trim().substring(0, 4).toUpperCase(),
        balance_amount: balanceCents,
        status,
        contact_person: contact.trim() || null,
        contact_phone: phone.trim() || null,
      });
      onClose(true);
    } catch (e) {
      setError(e.message || 'Failed to add lender.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Add lender" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Adding…' : 'Add lender'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 120px', gap: 12 }}>
        <Field label="Lender name">
          <TextInput theme={theme} value={name} onChange={v => { setName(v); if (!shortCode) setShortCode(v.substring(0, 4).toUpperCase()); }} placeholder="e.g. Kanon Funding"/>
        </Field>
        <Field label="Short code" hint="4 chars">
          <TextInput theme={theme} value={shortCode} onChange={v => setShortCode(v.toUpperCase().substring(0, 5))} placeholder="KANON" mono/>
        </Field>
      </div>

      <Field label="Current balance" hint="Total amount owed to this lender.">
        <TextInput theme={theme} value={balance} onChange={setBalance} placeholder="$0" mono/>
      </Field>

      <Field label="Status">
        <Select theme={theme} value={status} onChange={setStatus} options={[
          { value: 'Contacted',     label: 'Contacted' },
          { value: 'Negotiating',   label: 'Negotiating' },
          { value: 'Offer Received',label: 'Offer Received' },
          { value: 'Settled',       label: 'Settled' },
        ]}/>
      </Field>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <Field label="Contact person (optional)">
          <TextInput theme={theme} value={contact} onChange={setContact} placeholder="Jane Smith"/>
        </Field>
        <Field label="Contact phone (optional)">
          <TextInput theme={theme} value={phone} onChange={setPhone} placeholder="+1 (555) 555-0100" mono/>
        </Field>
      </div>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 5) EDIT LENDER
// ─────────────────────────────────────────────────────────────
function EditLenderSheet({ theme, client, lender, onClose }) {
  const [name, setName]         = React.useState(lender.name);
  const [balance, setBalance]   = React.useState(String(lender.balance));
  const [status, setStatus]     = React.useState(lender.status);
  const [contact, setContact]   = React.useState(lender.contactPerson || '');
  const [phone, setPhone]       = React.useState(lender.contactPhone || '');
  const [loading, setLoading]   = React.useState(false);
  const [error, setError]       = React.useState('');

  const submit = async () => {
    setLoading(true); setError('');
    try {
      const patch = {
        name: name.trim(),
        status,
        contact_person: contact.trim() || null,
        contact_phone: phone.trim() || null,
      };
      if (balance) patch.balance_amount = Math.round(parseFloat(balance.replace(/[^0-9.]/g, '')) * 100);
      await api.admin.updateLender(lender.id, patch);
      onClose(true);
    } catch (e) {
      setError(e.message || 'Failed to update lender.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Edit lender" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Saving…' : 'Save changes'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <Field label="Lender name">
        <TextInput theme={theme} value={name} onChange={setName} placeholder="Lender name"/>
      </Field>
      <Field label="Current balance">
        <TextInput theme={theme} value={balance} onChange={setBalance} placeholder="$0" mono/>
      </Field>
      <Field label="Status">
        <Select theme={theme} value={status} onChange={setStatus} options={[
          { value: 'Contacted',     label: 'Contacted' },
          { value: 'Negotiating',   label: 'Negotiating' },
          { value: 'Offer Received',label: 'Offer Received' },
          { value: 'Settled',       label: 'Settled' },
        ]}/>
      </Field>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <Field label="Contact person">
          <TextInput theme={theme} value={contact} onChange={setContact} placeholder="Jane Smith"/>
        </Field>
        <Field label="Contact phone">
          <TextInput theme={theme} value={phone} onChange={setPhone} placeholder="+1 (555) 555-0100" mono/>
        </Field>
      </div>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 6) UPDATE PAYMENT
// ─────────────────────────────────────────────────────────────
function UpdatePaymentSheet({ theme, client, onClose }) {
  const [mode, setMode]     = React.useState('schedule');
  const [date, setDate]     = React.useState('');
  const [amount, setAmount] = React.useState(`${client.nextPayment || ''}`);
  const [reason, setReason] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [error, setError]   = React.useState('');

  const submit = async () => {
    setLoading(true); setError('');
    try {
      // Create a new payment entry
      const body = {
        date_scheduled: date || new Date().toISOString().split('T')[0],
        amount: parseFloat(amount.replace(/[^0-9.]/g, '')) || 0,
        status: mode === 'mark' ? 'Posted' : mode === 'fail' ? 'Failed' : 'Scheduled',
        internal_note: reason || null,
      };
      if (mode === 'mark') body.date_settled = new Date().toISOString().split('T')[0];
      await api.admin.createPayment(client.id, body);
      onClose(true);
    } catch (e) {
      setError(e.message || 'Failed to update payment.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Update payment" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Saving…' : 'Save'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <Field label="Action">
        <PillSegment theme={theme} value={mode} onChange={setMode} options={[
          { value: 'schedule', label: 'Schedule' },
          { value: 'amount',   label: 'Change amount' },
          { value: 'mark',     label: 'Mark posted' },
          { value: 'fail',     label: 'Mark failed' },
        ]}/>
      </Field>

      {(mode === 'schedule' || mode === 'mark') && (
        <Field label="Date">
          <TextInput theme={theme} value={date} onChange={setDate} type="date"/>
        </Field>
      )}
      {(mode === 'amount' || mode === 'schedule' || mode === 'mark') && (
        <Field label="Amount">
          <TextInput theme={theme} value={amount} onChange={setAmount} placeholder="$2,450" mono/>
        </Field>
      )}

      <Field label="Reason / internal note">
        <TextArea theme={theme} value={reason} onChange={setReason} placeholder="Why this change? Stays internal."/>
      </Field>

      <div style={{
        marginTop: 10, padding: '11px 13px',
        background: '#FAF6EC', border: '1px solid #E2C77B',
        borderRadius: 9, display: 'flex', alignItems: 'flex-start', gap: 10,
      }}>
        <Icon name="info" size={14} color="#7A5A1B"/>
        <div style={{ fontSize: 11.5, color: '#7A5A1B', lineHeight: 1.5 }}>
          The client will see a "Payment updated" notification, but the internal reason stays in your team's audit log.
        </div>
      </div>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 7) ASSIGN REP
// ─────────────────────────────────────────────────────────────
function AssignRepSheet({ theme, client, onClose }) {
  const [picked, setPicked] = React.useState(client.rep);
  const [loading, setLoading] = React.useState(false);
  const [error, setError]   = React.useState('');

  const submit = async () => {
    if (!picked) return;
    setLoading(true); setError('');
    try {
      await api.admin.updateClient(client.id, { rep_user_id: picked });
      onClose(true);
    } catch (e) {
      setError(e.message || 'Failed to assign rep.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Assign specialist" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Assigning…' : 'Assign'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <div style={{ fontSize: 12.5, color: theme.inkMute, marginBottom: 14 }}>
        Reassigning will move this casefile to the selected specialist's queue.
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {ADMIN_REPS.map(r => {
          const selected = picked === r.id;
          const pto = r.status === 'pto';
          return (
            <button key={r.id} onClick={() => setPicked(r.id)} disabled={pto} style={{
              display: 'flex', alignItems: 'center', gap: 12,
              padding: '12px 14px', borderRadius: 10,
              background: selected ? '#EAF1FB' : theme.raised,
              border: selected ? `2px solid ${theme.surface}` : `1px solid ${theme.rule}`,
              marginLeft: selected ? -1 : 0,
              opacity: pto ? 0.5 : 1,
              textAlign: 'left', cursor: pto ? 'not-allowed' : 'pointer',
            }}>
              <div style={{
                width: 38, height: 38, borderRadius: 99,
                background: `linear-gradient(135deg, ${theme.accent.solid}, ${theme.accent.ink})`,
                color: '#fff', fontSize: 12, fontWeight: 700,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontFamily: 'Newsreader, serif', flexShrink: 0,
              }}>{r.initials}</div>
              <div style={{ flex: 1 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontSize: 13.5, fontWeight: 600, color: theme.ink }}>{r.name}</span>
                  {pto && <span style={{ fontSize: 10, fontWeight: 700, color: '#7A2E11', background: '#F5DFC9', padding: '2px 6px', borderRadius: 99 }}>PTO</span>}
                </div>
                <div style={{ fontSize: 11.5, color: theme.inkMute, marginTop: 2 }}>{r.role}</div>
              </div>
              <div style={{ textAlign: 'right' }}>
                <div className="tnum" style={{ fontSize: 12, fontWeight: 600, color: theme.ink }}>
                  {r.caseload}/{r.capacity}
                </div>
                <div style={{ fontSize: 10, color: theme.inkMute, marginTop: 2 }}>caseload</div>
              </div>
              {selected && <Icon name="check" size={16} color={theme.surface} strokeWidth={2.5}/>}
            </button>
          );
        })}
      </div>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 8) NEW CLIENT (intake)
// ─────────────────────────────────────────────────────────────
function NewClientSheet({ theme, onClose }) {
  const [name, setName]     = React.useState('');
  const [biz, setBiz]       = React.useState('');
  const [email, setEmail]   = React.useState('');
  const [phone, setPhone]   = React.useState('');
  const [estDebt, setDbt]   = React.useState('');
  const [refSrc, setRef]    = React.useState('');
  const [rep, setRep]       = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [error, setError]   = React.useState('');

  const submit = async () => {
    if (!name.trim() || !biz.trim() || !email.trim()) {
      setError('Name, business, and email are required.');
      return;
    }
    setLoading(true); setError('');
    try {
      const res = await api.admin.createClient({
        name: name.trim(),
        business: biz.trim(),
        email: email.trim(),
        phone: phone.trim() || null,
        enrolled_amount: parseFloat(estDebt.replace(/[^0-9.]/g, '')) || 0,
        referral_source_id: refSrc || null,
        rep_user_id: rep || null,
      });
      onClose(res?.id || true);
    } catch (e) {
      setError(e.message || 'Failed to create client.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="New client intake" subtitle="Create casefile" onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Creating…' : 'Create file'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <Field label="Owner name">
          <TextInput theme={theme} value={name} onChange={setName} placeholder="First Last"/>
        </Field>
        <Field label="Business">
          <TextInput theme={theme} value={biz} onChange={setBiz} placeholder="Company name"/>
        </Field>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <Field label="Email">
          <TextInput theme={theme} value={email} onChange={setEmail} placeholder="owner@business.com"/>
        </Field>
        <Field label="Phone">
          <TextInput theme={theme} value={phone} onChange={setPhone} placeholder="+1 (555) 555-0100" mono/>
        </Field>
      </div>
      <Field label="Estimated enrolled debt" hint="Rough figure from discovery call; will be refined.">
        <TextInput theme={theme} value={estDebt} onChange={setDbt} placeholder="$0" mono/>
      </Field>
      <Field label="Referral source">
        <Select theme={theme} value={refSrc} onChange={setRef} options={[
          { value: '', label: '— Direct / no referral —' },
          ...REFERRAL_SOURCES.map(r => ({ value: r.id, label: r.name })),
        ]}/>
      </Field>
      <Field label="Assign intake specialist">
        <Select theme={theme} value={rep} onChange={setRep} options={[
          { value: '', label: '— Assign later —' },
          ...ADMIN_REPS.map(r => ({
            value: r.id, label: `${r.name} — ${r.role}${r.status === 'pto' ? ' (PTO)' : ''}`,
          })),
        ]}/>
      </Field>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 9) EDIT CLIENT
// ─────────────────────────────────────────────────────────────
function EditClientSheet({ theme, client, onClose }) {
  const [status, setStatus]           = React.useState(client.status);
const [refSrc, setRefSrc]           = React.useState(client.referrer || '');
  const [enrolled, setEnrolled]       = React.useState(String(client.enrolled));
  const [settled, setSettled]         = React.useState(String(client.settled));
  const [saved, setSaved]             = React.useState(String(client.saved));
  const [planMonths, setPlanMonths]   = React.useState(String(client.planMonths));
  const [monthsDone, setMonthsDone]   = React.useState(String(client.planMonthsDone));
  const [bankBrand, setBankBrand]     = React.useState(client.bankBrand || '');
  const [bankLast4, setBankLast4]     = React.useState(client.bankLast4 || '');
  const [nextPayment, setNextPayment] = React.useState(String(client.nextPayment || ''));
  const [nextDate, setNextDate]       = React.useState('');
  const [atRisk, setAtRisk]           = React.useState(!!client.flagsAtRisk);
  const [loading, setLoading]         = React.useState(false);
  const [error, setError]             = React.useState('');
const [commissionTotal, setCommissionTotal]       = React.useState(client.commissionTotal > 0 ? String(client.commissionTotal) : '');
  const [commissionPerWire, setCommissionPerWire]   = React.useState(client.commissionPerWire > 0 ? String(client.commissionPerWire) : '');
  const [commissionWires, setCommissionWires]       = React.useState(String(client.commissionWiresPaid || 0));
  const [frequency, setFrequency]                   = React.useState('');
  const [scheduleAmount, setScheduleAmount] = React.useState('');
  const [scheduleStart, setScheduleStart]   = React.useState('');
  const [scheduleCount, setScheduleCount]   = React.useState('');
  const [scheduleDays, setScheduleDays]     = React.useState('14');


  const submit = async () => {
    setLoading(true); setError('');
    try {
      await api.admin.updateClient(client.id, {
        status,
        enrolled_amount: parseFloat(enrolled.replace(/[^0-9.]/g, '')) || 0,
        settled_amount:  parseFloat(settled.replace(/[^0-9.]/g, '')) || 0,
        saved_amount:    parseFloat(saved.replace(/[^0-9.]/g, '')) || 0,
        plan_months:     parseInt(planMonths) || 18,
        plan_months_done: parseInt(monthsDone) || 0,
        bank_brand:      bankBrand.trim() || null,
        bank_last4:      bankLast4.trim() || null,
        next_payment_amount: parseFloat(nextPayment.replace(/[^0-9.]/g, '')) || 0,
        next_payment_date: nextDate || null,
        at_risk: atRisk,
referral_source_id: refSrc || null,
        commission_total:      commissionTotal ? Math.round(parseFloat(commissionTotal.replace(/[^0-9.]/g, '')) * 100) : 0,
        commission_per_wire:   commissionPerWire ? Math.round(parseFloat(commissionPerWire.replace(/[^0-9.]/g, '')) * 100) : 0,
        commission_wires_paid: parseInt(commissionWires) || 0,
      });

if (frequency && scheduleAmount && scheduleStart && scheduleCount) {
        const amt = parseFloat(scheduleAmount.replace(/[^0-9.]/g, ''));
        const count = parseInt(scheduleCount);
        const days = frequency === 'weekly' ? 7 : frequency === 'biweekly' ? 14 : frequency === 'monthly' ? 30 : parseInt(scheduleDays) || 14;
        let date = new Date(scheduleStart);
        for (let i = 0; i < count; i++) {
          await api.admin.createPayment(client.id, {
            date_scheduled: date.toISOString().split('T')[0],
            amount: amt,
            status: 'Scheduled',
          });
          if (frequency === 'monthly') { date.setMonth(date.getMonth() + 1); }
          else { date.setDate(date.getDate() + days); }
        }
      }


      onClose(true);
    } catch (e) {
      setError(e.message || 'Failed to update client.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Edit client details" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading} style={btn(theme, 'primary')}>{loading ? 'Saving…' : 'Save changes'}</button>
      </>}
    >
      <SheetError msg={error}/>

<Field label="Referral source">
        <Select theme={theme} value={refSrc} onChange={setRefSrc} options={[
          { value: '', label: '— Direct / no referral —' },
          ...REFERRAL_SOURCES.map(r => ({ value: r.id, label: r.name })),
        ]}/>
      </Field>

      <Field label="Status">
        <Select theme={theme} value={status} onChange={setStatus} options={[
          { value: 'Intake',    label: 'Intake' },
          { value: 'Active',    label: 'Active' },
          { value: 'Settled',   label: 'Settled' },
          { value: 'Disabled',  label: 'Disabled' },
        ]}/>
      </Field>

      <label style={{
        display: 'flex', alignItems: 'center', gap: 10,
        padding: '12px 14px', borderRadius: 10,
        background: atRisk ? '#FFF8F1' : theme.canvas2,
        border: `1px solid ${atRisk ? '#E2C77B' : theme.rule}`,
        marginBottom: 16, cursor: 'pointer',
      }}>
        <input type="checkbox" checked={atRisk} onChange={e => setAtRisk(e.target.checked)} style={{ accentColor: '#B45309', width: 15, height: 15 }}/>
        <div>
          <div style={{ fontSize: 13, fontWeight: 600, color: theme.ink }}>Flag as at-risk</div>
          <div style={{ fontSize: 11.5, color: theme.inkMute, marginTop: 2 }}>Shows a warning badge on this casefile.</div>
        </div>
      </label>

      <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 1.4, textTransform: 'uppercase', color: theme.inkMute, marginBottom: 10 }}>Debt amounts</div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginBottom: 16 }}>
        <Field label="Enrolled ($)">
          <TextInput theme={theme} value={enrolled} onChange={setEnrolled} placeholder="0" mono/>
        </Field>
        <Field label="Settled ($)">
          <TextInput theme={theme} value={settled} onChange={setSettled} placeholder="0" mono/>
        </Field>
        <Field label="Saved ($)">
          <TextInput theme={theme} value={saved} onChange={setSaved} placeholder="0" mono/>
        </Field>
      </div>

      <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 1.4, textTransform: 'uppercase', color: theme.inkMute, marginBottom: 10 }}>Plan</div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 16 }}>
        <Field label="Plan months">
          <TextInput theme={theme} value={planMonths} onChange={setPlanMonths} placeholder="18" mono/>
        </Field>
        <Field label="Months completed">
          <TextInput theme={theme} value={monthsDone} onChange={setMonthsDone} placeholder="0" mono/>
        </Field>
      </div>

      <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 1.4, textTransform: 'uppercase', color: theme.inkMute, marginBottom: 10 }}>Payment</div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 16 }}>
        <Field label="Next payment ($)">
          <TextInput theme={theme} value={nextPayment} onChange={setNextPayment} placeholder="0" mono/>
        </Field>
        <Field label="Next payment date">
          <TextInput theme={theme} value={nextDate} onChange={setNextDate} type="date"/>
        </Field>
      </div>

      <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 1.4, textTransform: 'uppercase', color: theme.inkMute, marginBottom: 10 }}>Bank</div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 100px', gap: 12 }}>
        <Field label="Bank name">
          <TextInput theme={theme} value={bankBrand} onChange={setBankBrand} placeholder="Chase Business Plus"/>
        </Field>
        <Field label="Last 4">
          <TextInput theme={theme} value={bankLast4} onChange={setBankLast4} placeholder="5418" mono/>
        </Field>
      </div>
<div style={{ marginTop: 20, paddingTop: 18, borderTop: `1px dashed ${theme.rule}` }}>
        <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 1.4, textTransform: 'uppercase', color: theme.inkMute, marginBottom: 12 }}>Referral commission</div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12, marginBottom: 12 }}>
          <Field label="Total commission ($)">
            <TextInput theme={theme} value={commissionTotal} onChange={setCommissionTotal} placeholder="0" mono/>
          </Field>
          <Field label="Per wire ($)">
            <TextInput theme={theme} value={commissionPerWire} onChange={setCommissionPerWire} placeholder="0" mono/>
          </Field>
          <Field label="Wires paid">
            <TextInput theme={theme} value={commissionWires} onChange={setCommissionWires} placeholder="0" mono/>
          </Field>
        </div>
        {commissionTotal && commissionPerWire && (
          <div style={{ padding: '10px 12px', background: theme.canvas2, border: `1px solid ${theme.rule}`, borderRadius: 9, fontSize: 12, color: theme.inkDim, marginBottom: 12 }}>
            Paid: ${(parseInt(commissionWires) || 0) * (parseFloat(commissionPerWire) || 0)} of ${commissionTotal} total · Remaining: ${Math.max(0, parseFloat(commissionTotal) - (parseInt(commissionWires) || 0) * (parseFloat(commissionPerWire) || 0))}
          </div>
        )}
      </div>
      <div style={{ marginTop: 20, paddingTop: 18, borderTop: `1px dashed ${theme.rule}` }}>
        <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 1.4, textTransform: 'uppercase', color: theme.inkMute, marginBottom: 12 }}>Payment schedule</div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Field label="Frequency">
            <Select theme={theme} value={frequency} onChange={setFrequency} options={[
              { value: '',          label: '— No schedule —' },
              { value: 'weekly',    label: 'Weekly' },
              { value: 'biweekly',  label: 'Bi-weekly' },
              { value: 'monthly',   label: 'Monthly' },
              { value: 'custom',    label: 'Custom (days)' },
            ]}/>
          </Field>
          <Field label="Amount per payment ($)">
            <TextInput theme={theme} value={scheduleAmount} onChange={setScheduleAmount} placeholder="0" mono/>
          </Field>
        </div>
        {frequency && (
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
            <Field label="Start date">
              <TextInput theme={theme} value={scheduleStart} onChange={setScheduleStart} type="date"/>
            </Field>
            <Field label="Number of payments">
              <TextInput theme={theme} value={scheduleCount} onChange={setScheduleCount} placeholder="18" mono/>
            </Field>
            {frequency === 'custom' && (
              <Field label="Every N days">
                <TextInput theme={theme} value={scheduleDays} onChange={setScheduleDays} placeholder="10" mono/>
              </Field>
            )}
          </div>
        )}
        {frequency && (
          <div style={{ padding: '10px 12px', background: theme.canvas2, border: `1px solid ${theme.rule}`, borderRadius: 9, fontSize: 12, color: theme.inkDim }}>
            Will create {scheduleCount || 0} scheduled payments of ${scheduleAmount || 0} starting {scheduleStart || '—'}
          </div>
        )}
      </div>
    </SheetShell>
  );
}

// ─────────────────────────────────────────────────────────────
// 10) DELETE CLIENT confirmation
// ─────────────────────────────────────────────────────────────
function DeleteClientSheet({ theme, client, onClose, onDeleted }) {
  const [confirm, setConfirm] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [error, setError]     = React.useState('');

  const canDelete = confirm.trim().toLowerCase() === client.name.toLowerCase();

  const submit = async () => {
    if (!canDelete) return;
    setLoading(true); setError('');
    try {
      // Disable the client (soft delete via status)
      await api.admin.updateClient(client.id, { status: 'Disabled' });
      onDeleted();
    } catch (e) {
      setError(e.message || 'Failed to disable client.');
      setLoading(false);
    }
  };

  return (
    <SheetShell theme={theme} title="Disable client" subtitle={`${client.name} · ${client.code}`} onClose={() => onClose(false)}
      footer={<>
        <button onClick={() => onClose(false)} style={btn(theme, 'ghost')}>Cancel</button>
        <button onClick={submit} disabled={loading || !canDelete} style={{
          ...btn(theme, 'primary'),
          background: canDelete ? '#DC2626' : theme.inkMute,
          cursor: canDelete ? 'pointer' : 'not-allowed',
        }}>{loading ? 'Disabling…' : 'Disable client'}</button>
      </>}
    >
      <SheetError msg={error}/>
      <div style={{
        padding: '14px', borderRadius: 10,
        background: '#FEF2F2', border: '1px solid #FECACA',
        marginBottom: 20,
      }}>
        <div style={{ fontSize: 13.5, fontWeight: 600, color: '#991B1B' }}>This will disable the client's access.</div>
        <div style={{ fontSize: 12.5, color: '#B91C1C', marginTop: 6, lineHeight: 1.5 }}>
          The client won't be able to log in. All data is preserved and can be restored by changing their status back to Active.
        </div>
      </div>

      <Field label={`Type "${client.name}" to confirm`}>
        <TextInput theme={theme} value={confirm} onChange={setConfirm} placeholder={client.name}/>
      </Field>
    </SheetShell>
  );
}

// shared button style
function btn(theme, kind) {
  if (kind === 'primary') return {
    padding: '10px 18px', borderRadius: 9,
    background: theme.surface, color: theme.onSurface,
    fontSize: 13, fontWeight: 600,
  };
  return {
    padding: '10px 18px', borderRadius: 9,
    background: 'transparent', color: theme.inkDim,
    fontSize: 13, fontWeight: 500,
  };
}

Object.assign(window, {
  SheetShell, Field, TextInput, TextArea, Select, PillSegment, VisibilityToggle,
  AddEventSheet, UploadDocSheet, LogOfferSheet, AddLenderSheet, EditLenderSheet,
  UpdatePaymentSheet, AssignRepSheet, NewClientSheet, EditClientSheet, DeleteClientSheet,
});
