/* ============================================================
   ELECTROMED — Settings & Help
   Company profiles (multi-letterhead), GST, branches, team,
   rate plans, reminders + support
   ============================================================ */
const PERM_MODULES = ['Sales', 'Rentals', 'Workshop', 'Inventory', 'Payments', 'Reports', 'Settings'];
const ROLES = [
  { key: 'Owner',           members: 1, color: 'var(--ok)',       desc: 'Unrestricted — every branch, billing & settings.',
    perms: { Sales: 'Manage', Rentals: 'Manage', Workshop: 'Manage', Inventory: 'Manage', Payments: 'Manage', Reports: 'Manage', Settings: 'Manage' } },
  { key: 'Branch Manager',  members: 1, color: 'var(--info)',     desc: 'Full control of one branch; read-only on settings.',
    perms: { Sales: 'Manage', Rentals: 'Manage', Workshop: 'Manage', Inventory: 'Manage', Payments: 'Manage', Reports: 'View', Settings: 'View' } },
  { key: 'Sales Executive', members: 3, color: 'var(--lime-700)', desc: 'Quotes, sales, sleep bookings & own customers.',
    perms: { Sales: 'Manage', Rentals: 'View', Workshop: 'None', Inventory: 'View', Payments: 'View', Reports: 'None', Settings: 'None' } },
  { key: 'Workshop Tech',   members: 1, color: 'var(--warn)',     desc: 'Job cards, warranty checks & parts movements.',
    perms: { Sales: 'None', Rentals: 'None', Workshop: 'Manage', Inventory: 'Manage', Payments: 'None', Reports: 'None', Settings: 'None' } },
  { key: 'Field & Delivery',members: 1, color: 'var(--ink-2)',    desc: 'Deliveries, installs & rental pickups.',
    perms: { Sales: 'None', Rentals: 'View', Workshop: 'View', Inventory: 'View', Payments: 'None', Reports: 'None', Settings: 'None' } },
];
const roleColor = (k) => (ROLES.find((r) => r.key === k) || { color: 'var(--ink-2)' }).color;

// Maps display module names → backend module names + actions for each permission level
const MOD_MAP = {
  Sales:     { mod: 'sales',     manageActions: ['view','create','edit','delete','approve'] },
  Rentals:   { mod: 'rentals',   manageActions: ['view','create','edit','delete'] },
  Workshop:  { mod: 'workshop',  manageActions: ['view','create','edit','delete'] },
  Inventory: { mod: 'inventory', manageActions: ['view','create','edit','delete','approve'] },
  Payments:  { mod: 'payments',  manageActions: ['view','create','edit'] },
  Reports:   { mod: 'reports',   manageActions: ['view','export','create'] },
  Settings:  { mod: 'settings',  manageActions: ['view','edit'] },
};
const ALL_ACTIONS = ['view','create','edit','delete','approve','export','manage_users','assign_permissions'];


function Settings({ go, branch = 'All' }) {
  const D = window.DATA;
  const isSuperAdmin = api.isSuperAdmin(); // role-based (admin/owner/super_admin)
  const { data: branches } = useBranches();
  const branchName = branch === 'All' ? null
    : ((branches.find(b => String(b.id) === String(branch)) || {}).city
       || (branches.find(b => String(b.id) === String(branch)) || {}).name || branch);
  const SECTIONS = [
    { id: 'company',       label: 'Company Profiles',  icon: Icons.building, adminOnly: true },
    { id: 'branchprofile', label: 'Branch Profile',    icon: Icons.gear },
    { id: 'tax',           label: 'Tax & Invoicing',   icon: Icons.percent, adminOnly: true },
    { id: 'branches',      label: 'Branches',           icon: Icons.pin,     adminOnly: true },
    { id: 'team',       label: 'Team & Roles',       icon: Icons.users, perm: ['users','manage_users'] },
    { id: 'email',      label: 'Email Settings',     icon: Icons.bell,  adminOnly: true },
    { id: 'rates',      label: 'Rental Rate Plans',  icon: Icons.rental },
    { id: 'sleeptests', label: 'Sleep Test Types',   icon: Icons.moon,  adminOnly: true },
    { id: 'reminders',  label: 'Reminders',          icon: Icons.bell },
    { id: 'transmsg',   label: 'Transaction Messages', icon: Icons.phone },
    { id: 'msglogs',    label: 'Message Logs',         icon: Icons.list },
  ].filter(s => {
    if (s.adminOnly && !isSuperAdmin) return false;
    if (s.perm && !window.can(s.perm[0], s.perm[1]) && !isSuperAdmin) return false;
    return true;
  });
  const [sec, setSec] = useState(() => SECTIONS[0]?.id || 'branchprofile');
  const [modal, setModal] = useState(null);   // { type, data }
  const open = (type, data = null) => setModal({ type, data });
  const close = () => setModal(null);

  return (
    <div className="view-enter">
      <PageHead eyebrow="System · Configuration" title="Settings"
        sub="Company letterheads, tax, branches, team and automation — the backbone of the platform." />

      {/* Super admins edit per-branch settings for the branch they're viewing */}
      {isSuperAdmin && (
        <div className="row" style={{ gap: 10, padding: '11px 16px', borderRadius: 12, marginBottom: 16,
          background: branch === 'All' ? 'var(--warn-bg)' : 'var(--surface-2)',
          border: branch === 'All' ? '1px solid var(--warn)' : '1px solid var(--line)' }}>
          <Icons.pin size={16} style={{ color: branch === 'All' ? 'var(--warn)' : 'var(--lime-700)', flexShrink: 0 }} />
          {branch === 'All'
            ? <span className="tiny" style={{ color: 'var(--ink-2)' }}>You're viewing <b>All Branches</b>. Pick a specific branch from the top bar to view or save <b>branch-level</b> settings (Branch Profile, Transaction Messages).</span>
            : <span className="tiny" style={{ color: 'var(--ink-2)' }}>Editing settings for branch: <b>{branchName}</b>. Switch branches in the top bar to manage another branch.</span>}
        </div>
      )}

      <div style={{ display: 'grid', gridTemplateColumns: '232px 1fr', gap: 22, alignItems: 'start' }}>
        <div className="card" style={{ padding: 8, position: 'sticky', top: 0 }}>
          {SECTIONS.map((s) => (
            <button key={s.id} className={cls('nav-item', sec === s.id && 'active')} onClick={() => setSec(s.id)}>
              <s.icon className="nav-ic" />{s.label}
            </button>
          ))}
        </div>
        {/* key on branch → per-branch sections re-fetch when the branch changes */}
        <div key={branch}>
          {sec === 'company'       && <CompanySettings open={open} />}
          {sec === 'branchprofile' && <BranchProfileSettings />}
          {sec === 'tax'           && <TaxSettings />}
          {sec === 'branches'   && <BranchSettings open={open} />}
          {sec === 'team'       && <TeamSettings open={open} />}
          {sec === 'email'      && <EmailSettings />}
          {sec === 'rates'      && <RateSettings />}
          {sec === 'sleeptests' && <SleepTestTypeSettings open={open} />}
          {sec === 'reminders'  && <ReminderSettings />}
          {sec === 'transmsg'   && <TransactionMessageSettings />}
          {sec === 'msglogs'    && <MessageLogSettings />}
        </div>
      </div>
      <SettingsModals modal={modal} close={close} />
    </div>
  );
}

function BranchProfileSettings() {
  const [s, setS]       = useState({});
  const [busy, setBusy] = useState(false);
  const [loading, setLoading] = useState(true);
  const set = (k, v) => setS(p => ({ ...p, [k]: v }));

  useEffect(() => {
    api.getBranchSettings().then(r => { setS(r.settings || {}); setLoading(false); }).catch(() => setLoading(false));
  }, []);

  const save = async () => {
    setBusy(true);
    try {
      await api.updateBranchSettings(s);
      window.toast('Branch profile saved', 'ok');
    } catch (err) {
      window.toast(err.message || 'Failed to save', 'error');
    } finally { setBusy(false); }
  };

  if (loading) return <div className="card card-pad tiny muted">Loading branch profile…</div>;

  return (
    <div>
      <SecHead title="Branch Profile" sub="Company identity, contact info, bank details and invoice template for this branch." />

      <div className="card" style={{ padding: 20, display: 'grid', gap: 14, marginBottom: 16 }}>
        <div style={{ fontWeight: 800, fontSize: 13, color: 'var(--ink-3)', letterSpacing: '.06em' }}>COMPANY IDENTITY</div>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Company Name"><input className="input-block" value={s.company_name || ''} onChange={e => set('company_name', e.target.value)} placeholder="Electromed Corporation" /></Fld>
          <Fld label="Tagline"><input className="input-block" value={s.company_tagline || ''} onChange={e => set('company_tagline', e.target.value)} placeholder="Respiratory & Sleep Care" /></Fld>
        </div>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
          <Fld label="NTN"><input className="input-block mono" value={s.company_ntn || ''} onChange={e => set('company_ntn', e.target.value)} placeholder="0000000-0" /></Fld>
          <Fld label="STRN"><input className="input-block mono" value={s.company_strn || ''} onChange={e => set('company_strn', e.target.value)} placeholder="32-77-0000-000-00" /></Fld>
          <Fld label="GST Rate (%)"><input className="input-block mono" value={s.gst_rate ?? ''} onChange={e => set('gst_rate', e.target.value.replace(/[^0-9.]/g, ''))} placeholder="17" /></Fld>
        </div>
      </div>

      <div className="card" style={{ padding: 20, display: 'grid', gap: 14, marginBottom: 16 }}>
        <div style={{ fontWeight: 800, fontSize: 13, color: 'var(--ink-3)', letterSpacing: '.06em' }}>CONTACT</div>
        <Fld label="Address"><textarea className="input-block" rows="2" value={s.address || ''} onChange={e => set('address', e.target.value)} placeholder="Street, area, city" /></Fld>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Phone"><input className="input-block mono" value={s.phone || ''} onChange={e => set('phone', e.target.value)} placeholder="+92 21 …" /></Fld>
          <Fld label="Email"><input className="input-block" type="email" value={s.email || ''} onChange={e => set('email', e.target.value)} placeholder="branch@electromed.pk" /></Fld>
        </div>
      </div>

      <div className="card" style={{ padding: 20, display: 'grid', gap: 14, marginBottom: 16 }}>
        <div style={{ fontWeight: 800, fontSize: 13, color: 'var(--ink-3)', letterSpacing: '.06em' }}>BANK DETAILS</div>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Bank Name"><input className="input-block" value={s.bank_name || ''} onChange={e => set('bank_name', e.target.value)} placeholder="HBL" /></Fld>
          <Fld label="Account Number"><input className="input-block mono" value={s.bank_account || ''} onChange={e => set('bank_account', e.target.value)} placeholder="01234567890" /></Fld>
        </div>
        <Fld label="IBAN"><input className="input-block mono" value={s.bank_iban || ''} onChange={e => set('bank_iban', e.target.value)} placeholder="PK36HABB0000000000000000" /></Fld>
      </div>

      <div className="card" style={{ padding: 20, display: 'grid', gap: 14, marginBottom: 16 }}>
        <div style={{ fontWeight: 800, fontSize: 13, color: 'var(--ink-3)', letterSpacing: '.06em' }}>INVOICE TEMPLATE</div>
        <div className="row" style={{ gap: 10 }}>
          {['standard','minimal','detailed'].map(tpl => (
            <button key={tpl} type="button" onClick={() => set('invoice_template', tpl)} style={{
              padding: '10px 20px', borderRadius: 11, fontWeight: 700, fontSize: 13, cursor: 'pointer',
              border: (s.invoice_template || 'standard') === tpl ? '2px solid var(--lime-700)' : '2px solid var(--line)',
              background: (s.invoice_template || 'standard') === tpl ? 'var(--lime-soft, #e8f8f0)' : 'var(--surface-2)',
              color: (s.invoice_template || 'standard') === tpl ? 'var(--lime-700)' : 'var(--ink-2)',
              textTransform: 'capitalize',
            }}>{tpl}</button>
          ))}
        </div>
        <Fld label="Brand Color">
          <div className="row" style={{ gap: 10 }}>
            {['#16a34a','#1c5a3a','#2f6fd6','#7c3aed','#0d1411'].map(c => (
              <button key={c} type="button" onClick={() => set('brand_color', c)} style={{
                width: 36, height: 36, borderRadius: 10, background: c, cursor: 'pointer',
                border: (s.brand_color || '#16a34a') === c ? '3px solid var(--lime)' : '3px solid transparent',
                display: 'grid', placeItems: 'center',
              }}>
                {(s.brand_color || '#16a34a') === c && <Icons.check size={14} stroke={3} style={{ color: '#fff' }} />}
              </button>
            ))}
          </div>
        </Fld>
      </div>

      <div className="row" style={{ justifyContent: 'flex-end' }}>
        <Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>{busy ? 'Saving…' : 'Save Branch Profile'}</Btn>
      </div>
    </div>
  );
}

function SecHead({ title, sub, action }) {
  return (
    <div className="row" style={{ justifyContent: 'space-between', marginBottom: 16, gap: 14, flexWrap: 'wrap' }}>
      <div><div style={{ fontWeight: 800, fontSize: 19, letterSpacing: '-.02em' }}>{title}</div><div className="tiny muted" style={{ marginTop: 3 }}>{sub}</div></div>
      {action}
    </div>
  );
}

function CompanySettings({ open }) {
  const [companies, setCompanies] = useState([]);
  const [loading, setLoading] = useState(true);

  const load = () => api.getCompanies().then(r => { setCompanies(r.companies || []); setLoading(false); }).catch(() => setLoading(false));
  useEffect(() => { load(); }, []);

  // Expose reload so modal can trigger refresh
  useEffect(() => { window.__reloadCompanies = load; }, []);

  if (loading) return <div className="tiny muted" style={{ padding: 20 }}>Loading…</div>;

  return (
    <div>
      <SecHead title="Company Profiles" sub="Each profile is a letterhead you can invoice under (GST registered)."
        action={<Btn variant="primary" icon={<Icons.plus size={16} stroke={2.6} />} onClick={() => open('company', null)}>Add Company</Btn>} />
      <div style={{ display: 'grid', gap: 16 }}>
        {companies.map((c) => (
          <div key={c.id} className="card">
            <div className="row" style={{ gap: 12, padding: '16px 18px', background: c.color || '#1c5a3a', color: '#fff', borderRadius: 'var(--r-lg) var(--r-lg) 0 0' }}>
              <div style={{ width: 40, height: 40, borderRadius: 11, background: 'rgba(255,255,255,.12)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--lime)" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 12h4l2-6 4 13 3-9 2 2h5" /></svg>
              </div>
              <div className="grow"><div style={{ fontWeight: 800, fontSize: 16 }}>{c.name}</div><div className="tiny" style={{ color: 'rgba(255,255,255,.7)' }}>{c.letterhead}</div></div>
              <Btn variant="ghost" sm style={{ background: 'rgba(255,255,255,.14)', color: '#fff', border: 'none' }} icon={<Icons.gear size={14} />} onClick={() => open('company', c)}>Edit</Btn>
            </div>
            <div className="grid" style={{ gridTemplateColumns: '1fr 1fr 1fr', gap: 0 }}>
              {[['NTN', c.ntn], ['STRN', c.strn], ['GST Rate', (c.gst_rate || c.gstRate || 17) + '%'], ['Phone', c.phone], ['Email', c.email], ['Bank', c.bank]].map(([k, v], ix) => (
                <div key={k} style={{ padding: '12px 16px', borderTop: '1px solid var(--line)', borderRight: (ix % 3 !== 2) ? '1px solid var(--line)' : 'none' }}>
                  <div className="tiny muted" style={{ fontWeight: 700 }}>{k}</div><div className="mono" style={{ fontWeight: 700, marginTop: 2, fontSize: 13 }}>{v || '—'}</div>
                </div>
              ))}
            </div>
            <div className="tiny muted" style={{ padding: '11px 16px', borderTop: '1px solid var(--line)' }}>{c.addr || '—'}</div>
          </div>
        ))}
        {!companies.length && <div className="card card-pad tiny muted">No companies yet. Click "Add Company" to create one.</div>}
      </div>
    </div>
  );
}

function Toggle({ on }) {
  const [v, setV] = useState(on);
  return <button onClick={() => setV(!v)} style={{ width: 42, height: 24, borderRadius: 999, background: v ? 'var(--lime-700)' : 'var(--line-2)', position: 'relative', transition: '.16s', flexShrink: 0 }}><span style={{ position: 'absolute', top: 3, left: v ? 21 : 3, width: 18, height: 18, borderRadius: 50, background: '#fff', transition: '.16s', boxShadow: 'var(--sh-sm)' }} /></button>;
}

function Row({ title, sub, children }) {
  return (
    <div className="row" style={{ justifyContent: 'space-between', padding: '14px 18px', borderBottom: '1px solid var(--line)', gap: 14 }}>
      <div><div style={{ fontWeight: 700 }}>{title}</div>{sub && <div className="tiny muted" style={{ marginTop: 2 }}>{sub}</div>}</div>
      {children}
    </div>
  );
}

function TaxSettings() {
  return (
    <div>
      <SecHead title="Tax & Invoicing" sub="Sales-tax defaults and document numbering." />
      <div className="card" style={{ overflow: 'hidden' }}>
        <Row title="Standard GST rate" sub="Applied to GST tax invoices"><input className="input-block mono" defaultValue="17%" style={{ width: 90, textAlign: 'center' }} /></Row>
        <Row title="Default invoice type" sub="Pre-selected on new sales">
          <div className="tabs"><button className="tab active">GST</button><button className="tab">Non-GST</button></div>
        </Row>
        <Row title="Show tax breakdown on invoice" sub="Display taxable value + GST line"><Toggle on={true} /></Row>
        <Row title="Withholding tax on services" sub="Apply WHT to workshop labour"><Toggle on={false} /></Row>
        <div style={{ padding: 18 }}>
          <div className="tiny muted" style={{ fontWeight: 700, marginBottom: 10 }}>DOCUMENT NUMBERING</div>
          <div className="grid" style={{ gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
            <label className="fld"><span>Invoice prefix</span><input className="input-block mono" defaultValue="INV-24-" /></label>
            <label className="fld"><span>Quotation prefix</span><input className="input-block mono" defaultValue="QT-26-" /></label>
            <label className="fld"><span>Receipt prefix</span><input className="input-block mono" defaultValue="RC-" /></label>
          </div>
        </div>
      </div>
    </div>
  );
}

function BranchSettings({ open }) {
  const [branches,      setBranches]      = useState([]);
  const [loading,       setLoading]       = useState(true);
  const [showDeleted,   setShowDeleted]   = useState(false);
  const [restoringId,   setRestoringId]   = useState(null);
  const isSuperAdmin = api.user?._isSuperAdmin || !api.user?.permissions;

  const load = () => {
    const params = showDeleted ? 'include_inactive=1&include_deleted=1' : '';
    api.getBranches(params)
      .then(r => { setBranches(r.branches || []); setLoading(false); })
      .catch(() => setLoading(false));
  };
  useEffect(() => { load(); }, [showDeleted]);
  useEffect(() => { window.__reloadBranches = load; }, [showDeleted]);

  const restore = async (b) => {
    setRestoringId(b.id);
    try {
      await api.restoreBranch(b.id);
      window.toast(`${b.name} restored`, 'ok');
      load();
    } catch (err) { window.toast(err.message || 'Failed to restore', 'error'); }
    finally { setRestoringId(null); }
  };

  const active   = branches.filter(b => !b.deleted_at);
  const deleted  = branches.filter(b => !!b.deleted_at);

  return (
    <div>
      <SecHead title="Branches" sub="Locations stock, staff and contracts are tracked against."
        action={<div className="row" style={{ gap: 10 }}>
          {isSuperAdmin && (
            <Btn variant="ghost" sm onClick={() => setShowDeleted(v => !v)}>
              {showDeleted ? 'Hide Deleted' : 'Show Deleted'}
            </Btn>
          )}
          <Btn variant="primary" icon={<Icons.plus size={16} stroke={2.6} />} onClick={() => open('branch', null)}>Add Branch</Btn>
        </div>} />
      <div className="card">
        <table className="tbl">
          <thead><tr><th>Branch</th><th>City</th><th>Code</th><th>Manager</th><th>Staff</th><th>Status</th><th></th></tr></thead>
          <tbody>
            {loading ? <tr><td colSpan="7" className="tiny muted" style={{ padding: 20 }}>Loading…</td></tr> :
             !active.length && !deleted.length ? <tr><td colSpan="7" className="tiny muted" style={{ padding: 20 }}>No branches found.</td></tr> :
             active.map((b) => {
               const isActive = (b.status || 'active') === 'active';
               const toggleStatus = async () => {
                 try {
                   await api.updateBranchStatus(b.id, isActive ? 'inactive' : 'active');
                   window.toast(isActive ? 'Branch deactivated' : 'Branch activated', 'ok');
                   load();
                 } catch (err) { window.toast(err.message || 'Failed', 'error'); }
               };
               return (
                <tr key={b.id}>
                  <td><div className="row" style={{ gap: 10 }}><div style={{ width: 34, height: 34, borderRadius: 10, background: 'var(--surface-3)', display: 'grid', placeItems: 'center' }}><Icons.pin size={16} style={{ color: 'var(--ink-2)' }} /></div><span style={{ fontWeight: 700 }}>{b.name}</span></div></td>
                  <td className="muted">{b.city}</td>
                  <td className="mono" style={{ fontSize: 12 }}>{b.code || '—'}</td>
                  <td className="muted">{b.manager || '—'}</td>
                  <td className="mono">{b.staff || 0}</td>
                  <td><span style={{ fontSize: 11.5, fontWeight: 700, padding: '3px 8px', borderRadius: 6, background: isActive ? 'var(--ok-bg, #e8f8f0)' : 'var(--surface-2)', color: isActive ? 'var(--ok)' : 'var(--ink-3)' }}>{isActive ? 'Active' : 'Inactive'}</span></td>
                  <td style={{ textAlign: 'right' }}>
                    <div className="row" style={{ gap: 6, justifyContent: 'flex-end' }}>
                      <Btn variant="ghost" sm onClick={toggleStatus}>{isActive ? 'Deactivate' : 'Activate'}</Btn>
                      <Btn variant="ghost" sm icon={<Icons.gear size={14} />} onClick={() => open('branch', b)}>Edit</Btn>
                    </div>
                  </td>
                </tr>
              );
             })}
            {showDeleted && deleted.map((b) => (
              <tr key={b.id} style={{ opacity: 0.55 }}>
                <td><div className="row" style={{ gap: 10 }}><div style={{ width: 34, height: 34, borderRadius: 10, background: 'var(--bad-bg)', display: 'grid', placeItems: 'center' }}><Icons.trash size={16} style={{ color: 'var(--bad)' }} /></div><span style={{ fontWeight: 700 }}>{b.name}</span></div></td>
                <td className="muted">{b.city}</td>
                <td className="mono" style={{ fontSize: 12 }}>{b.code || '—'}</td>
                <td className="muted">{b.manager || '—'}</td>
                <td className="mono">{b.staff || 0}</td>
                <td><span style={{ fontSize: 11.5, fontWeight: 700, padding: '3px 8px', borderRadius: 6, background: 'var(--bad-bg)', color: 'var(--bad)' }}>Deleted</span></td>
                <td style={{ textAlign: 'right' }}>
                  <Btn variant="ghost" sm icon={<Icons.undo size={14} />}
                    disabled={restoringId === b.id}
                    onClick={() => restore(b)}>
                    {restoringId === b.id ? 'Restoring…' : 'Restore'}
                  </Btn>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function ToggleStatusBtn({ member: m, onDone }) {
  const [busy, setBusy] = React.useState(false);
  const isActive = m.status === 'Active';

  const toggle = async () => {
    const action = isActive ? 'Suspend' : 'Reactivate';
    if (!window.confirm(action + ' ' + m.name + '?')) return;
    setBusy(true);
    try {
      await api.updateUserStatus(m.id, isActive ? 'suspended' : 'active');
      window.toast(m.name + (isActive ? ' suspended' : ' reactivated'), isActive ? 'warn' : 'ok');
      if (onDone) onDone();
    } catch (err) {
      window.toast(err.message || 'Failed', 'error');
    } finally { setBusy(false); }
  };

  return (
    <Btn variant="ghost" sm disabled={busy}
      style={{ color: isActive ? 'var(--warn)' : 'var(--ok)', minWidth: 82 }}
      onClick={toggle}>
      {busy ? '…' : isActive ? 'Suspend' : 'Reactivate'}
    </Btn>
  );
}

function TeamSettings({ open }) {
  const D = window.DATA;
  const [tab, setTab] = useState('Members');
  const { data: users, loading: uLoading, refetch: refetchUsers } = useUsers();
  const { data: invites, refetch: refetchInvites } = useInvites();
  const { data: branches } = useBranches();

  const branchName = React.useCallback((id) => {
    if (!id) return 'All';
    const b = branches.find(x => x.id === id);
    return b ? (b.label || b.city || b.name) : id.slice(0, 8) + '…';
  }, [branches]);

  // Merge DB users + pending invites into one team list
  const currentUserId = api.user ? api.user.id : null;
  const members = users.map(u => ({
    id:        u.id,
    name:      u.name,
    email:     u.email,
    role:      u.display_role || u.role || 'User',
    branch:    branchName(u.branch_id),
    branch_id: u.branch_id || null,
    status:    u.status === 'active' ? 'Active' : u.status,
    init:      (u.name || 'U').split(' ').map(w => w[0]).join('').toUpperCase().slice(0, 2),
    you:       u.id === currentUserId,
    isUser:    true,
  }));
  const pendingInvites = (invites || []).filter(i => i.status === 'pending').map(i => ({
    id:        i.id,
    name:      i.email.split('@')[0],
    email:     i.email,
    role:      i.role || 'Sales Executive',
    branch:    branchName(i.branch_id),
    branch_id: i.branch_id || null,
    status:    'Invited',
    init:      i.email[0].toUpperCase(),
    you:       false,
    isUser:    false,
    inviteId:  i.id,
  }));
  const team = [...members, ...pendingInvites];

  const doRefetch = () => { refetchUsers(); refetchInvites(); };

  return (
    <div>
      <SecHead title="Team & Roles" sub="Platform users, their branch and access role."
        action={<div className="row" style={{ gap: 10 }}>
          <Tabs tabs={['Members', 'Roles']} value={tab} onChange={setTab} />
          {tab === 'Members' && window.can('users','manage_users') && <Btn variant="primary" icon={<Icons.plus size={16} stroke={2.6} />} onClick={() => open('invite', { onDone: doRefetch })}>Invite User</Btn>}
        </div>} />
      {tab === 'Members' ? (
        <div className="card">
          {uLoading ? <div className="card-pad muted tiny" style={{ padding: 24, textAlign: 'center' }}>Loading team…</div> : (
          <table className="tbl">
            <thead><tr><th>User</th><th>Role</th><th>Branch</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {team.map((m) => (
                <tr key={m.email}>
                  <td><div className="row" style={{ gap: 11 }}><div style={{ width: 36, height: 36, borderRadius: 50, background: m.you ? 'var(--grad-green)' : 'var(--surface-3)', color: m.you ? 'var(--lime)' : 'var(--ink-2)', display: 'grid', placeItems: 'center', fontWeight: 800, fontSize: 12.5, opacity: m.status === 'Invited' ? .55 : 1 }}>{m.init}</div><div><div className="row" style={{ gap: 7, fontWeight: 700 }}>{m.name}{m.you && <Badge kind="info">You</Badge>}</div><div className="tiny muted">{m.email}</div></div></div></td>
                  <td><span className="badge" style={{ color: roleColor(m.role), background: 'var(--surface-2)' }}>{m.role}</span></td>
                  <td className="tiny muted">{m.branch}</td>
                  <td><Badge kind={m.status === 'Invited' ? 'warn' : m.status === 'Active' ? 'ok' : 'idle'}>{m.status}</Badge></td>
                  <td style={{ textAlign: 'right' }}>
                    <div className="row" style={{ gap: 6, justifyContent: 'flex-end' }}>
                      {m.isUser && !m.you && window.can('users','edit') && (
                        <ToggleStatusBtn member={m} onDone={doRefetch} />
                      )}
                      {window.can('users','manage_users') && (
                        <Btn variant="ghost" sm icon={<Icons.shield size={14} />} onClick={() => open('access', { ...m, onDone: doRefetch })}>
                          {m.isUser ? 'Access' : 'Revoke'}
                        </Btn>
                      )}
                    </div>
                  </td>
                </tr>
              ))}
              {!team.length && <tr><td colSpan="5" style={{ textAlign: 'center', padding: 28, color: 'var(--ink-3)' }}>No team members yet</td></tr>}
            </tbody>
          </table>
          )}
        </div>
      ) : (
        <div style={{ display: 'grid', gap: 14 }}>
          {ROLES.map((r) => (
            <div key={r.key} className="card card-pad" style={{ cursor: 'pointer' }} onClick={() => open('role', r)}>
              <div className="row" style={{ gap: 13, alignItems: 'flex-start' }}>
                <div style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--surface-2)', display: 'grid', placeItems: 'center', color: r.color, flexShrink: 0 }}><Icons.shield size={19} /></div>
                <div className="grow">
                  <div className="row" style={{ gap: 9 }}><span style={{ fontWeight: 800, fontSize: 15.5 }}>{r.key}</span><span className="tiny muted">· {r.members} {r.members === 1 ? 'user' : 'users'}</span></div>
                  <div className="tiny muted" style={{ marginTop: 3 }}>{r.desc}</div>
                  <div className="row" style={{ gap: 6, marginTop: 10, flexWrap: 'wrap' }}>
                    {PERM_MODULES.map((mod) => (
                      <span key={mod} className="badge" style={{ fontSize: 11, color: r.perms[mod] === 'None' ? 'var(--ink-3)' : r.perms[mod] === 'Manage' ? 'var(--ok)' : 'var(--info)', background: r.perms[mod] === 'None' ? 'var(--surface-2)' : r.perms[mod] === 'Manage' ? 'var(--ok-bg)' : 'var(--info-bg)' }}>{mod} · {r.perms[mod]}</span>
                    ))}
                  </div>
                </div>
                <Icons.chevR size={17} style={{ color: 'var(--ink-3)', flexShrink: 0 }} />
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function EmailSettings() {
  const [user,    setUser]    = useState('');
  const [pass,    setPass]    = useState('');
  const [host,    setHost]    = useState('smtp.gmail.com');
  const [port,    setPort]    = useState('587');
  const [testTo,  setTestTo]  = useState('');
  const [busy,    setBusy]    = useState(false);
  const [testBusy,setTestBusy]= useState(false);
  const [status,  setStatus]  = useState(null); // 'ok'|'error'|null
  const [configured, setConfigured] = useState(false);
  const [showPass, setShowPass] = useState(false);

  useEffect(() => {
    api.getEmailSettings().then(r => {
      setUser(r.smtp_user || '');
      setHost(r.smtp_host || 'smtp.gmail.com');
      setPort(r.smtp_port || '587');
      setConfigured(r.smtp_configured);
    }).catch(() => {});
  }, []);

  const save = async () => {
    if (!user.trim()) { window.toast('Gmail address is required', 'warn'); return; }
    if (!pass.trim()) { window.toast('App Password is required', 'warn'); return; }
    setBusy(true);
    try {
      await api.saveEmailSettings({ smtp_user: user, smtp_pass: pass, smtp_host: host, smtp_port: port });
      setConfigured(true);
      setPass('');
      window.toast('Email settings saved!', 'ok');
      setStatus('ok');
    } catch (err) {
      window.toast(err.message || 'Failed to save', 'error');
      setStatus('error');
    } finally { setBusy(false); }
  };

  const sendTest = async () => {
    const to = testTo.trim() || user.trim();
    if (!to) { window.toast('Enter a recipient email', 'warn'); return; }
    setTestBusy(true);
    try {
      const r = await api.testEmail(to);
      if (r.previewUrl) {
        window.toast('SMTP not set — opening Ethereal preview', 'warn');
        window.open(r.previewUrl);
      } else {
        window.toast('Test email sent to ' + to, 'ok');
      }
    } catch (err) {
      window.toast('Test failed: ' + (err.message || 'unknown error'), 'error');
    } finally { setTestBusy(false); }
  };

  return (
    <div>
      <SecHead title="Email Settings" sub="Configure SMTP so invites are delivered to real inboxes." />

      {/* Status banner */}
      <div className="row" style={{ gap: 12, padding: '14px 18px', background: configured ? 'var(--ok-bg)' : 'var(--warn-bg)', borderRadius: 12, marginBottom: 18, border: `1px solid ${configured ? 'var(--ok)' : 'var(--warn)'}` }}>
        <span style={{ fontSize: 20 }}>{configured ? '✅' : '⚠️'}</span>
        <div>
          <div style={{ fontWeight: 700, color: configured ? 'var(--ok)' : 'var(--warn)' }}>{configured ? 'Email is configured and working' : 'Email not configured — invites show a link only'}</div>
          <div className="tiny muted" style={{ marginTop: 2 }}>{configured ? `Sending from ${user}` : 'Complete the form below to enable real email delivery.'}</div>
        </div>
      </div>

      <div className="card" style={{ overflow: 'hidden', marginBottom: 18 }}>
        {/* Step guide for Gmail */}
        <div style={{ padding: '16px 20px', background: 'var(--surface-2)', borderBottom: '1px solid var(--line)' }}>
          <div style={{ fontWeight: 800, marginBottom: 10 }}>How to get a Gmail App Password (3 steps)</div>
          {[
            ['1', 'Open', 'myaccount.google.com → Security tab'],
            ['2', 'Enable', '2-Step Verification (if not already on)'],
            ['3', 'Search', '"App Passwords" → App = Mail → Generate → Copy the 16-char code'],
          ].map(([n, bold, rest]) => (
            <div key={n} className="row" style={{ gap: 10, padding: '7px 0', borderTop: n !== '1' ? '1px solid var(--line)' : 'none' }}>
              <div style={{ width: 24, height: 24, borderRadius: 50, background: 'var(--lime-700)', color: '#fff', display: 'grid', placeItems: 'center', fontSize: 12, fontWeight: 800, flexShrink: 0 }}>{n}</div>
              <span className="tiny"><b>{bold}</b> {rest}</span>
            </div>
          ))}
          <a href="https://myaccount.google.com/apppasswords" target="_blank" rel="noreferrer"
            style={{ display: 'inline-block', marginTop: 10, padding: '8px 14px', background: 'var(--lime-700)', color: '#fff', borderRadius: 8, fontSize: 13, fontWeight: 700, textDecoration: 'none' }}>
            Open Google App Passwords ↗
          </a>
        </div>

        {/* SMTP Form */}
        <div style={{ padding: '20px 20px', display: 'grid', gap: 14 }}>
          <div className="grid" style={{ gridTemplateColumns: '1fr 100px', gap: 12 }}>
            <Fld label="SMTP Host"><input className="input-block mono" value={host} onChange={e => setHost(e.target.value)} /></Fld>
            <Fld label="Port"><input className="input-block mono" value={port} onChange={e => setPort(e.target.value)} /></Fld>
          </div>
          <Fld label="Gmail Address (SMTP Username)">
            <input className="input-block" type="email" value={user} onChange={e => setUser(e.target.value)} placeholder="ahmedzarrar64@gmail.com" />
          </Fld>
          <Fld label="Gmail App Password (16 characters — NOT your real password)">
            <div style={{ position: 'relative' }}>
              <input className="input-block mono" type={showPass ? 'text' : 'password'} value={pass} onChange={e => setPass(e.target.value)} placeholder="xxxx xxxx xxxx xxxx" style={{ paddingRight: 70, letterSpacing: showPass ? 'normal' : '.2em' }} />
              <button type="button" className="login-eye" style={{ top: '50%', transform: 'translateY(-50%)' }} onClick={() => setShowPass(v => !v)}>{showPass ? 'Hide' : 'Show'}</button>
            </div>
            <div className="tiny muted" style={{ marginTop: 4 }}>This is the App Password from Google, NOT your Gmail login password.</div>
          </Fld>
          <div className="row" style={{ gap: 10 }}>
            <Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>{busy ? 'Saving…' : 'Save Email Settings'}</Btn>
            {configured && <Btn variant="ghost" style={{ color: 'var(--ok)' }} icon={<Icons.check size={14} />}>Saved</Btn>}
          </div>
        </div>
      </div>

      {/* Test email */}
      <div className="card card-pad">
        <div style={{ fontWeight: 800, marginBottom: 4 }}>Send a Test Email</div>
        <div className="tiny muted" style={{ marginBottom: 12 }}>Confirm your settings are working by sending a test message.</div>
        <div className="row" style={{ gap: 10 }}>
          <input className="input-block" style={{ flex: 1 }} value={testTo} onChange={e => setTestTo(e.target.value)} placeholder={user || 'recipient@email.com'} />
          <Btn variant="primary" onClick={sendTest} disabled={testBusy}>{testBusy ? 'Sending…' : 'Send Test'}</Btn>
        </div>
      </div>
    </div>
  );
}

function RateSettings() {
  const { PKR } = window.DATA;
  const { data: inventory, loading, refetch } = useInventory();
  const [editProduct, setEditProduct] = React.useState(null);

  // Show any inventory item that is in the rental pool OR is a machine-category item
  const rentable = inventory.filter(i =>
    (i.rent_sys || 0) > 0 ||
    (i.rent_stock || 0) > 0 ||
    (i.category || '').toLowerCase().includes('machine')
  );
  // Deduplicate by product_id (or sku if no product_id)
  const seen = new Set();
  const rows = rentable.filter(i => {
    const key = i.product_id || i.sku || i.id;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });

  return (
    <div>
      <SecHead title="Rental Rate Plans" sub="Per-machine daily, weekly and monthly rates with security deposits." />

      {loading ? <div className="card card-pad tiny muted">Loading…</div> : (
        <div className="card" style={{ overflow: 'hidden' }}>
          <table className="tbl">
            <thead>
              <tr>
                <th>Machine</th>
                <th style={{ textAlign: 'right' }}>Daily</th>
                <th style={{ textAlign: 'right' }}>Weekly</th>
                <th style={{ textAlign: 'right' }}>Monthly</th>
                <th style={{ textAlign: 'right' }}>Deposit</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {rows.map((p) => (
                <tr key={p.id}>
                  <td style={{ fontWeight: 700 }}>{p.name}<div className="tiny muted mono">{p.sku}</div></td>
                  <td className="mono" style={{ textAlign: 'right' }}>{PKR(Number(p.rent_rate_daily  || 0))}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{PKR(Number(p.rent_rate_weekly || 0))}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{PKR(Number(p.rent_rate_monthly || p.rent_rate || 0))}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{PKR(Number(p.rent_deposit || 0))}</td>
                  <td style={{ textAlign: 'right' }}>
                    <Btn variant="ghost" sm icon={<Icons.gear size={14} />} onClick={() => setEditProduct(p)}>Edit Rates</Btn>
                  </td>
                </tr>
              ))}
              {!rows.length && (
                <tr><td colSpan={6} className="tiny muted" style={{ padding: 20, textAlign: 'center' }}>No machines in the rental fleet yet. Use Rentals → Rent Inventory → Add to Fleet first.</td></tr>
              )}
            </tbody>
          </table>
        </div>
      )}

      {editProduct && (
        <MachineRateModal product={editProduct} onClose={() => { setEditProduct(null); refetch(); }} />
      )}
    </div>
  );
}

function MachineRateModal({ product: p, onClose }) {
  const { PKR } = window.DATA;
  const [daily,   setDaily]   = React.useState(String(p.rent_rate_daily   || ''));
  const [weekly,  setWeekly]  = React.useState(String(p.rent_rate_weekly  || ''));
  const [monthly, setMonthly] = React.useState(String(p.rent_rate_monthly || p.rent_rate || ''));
  const [deposit, setDeposit] = React.useState(String(p.rent_deposit      || ''));
  const [busy,    setBusy]    = React.useState(false);

  const num = (v) => parseFloat(String(v).replace(/[^0-9.]/g, '')) || 0;

  const save = async () => {
    setBusy(true);
    try {
      // Save rates on the inventory item directly (per-branch)
      await api.updateInventory(p.id, {
        rent_rate_daily:   num(daily),
        rent_rate_weekly:  num(weekly),
        rent_rate_monthly: num(monthly),
        rent_deposit:      num(deposit),
      });
      // Also sync to product record so New Rental form picks them up
      if (p.product_id) {
        await api.updateProduct(p.product_id, {
          rent_rate_daily:   num(daily),
          rent_rate_weekly:  num(weekly),
          rent_rate_monthly: num(monthly),
          rent_deposit:      num(deposit),
          rent_rate:         num(monthly),
          rentable:          1,
        });
      }
      window.toast && window.toast(`Rates saved for ${p.name}`, 'ok');
      onClose();
    } catch (err) {
      window.toast && window.toast(err.message || 'Failed to save', 'error');
      setBusy(false);
    }
  };

  return (
    <Modal title="Edit Rental Rates" sub={p.name} onClose={onClose}
      foot={<>
        <Btn variant="ghost" onClick={onClose} disabled={busy}>Cancel</Btn>
        <Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>{busy ? 'Saving…' : 'Save Rates'}</Btn>
      </>}>
      <div style={{ display: 'grid', gap: 14 }}>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
          <Fld label="Daily Rate (Rs)">
            <input className="input-block mono" value={daily} onChange={e => setDaily(e.target.value.replace(/[^0-9]/g, ''))} placeholder="0" />
          </Fld>
          <Fld label="Weekly Rate (Rs)">
            <input className="input-block mono" value={weekly} onChange={e => setWeekly(e.target.value.replace(/[^0-9]/g, ''))} placeholder="0" />
          </Fld>
          <Fld label="Monthly Rate (Rs)">
            <input className="input-block mono" value={monthly} onChange={e => setMonthly(e.target.value.replace(/[^0-9]/g, ''))} placeholder="0" />
          </Fld>
        </div>
        <Fld label="Security Deposit (Rs)">
          <input className="input-block mono" value={deposit} onChange={e => setDeposit(e.target.value.replace(/[^0-9]/g, ''))} placeholder="0" />
        </Fld>
        <div style={{ border: '1px solid var(--line)', borderRadius: 12, overflow: 'hidden' }}>
          <div className="row" style={{ justifyContent: 'space-between', padding: '9px 14px', background: 'var(--surface-2)', fontSize: 12, fontWeight: 700, color: 'var(--ink-2)' }}>
            <span>Cycle</span><span>Rate</span><span>Label</span>
          </div>
          {[['Daily', daily, '/day'], ['Weekly', weekly, '/wk'], ['Monthly', monthly, '/mo']].map(([c, v, per]) => (
            <div key={c} className="row" style={{ justifyContent: 'space-between', padding: '9px 14px', borderTop: '1px solid var(--line)' }}>
              <span style={{ fontWeight: 600, fontSize: 13 }}>{c}</span>
              <span className="mono" style={{ fontWeight: 700 }}>{PKR(Number(v) || 0)}</span>
              <span className="tiny muted">{PKR(Number(v) || 0)}{per}</span>
            </div>
          ))}
          <div className="row" style={{ justifyContent: 'space-between', padding: '9px 14px', borderTop: '1px solid var(--line)', background: 'var(--warn-bg)' }}>
            <span style={{ fontWeight: 600, fontSize: 13 }}>Deposit</span>
            <span className="mono" style={{ fontWeight: 700 }}>{PKR(Number(deposit) || 0)}</span>
            <span className="tiny muted">refundable</span>
          </div>
        </div>
      </div>
    </Modal>
  );
}

function SleepTestTypeSettings({ open }) {
  const { PKR } = window.DATA;
  const { data: types, loading, refetch } = useStudyTypes();

  const toggle = async (t) => {
    try {
      await api.updateStudyType(t.id, { active: !t.active });
      refetch();
    } catch (err) {
      window.toast(err.message || 'Failed', 'error');
    }
  };

  return (
    <div>
      <SecHead title="Sleep Test Types" sub="Study types shown in the booking form with their default session fees."
        action={<Btn variant="primary" icon={<Icons.plus size={16} stroke={2.6} />} onClick={() => open('studytype', { onDone: refetch })}>Add Study Type</Btn>} />
      <div className="card" style={{ overflow: 'hidden' }}>
        {loading ? <div className="tiny muted" style={{ padding: 20 }}>Loading…</div> : (
          <table className="tbl">
            <thead><tr><th>Study Type</th><th>Description</th><th style={{ textAlign: 'right' }}>Default Fee</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {types.map((t) => (
                <tr key={t.id}>
                  <td style={{ fontWeight: 700 }}>{t.name}</td>
                  <td className="tiny muted">{t.description || '—'}</td>
                  <td className="mono" style={{ textAlign: 'right', fontWeight: 700 }}>{PKR(Number(t.default_charge))}</td>
                  <td><Badge kind={t.active ? 'ok' : 'idle'}>{t.active ? 'Active' : 'Inactive'}</Badge></td>
                  <td style={{ textAlign: 'right' }}>
                    <div className="row" style={{ gap: 6, justifyContent: 'flex-end' }}>
                      <Btn variant="ghost" sm onClick={() => toggle(t)}>{t.active ? 'Deactivate' : 'Activate'}</Btn>
                      <Btn variant="ghost" sm icon={<Icons.gear size={14} />} onClick={() => open('studytype', { ...t, onDone: refetch })}>Edit</Btn>
                    </div>
                  </td>
                </tr>
              ))}
              {!types.length && <tr><td colSpan={5} className="tiny muted" style={{ padding: 20, textAlign: 'center' }}>No study types found.</td></tr>}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}

function ReminderSettings() {
  return (
    <div>
      <SecHead title="Reminders & Automation" sub="When the scheduler nudges customers and staff." />
      <div className="card" style={{ overflow: 'hidden' }}>
        <Row title="Rental renewal reminder" sub="Before contract due date"><div className="row" style={{ gap: 8 }}><input className="input-block mono" defaultValue="3" style={{ width: 56, textAlign: 'center' }} /><span className="tiny muted">days</span></div></Row>
        <Row title="Overdue return escalation" sub="Notify branch manager"><div className="row" style={{ gap: 8 }}><input className="input-block mono" defaultValue="1" style={{ width: 56, textAlign: 'center' }} /><span className="tiny muted">day late</span></div></Row>
        <Row title="Payment due reminder" sub="For outstanding invoices"><div className="row" style={{ gap: 8 }}><input className="input-block mono" defaultValue="7" style={{ width: 56, textAlign: 'center' }} /><span className="tiny muted">days</span></div></Row>
        <Row title="Warranty expiry alert" sub="Before OEM/claim warranty ends"><div className="row" style={{ gap: 8 }}><input className="input-block mono" defaultValue="30" style={{ width: 56, textAlign: 'center' }} /><span className="tiny muted">days</span></div></Row>
        <div style={{ padding: 18 }}>
          <div className="tiny muted" style={{ fontWeight: 700, marginBottom: 10 }}>CHANNELS</div>
          {[['SMS', true], ['WhatsApp', true], ['Email', true], ['Push notification', false]].map(([ch, on]) => (
            <div key={ch} className="row" style={{ justifyContent: 'space-between', padding: '8px 0' }}><span style={{ fontWeight: 600 }}>{ch}</span><Toggle on={on} /></div>
          ))}
        </div>
      </div>
    </div>
  );
}
/* ============================================================
   TRANSACTION MESSAGES — WhatsApp templates & auto-send rules
   ============================================================ */
const WA_DOC_TYPES = [
  { key: 'Invoice',    label: 'Invoice',    icon: Icons.doc },
  { key: 'Purchase',   label: 'Purchase',   icon: Icons.box },
  { key: 'Sale Order', label: 'Sale Order', icon: Icons.sales },
  { key: 'Estimate',   label: 'Estimate',   icon: Icons.receipt },
  { key: 'Pay In',     label: 'Pay In',     icon: Icons.arrowDn },
  { key: 'Pay Out',    label: 'Pay Out',    icon: Icons.arrowUp },
  { key: 'Reminder',   label: 'Reminder',   icon: Icons.bell },
];

const WA_VARS = ['{Transaction_Date}', '{Party_Name}', '{Invoice_No}', '{Invoice_Amount}', '{Party_Balance}', '{Company_Name}', '{Company_Phone}'];

const WA_MSG_TOGGLES = [
  ['attach_invoice_pdf',    'Attach Invoice PDF',     'Include PDF attachment with the message'],
  ['attach_reminder_image', 'Attach Reminder Image',  'Auto-attach payment reminder image'],
  ['auto_sales_invoice',    'Auto-send Sales Invoice','Automatically send when creating sales invoice'],
  ['auto_purchase_order',   'Auto-send Purchase Order','Automatically send when creating purchase order'],
  ['auto_sale_order',       'Auto-send Sale Order',   'Automatically send when creating sale order'],
  ['auto_estimate',         'Auto-send Estimate',     'Automatically send when creating estimate'],
  ['auto_payment_in',       'Auto-send Payment In',   'Automatically send when receiving payment'],
  ['auto_payment_out',      'Auto-send Payment Out',  'Automatically send when making payment'],
];

const WA_DEFAULT_TEMPLATES = {
  'Invoice':    'Dear {Party_Name},\nAslam-o-Alaikam! Please see the new Invoice.\n{Transaction_Date}\n\nInvoice # {Invoice_No}\nInv. Amount {Invoice_Amount} /-\nCurrent Total Balance= {Party_Balance}\n\nThanks\n{Company_Name}\n{Company_Phone}',
  'Purchase':   'Dear {Party_Name},\nPlease find our Purchase Order below.\n{Transaction_Date}\n\nP.O. # {Invoice_No}\nAmount {Invoice_Amount} /-\n\nThanks\n{Company_Name}\n{Company_Phone}',
  'Sale Order': 'Dear {Party_Name},\nThank you for your order!\n{Transaction_Date}\n\nOrder # {Invoice_No}\nAmount {Invoice_Amount} /-\n\nThanks\n{Company_Name}\n{Company_Phone}',
  'Estimate':   'Dear {Party_Name},\nPlease find your Estimate / Quotation below.\n{Transaction_Date}\n\nEstimate # {Invoice_No}\nAmount {Invoice_Amount} /-\n\nThanks\n{Company_Name}\n{Company_Phone}',
  'Pay In':     'Dear {Party_Name},\nWe have received your payment. JazakAllah!\n{Transaction_Date}\n\nReceipt # {Invoice_No}\nAmount Received {Invoice_Amount} /-\nRemaining Balance= {Party_Balance}\n\nThanks\n{Company_Name}\n{Company_Phone}',
  'Pay Out':    'Dear {Party_Name},\nWe have made a payment to your account.\n{Transaction_Date}\n\nVoucher # {Invoice_No}\nAmount Paid {Invoice_Amount} /-\n\nThanks\n{Company_Name}\n{Company_Phone}',
  'Reminder':   'Dear {Party_Name},\nGentle reminder regarding your outstanding balance.\n{Transaction_Date}\n\nInvoice # {Invoice_No}\nOutstanding Balance= {Party_Balance}\n\nKindly clear at your earliest. Thanks\n{Company_Name}\n{Company_Phone}',
};

const WA_SAMPLE = {
  Transaction_Date: '17/06/2026',
  Party_Name:       'ABC Company Ltd.',
  Invoice_No:       'INV-2024-001',
  Invoice_Amount:   '25,000',
  Party_Balance:    '150,000',
  Company_Name:     'Electromed Corporation',
  Company_Phone:    '0300-1234567',
};

const WaLogo = ({ size = 22 }) => (
  <svg width={size} height={size} viewBox="0 0 32 32" fill="#25D366" aria-hidden="true">
    <path d="M16 3C9.4 3 4 8.4 4 15c0 2.1.6 4.2 1.6 6L4 29l8.2-1.6c1.7.9 3.7 1.4 5.8 1.4 6.6 0 12-5.4 12-12S22.6 3 16 3z" opacity=".15" />
    <path d="M16 5.3C10.6 5.3 6.3 9.6 6.3 15c0 1.9.6 3.7 1.5 5.2l-1 3.6 3.7-1c1.5.8 3.1 1.2 4.5 1.2 5.4 0 9.7-4.3 9.7-9.7S21.4 5.3 16 5.3zm5.7 13.7c-.2.7-1.4 1.3-2 1.4-.5.1-1.2.1-1.9-.1-.4-.1-1-.3-1.8-.6-3.1-1.3-5.1-4.4-5.3-4.6-.2-.2-1.3-1.7-1.3-3.2s.8-2.3 1.1-2.6c.3-.3.6-.4.8-.4h.6c.2 0 .5-.1.7.5l.9 2.1c.1.2.1.4 0 .6l-.4.6c-.2.2-.4.4-.2.7.2.4.9 1.4 1.9 2.3 1.3 1.1 2.3 1.5 2.7 1.6.3.1.5.1.7-.1l.8-1c.2-.3.5-.2.7-.1l2 1c.3.1.5.2.5.3.1.2.1.8-.1 1.5z" />
  </svg>
);

function WaToggleCard({ on, onToggle, title, sub, accent }) {
  return (
    <button type="button" onClick={onToggle} style={{
      display: 'flex', gap: 11, alignItems: 'flex-start', textAlign: 'left',
      padding: '13px 15px', borderRadius: 12, cursor: 'pointer', width: '100%',
      border: on ? '1.5px solid var(--lime-700)' : '1.5px solid var(--line)',
      background: on ? 'var(--lime-soft, #eafaf1)' : 'var(--surface-2)', transition: '.14s',
    }}>
      <span style={{
        width: 18, height: 18, borderRadius: 5, flexShrink: 0, marginTop: 1,
        display: 'grid', placeItems: 'center',
        background: on ? (accent || 'var(--lime-700)') : '#fff',
        border: on ? 'none' : '1.5px solid var(--line-2)',
      }}>{on && <Icons.check size={12} stroke={3} style={{ color: '#fff' }} />}</span>
      <span>
        <span style={{ display: 'block', fontWeight: 700, fontSize: 13.5, color: on ? 'var(--ink)' : 'var(--ink-2)' }}>{title}</span>
        <span className="tiny muted" style={{ display: 'block', marginTop: 2 }}>{sub}</span>
      </span>
    </button>
  );
}

function TransactionMessageSettings() {
  const [loading, setLoading] = useState(true);
  const [busy, setBusy]       = useState(false);
  const [connected, setConnected] = useState(false);
  const [waPhone, setWaPhone] = useState('');
  const [settings, setSettings] = useState({ attach_invoice_pdf: true, attach_reminder_image: true });
  const [templates, setTemplates] = useState({ ...WA_DEFAULT_TEMPLATES });
  const [tab, setTab] = useState('Invoice');
  const [showConnect, setShowConnect] = useState(false);
  const taRef = React.useRef(null);

  useEffect(() => {
    api.getBranchSettings().then(r => {
      const wa = (r.settings && r.settings.whatsapp_config) || {};
      setConnected(!!wa.connected);
      setWaPhone(wa.phone || '');
      setSettings({ attach_invoice_pdf: true, attach_reminder_image: true, ...(wa.settings || {}) });
      setTemplates({ ...WA_DEFAULT_TEMPLATES, ...(wa.templates || {}) });
      setLoading(false);
    }).catch(() => setLoading(false));
    // Reflect the live gateway state (survives restarts / linked elsewhere)
    api.whatsappStatus().then(s => {
      if (s && s.status === 'connected') { setConnected(true); if (s.phone) setWaPhone(s.phone); }
    }).catch(() => {});
  }, []);

  const persist = async (patch) => {
    const payload = {
      connected, phone: waPhone, settings, templates,
      ...patch,
    };
    return api.updateBranchSettings({ whatsapp_config: payload });
  };

  const save = async () => {
    setBusy(true);
    try {
      await persist();
      window.toast('Transaction messages saved', 'ok');
    } catch (err) {
      window.toast(err.message || 'Failed to save', 'error');
    } finally { setBusy(false); }
  };

  const toggleConnect = async () => {
    if (connected) {
      try {
        await api.whatsappDisconnect();
        setConnected(false); setWaPhone('');
        window.toast('WhatsApp number unlinked', 'warn');
      } catch (err) { window.toast(err.message || 'Failed to disconnect', 'error'); }
      return;
    }
    setShowConnect(true);
  };

  const onLinked = (phone) => {
    setConnected(true);
    if (phone) setWaPhone(phone);
    setShowConnect(false);
    window.toast('WhatsApp linked — you can now send messages', 'ok');
  };

  const setSetting = (k) => setSettings(s => ({ ...s, [k]: !s[k] }));
  const setTemplate = (v) => setTemplates(t => ({ ...t, [tab]: v }));

  const insertVar = (v) => {
    const ta = taRef.current;
    const cur = templates[tab] || '';
    if (!ta) { setTemplate(cur + v); return; }
    const s = ta.selectionStart ?? cur.length;
    const e = ta.selectionEnd ?? cur.length;
    setTemplate(cur.slice(0, s) + v + cur.slice(e));
    requestAnimationFrame(() => { ta.focus(); const p = s + v.length; ta.setSelectionRange(p, p); });
  };

  const rendered = (templates[tab] || '').replace(/\{(\w+)\}/g, (m, k) => (WA_SAMPLE[k] !== undefined ? WA_SAMPLE[k] : m));
  const showPdf = tab !== 'Reminder' && settings.attach_invoice_pdf;
  const showImg = tab === 'Reminder' && settings.attach_reminder_image;

  if (loading) return <div className="card card-pad tiny muted">Loading transaction messages…</div>;

  return (
    <div>
      <SecHead title="Transaction Messages" sub="Configure WhatsApp messages for invoices and orders."
        action={<Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>{busy ? 'Saving…' : 'Save Changes'}</Btn>} />

      {/* WhatsApp connection */}
      <div className="card" style={{ padding: 16, marginBottom: 16, display: 'flex', alignItems: 'center', gap: 14 }}>
        <div style={{ width: 42, height: 42, borderRadius: 11, background: '#e9f9ef', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
          <WaLogo size={24} />
        </div>
        <div className="grow">
          <div className="row" style={{ gap: 8, alignItems: 'center' }}>
            <span style={{ fontWeight: 800 }}>WhatsApp</span>
            <span style={{
              fontSize: 11.5, fontWeight: 700, padding: '2px 9px', borderRadius: 999,
              background: connected ? 'var(--ok-bg)' : 'var(--warn-bg)',
              color: connected ? 'var(--ok)' : 'var(--warn)',
            }}>{connected ? `Connected${waPhone ? ' · ' + waPhone : ''}` : 'Not Connected'}</span>
          </div>
          <div className="tiny muted" style={{ marginTop: 2 }}>
            {connected ? 'Messages will be sent from this number.' : 'Link your WhatsApp business number to enable sending.'}
          </div>
        </div>
        <Btn variant={connected ? 'ghost' : 'primary'} icon={<WaLogo size={15} />} onClick={toggleConnect}>
          {connected ? 'Disconnect' : 'Connect'}
        </Btn>
      </div>

      {/* Message settings toggles */}
      <div className="card" style={{ padding: 18, marginBottom: 16 }}>
        <div style={{ fontWeight: 800, fontSize: 13, color: 'var(--ink-3)', letterSpacing: '.06em', marginBottom: 12 }}>MESSAGE SETTINGS</div>
        <div className="grid" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))', gap: 12 }}>
          {WA_MSG_TOGGLES.map(([k, title, sub]) => (
            <WaToggleCard key={k} on={!!settings[k]} onToggle={() => setSetting(k)} title={title} sub={sub}
              accent={k === 'attach_reminder_image' ? 'var(--warn)' : undefined} />
          ))}
        </div>
      </div>

      {/* Doc-type tabs */}
      <div className="row" style={{ gap: 8, flexWrap: 'wrap', marginBottom: 16 }}>
        {WA_DOC_TYPES.map(d => (
          <button key={d.key} type="button" onClick={() => setTab(d.key)} className={cls('nav-item', tab === d.key && 'active')}
            style={{ width: 'auto', padding: '8px 14px', borderRadius: 10, border: tab === d.key ? '1.5px solid var(--lime-700)' : '1.5px solid var(--line)' }}>
            <d.icon className="nav-ic" />{d.label}
          </button>
        ))}
      </div>

      {/* Template editor + preview */}
      <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 16, alignItems: 'start' }}>
        <div className="card" style={{ padding: 18 }}>
          <div style={{ fontWeight: 800, marginBottom: 4 }}>Message Template</div>
          <div className="tiny muted" style={{ marginBottom: 12 }}>Click a variable to insert it at the cursor.</div>
          <div className="row" style={{ gap: 7, flexWrap: 'wrap', marginBottom: 12 }}>
            {WA_VARS.map(v => (
              <button key={v} type="button" onClick={() => insertVar(v)} style={{
                fontSize: 11.5, fontWeight: 600, padding: '4px 10px', borderRadius: 999, cursor: 'pointer',
                background: 'var(--surface-2)', border: '1px solid var(--line-2)', color: 'var(--lime-700)',
              }}>{v}</button>
            ))}
          </div>
          <textarea ref={taRef} className="input-block" rows="11" value={templates[tab] || ''}
            onChange={e => setTemplate(e.target.value)} style={{ resize: 'vertical', lineHeight: 1.5, fontSize: 13.5 }} />
        </div>

        {/* Live preview */}
        <div className="card" style={{ overflow: 'hidden' }}>
          <div className="row" style={{ justifyContent: 'space-between', padding: '12px 16px', borderBottom: '1px solid var(--line)' }}>
            <div style={{ fontWeight: 800 }}>Message Preview</div>
            <span className="tiny muted">Sample data</span>
          </div>
          <div style={{ padding: 18, background: '#e5ddd5', minHeight: 320 }}>
            <div className="row" style={{ gap: 9, padding: '10px 12px', background: '#075E54', borderRadius: '10px 10px 0 0', marginBottom: 10 }}>
              <div style={{ width: 30, height: 30, borderRadius: 50, background: 'rgba(255,255,255,.18)', display: 'grid', placeItems: 'center', color: '#fff', fontWeight: 800, fontSize: 12 }}>AC</div>
              <div><div style={{ color: '#fff', fontWeight: 700, fontSize: 13 }}>{WA_SAMPLE.Party_Name}</div><div style={{ color: 'rgba(255,255,255,.65)', fontSize: 11 }}>online</div></div>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 6 }}>
              {showPdf && (
                <div style={{ background: '#dcf8c6', borderRadius: 8, padding: 8, display: 'flex', gap: 8, alignItems: 'center', maxWidth: 240 }}>
                  <div style={{ width: 30, height: 36, borderRadius: 5, background: '#e74c3c', color: '#fff', display: 'grid', placeItems: 'center', fontSize: 9, fontWeight: 800 }}>PDF</div>
                  <div style={{ fontSize: 11, fontWeight: 600 }}>{WA_SAMPLE.Invoice_No}.pdf<div style={{ color: 'var(--ink-3)', fontWeight: 500 }}>12 KB</div></div>
                </div>
              )}
              {showImg && (
                <div style={{ background: '#dcf8c6', borderRadius: 8, padding: 8, maxWidth: 200 }}>
                  <div style={{ height: 90, borderRadius: 5, background: 'linear-gradient(135deg,#fde68a,#f59e0b)', display: 'grid', placeItems: 'center', color: '#7c2d12', fontWeight: 800, fontSize: 12 }}>Payment Reminder</div>
                </div>
              )}
              <div style={{ background: '#dcf8c6', borderRadius: '8px 8px 0 8px', padding: '8px 11px', maxWidth: 280, fontSize: 12.5, lineHeight: 1.5, whiteSpace: 'pre-wrap', boxShadow: '0 1px 1px rgba(0,0,0,.08)' }}>
                {rendered}
                <div style={{ textAlign: 'right', fontSize: 10, color: '#667781', marginTop: 3 }}>15:12 ✓✓</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="row" style={{ gap: 10, padding: '14px 16px', background: 'var(--info-bg, #eef4ff)', borderRadius: 12, marginTop: 16 }}>
        <span style={{ fontSize: 16 }}>💡</span>
        <span className="tiny" style={{ color: 'var(--ink-2)' }}><b>Note:</b> Connect WhatsApp to enable automatic message sending for your transactions. Sent messages are recorded under <b>Message Logs</b>.</span>
      </div>

      {showConnect && <WaConnectModal onClose={() => setShowConnect(false)} onConnected={onLinked} />}
    </div>
  );
}

/* QR-scan modal — links a real WhatsApp number via WhatsApp Web (multi-device). */
function WaConnectModal({ onClose, onConnected }) {
  const [status, setStatus] = useState('connecting'); // connecting | qr | connected | error
  const [qr, setQr]   = useState(null);
  const [err, setErr] = useState(null);

  useEffect(() => {
    let alive = true;
    let timer = null;
    const poll = async () => {
      try {
        const s = await api.whatsappStatus();
        if (!alive) return;
        setStatus(s.status); setQr(s.qr || null); setErr(s.error || null);
        if (s.status === 'connected') { onConnected(s.phone); return; }
      } catch (e) { if (alive) { setStatus('error'); setErr(e.message); } }
      if (alive) timer = setTimeout(poll, 2500);
    };
    // Kick off the connection, then begin polling for the QR / open event
    api.whatsappConnect().then(s => { if (alive) { setStatus(s.status); setQr(s.qr || null); } }).catch(e => { if (alive) { setStatus('error'); setErr(e.message); } });
    timer = setTimeout(poll, 1500);
    return () => { alive = false; if (timer) clearTimeout(timer); };
  }, []);

  return (
    <Modal title="Link WhatsApp" sub="Connect your WhatsApp number to send invoices and reminders." onClose={onClose}
      foot={<Btn variant="ghost" onClick={onClose}>Close</Btn>}>
      <div style={{ display: 'grid', gap: 16, justifyItems: 'center', padding: '8px 0 4px' }}>
        <ol className="tiny muted" style={{ alignSelf: 'stretch', margin: 0, paddingLeft: 18, lineHeight: 1.7 }}>
          <li>Open <b>WhatsApp</b> on your phone</li>
          <li>Tap <b>Settings → Linked Devices → Link a Device</b></li>
          <li>Point your phone at the code below</li>
        </ol>

        <div style={{ width: 248, height: 248, borderRadius: 14, border: '1.5px solid var(--line)', display: 'grid', placeItems: 'center', background: '#fff', overflow: 'hidden' }}>
          {status === 'qr' && qr ? (
            <img src={qr} alt="WhatsApp QR code" width={240} height={240} style={{ display: 'block' }} />
          ) : status === 'connected' ? (
            <div style={{ textAlign: 'center', color: 'var(--ok)' }}>
              <Icons.check size={48} stroke={2.4} /><div style={{ fontWeight: 700, marginTop: 8 }}>Linked!</div>
            </div>
          ) : status === 'error' ? (
            <div style={{ textAlign: 'center', color: 'var(--bad, #dc2626)', padding: 16 }}>
              <Icons.x size={36} /><div className="tiny" style={{ marginTop: 8 }}>{err || 'Connection failed'}</div>
            </div>
          ) : (
            <div style={{ textAlign: 'center', color: 'var(--ink-3)' }}>
              <div className="spin" style={{ width: 30, height: 30, border: '3px solid var(--line-2)', borderTopColor: 'var(--lime-700)', borderRadius: '50%', margin: '0 auto', animation: 'spin 0.8s linear infinite' }} />
              <div className="tiny" style={{ marginTop: 10 }}>Generating secure QR code…</div>
            </div>
          )}
        </div>
        <div className="tiny muted">The code refreshes automatically. Keep this window open while scanning.</div>
      </div>
    </Modal>
  );
}

/* ============================================================
   MESSAGE LOGS — audit trail of sent transaction messages
   ============================================================ */
const WA_STATUS_STYLE = {
  Sent:      ['var(--info)',  'var(--info-bg, #eef4ff)'],
  Delivered: ['var(--ok)',    'var(--ok-bg)'],
  Read:      ['var(--lime-700)', 'var(--lime-soft, #eafaf1)'],
  Queued:    ['var(--warn)',  'var(--warn-bg)'],
  Failed:    ['var(--bad, #dc2626)', 'var(--bad-bg, #fdecec)'],
};

function MessageLogSettings() {
  const [logs, setLogs]     = useState([]);
  const [counts, setCounts] = useState({});
  const [loading, setLoading] = useState(true);
  const [docType, setDocType] = useState('All');
  const [status, setStatus]   = useState('All');
  const [search, setSearch]   = useState('');

  const load = () => {
    setLoading(true);
    api.getMessageLogs({ doc_type: docType, status, search })
      .then(r => { setLogs(r.logs || []); setCounts(r.counts || {}); setLoading(false); })
      .catch(() => { setLogs([]); setLoading(false); });
  };
  useEffect(() => { load(); }, [docType, status]);

  const summary = [
    ['Delivered', counts.Delivered || 0, 'var(--ok)'],
    ['Sent',      counts.Sent || 0,      'var(--info)'],
    ['Queued',    counts.Queued || 0,    'var(--warn)'],
    ['Failed',    counts.Failed || 0,    'var(--bad, #dc2626)'],
  ];

  const fmt = (d) => { try { return new Date(d).toLocaleString('en-GB', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' }); } catch { return d; } };

  return (
    <div>
      <SecHead title="Message Logs" sub="Every WhatsApp message sent for invoices, orders and payments."
        action={<Btn variant="ghost" icon={<Icons.undo size={15} />} onClick={load}>Refresh</Btn>} />

      {/* Summary cards */}
      <div className="grid" style={{ gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 16 }}>
        {summary.map(([label, n, color]) => (
          <div key={label} className="card" style={{ padding: '14px 16px' }}>
            <div className="tiny muted" style={{ fontWeight: 700 }}>{label}</div>
            <div style={{ fontWeight: 800, fontSize: 24, color, marginTop: 3 }}>{n}</div>
          </div>
        ))}
      </div>

      {/* Filters */}
      <div className="card" style={{ padding: 12, marginBottom: 16 }}>
        <div className="row" style={{ gap: 10, flexWrap: 'wrap' }}>
          <div style={{ position: 'relative', flex: 1, minWidth: 200 }}>
            <Icons.search size={15} style={{ position: 'absolute', left: 11, top: '50%', transform: 'translateY(-50%)', color: 'var(--ink-3)' }} />
            <input className="input-block" value={search} onChange={e => setSearch(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && load()} placeholder="Search party, document or phone…" style={{ paddingLeft: 34 }} />
          </div>
          <select className="input-block" value={docType} onChange={e => setDocType(e.target.value)} style={{ width: 160 }}>
            <option value="All">All Types</option>
            {WA_DOC_TYPES.map(d => <option key={d.key} value={d.key}>{d.label}</option>)}
          </select>
          <select className="input-block" value={status} onChange={e => setStatus(e.target.value)} style={{ width: 150 }}>
            {['All', 'Queued', 'Sent', 'Delivered', 'Read', 'Failed'].map(s => <option key={s} value={s}>{s === 'All' ? 'All Status' : s}</option>)}
          </select>
          <Btn variant="primary" icon={<Icons.search size={15} />} onClick={load}>Search</Btn>
        </div>
      </div>

      {/* Table */}
      <div className="card" style={{ overflow: 'hidden' }}>
        {loading ? <div className="card-pad tiny muted">Loading logs…</div> : !logs.length ? (
          <div style={{ padding: '46px 20px', textAlign: 'center' }}>
            <div style={{ width: 54, height: 54, borderRadius: 14, background: '#e9f9ef', display: 'grid', placeItems: 'center', margin: '0 auto 14px' }}><WaLogo size={28} /></div>
            <div style={{ fontWeight: 700, marginBottom: 4 }}>No messages yet</div>
            <div className="tiny muted" style={{ maxWidth: 360, margin: '0 auto' }}>Once WhatsApp is connected and you send invoices or payments, every message will be recorded here.</div>
          </div>
        ) : (
          <table className="tbl">
            <thead>
              <tr>
                <th>Date</th><th>Party</th><th>Type</th><th>Document</th><th>Phone</th><th>Channel</th><th>Status</th>
              </tr>
            </thead>
            <tbody>
              {logs.map(l => {
                const [c, bg] = WA_STATUS_STYLE[l.status] || ['var(--ink-2)', 'var(--surface-2)'];
                return (
                  <tr key={l.id}>
                    <td className="mono tiny">{fmt(l.created_at)}</td>
                    <td style={{ fontWeight: 600 }}>{l.party_name || '—'}</td>
                    <td className="tiny">{l.doc_type}</td>
                    <td className="mono tiny">{l.doc_no || '—'}</td>
                    <td className="mono tiny">{l.phone || '—'}</td>
                    <td className="tiny">{l.channel}</td>
                    <td><span style={{ fontSize: 11.5, fontWeight: 700, padding: '2px 9px', borderRadius: 999, background: bg, color: c }}>{l.status}</span></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}

/* ---------- Permission picker (None / View / Manage) ---------- */
function PermSeg({ value, onChange, disabled }) {
  const opts = ['None', 'View', 'Manage'];
  return (
    <div className="tabs" style={{ borderRadius: 10, opacity: disabled ? .6 : 1 }}>
      {opts.map((o) => <button key={o} type="button" className={cls('tab', value === o && 'active')} style={{ padding: '6px 14px', fontSize: 12.5 }} onClick={() => !disabled && onChange(o)}>{o}</button>)}
    </div>
  );
}
function Fld({ label, children }) {
  return <label className="fld"><span>{label}</span>{children}</label>;
}

/* ---------- Settings modal switchboard ---------- */
function SettingsModals({ modal, close }) {
  if (!modal) return null;
  const { type, data } = modal;
  if (type === 'company')   return <CompanyModal data={data} close={close} />;
  if (type === 'branch')    return <BranchModal data={data} close={close} />;
  if (type === 'invite')    return <InviteModal close={close} data={data} />;
  if (type === 'access')    return <AccessModal data={data} close={close} />;
  if (type === 'role')      return <RoleModal data={data} close={close} />;
  if (type === 'studytype') return <StudyTypeModal data={data} close={close} />;
  return null;
}

function StudyTypeModal({ data, close }) {
  const isNew = !data || !data.id;
  const onDone = data && data.onDone;
  const [name,    setName]    = useState(isNew ? '' : (data.name || ''));
  const [charge,  setCharge]  = useState(isNew ? '' : String(data.default_charge || ''));
  const [desc,    setDesc]    = useState(isNew ? '' : (data.description || ''));
  const [busy,    setBusy]    = useState(false);

  const save = async () => {
    if (!name.trim()) { window.toast('Study type name is required', 'warn'); return; }
    setBusy(true);
    try {
      const payload = { name: name.trim(), default_charge: parseFloat(charge) || 0, description: desc.trim() || null };
      if (isNew) await api.createStudyType(payload);
      else        await api.updateStudyType(data.id, payload);
      window.toast(isNew ? 'Study type added' : 'Study type updated', 'ok');
      if (onDone) onDone();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed to save', 'error');
    } finally { setBusy(false); }
  };

  const remove = async () => {
    if (!confirm('Remove this study type?')) return;
    setBusy(true);
    try {
      await api.deleteStudyType(data.id);
      window.toast('Study type removed', 'ok');
      if (onDone) onDone();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed', 'error');
    } finally { setBusy(false); }
  };

  return (
    <Modal title={isNew ? 'Add Study Type' : 'Edit Study Type'} sub={isNew ? 'New diagnostic study type & default fee' : name} onClose={close}
      foot={<>
        {!isNew && <Btn variant="ghost" style={{ marginRight: 'auto', color: 'var(--bad)' }} onClick={remove} disabled={busy}>Remove</Btn>}
        <Btn variant="ghost" onClick={close} disabled={busy}>Cancel</Btn>
        <Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>{busy ? 'Saving…' : isNew ? 'Add Type' : 'Save Changes'}</Btn>
      </>}>
      <div style={{ display: 'grid', gap: 14 }}>
        <Fld label="Study Type Name">
          <input className="input-block" value={name} onChange={e => setName(e.target.value)} placeholder="e.g. Level-1 PSG (in-lab)" autoFocus />
        </Fld>
        <Fld label="Default Session Fee (Rs)">
          <input className="input-block mono" value={charge} onChange={e => setCharge(e.target.value.replace(/[^0-9.]/g, ''))} placeholder="0" />
        </Fld>
        <Fld label="Description (optional)">
          <input className="input-block" value={desc} onChange={e => setDesc(e.target.value)} placeholder="Short description shown to staff" />
        </Fld>
        <div className="row" style={{ gap: 10, padding: '12px 14px', background: 'var(--info-bg)', borderRadius: 11 }}>
          <Icons.moon size={16} style={{ color: 'var(--info)', flexShrink: 0 }} />
          <span className="tiny" style={{ fontWeight: 600 }}>The default fee pre-fills the "Book Sleep Test" form. Staff can still override it per booking.</span>
        </div>
      </div>
    </Modal>
  );
}

function CompanyModal({ data: c, close }) {
  const isNew = !c;
  const [f, setF]   = useState({ name: '', letterhead: '', ntn: '', strn: '', gst_rate: 17, addr: '', phone: '', email: '', bank: '', color: '#1c5a3a', ...(c || {}) });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF((p) => ({ ...p, [k]: v }));
  const swatches = ['#0f3324', '#1c5a3a', '#2f6fd6', '#0d1411'];

  const save = async () => {
    if (!f.name.trim()) { window.toast('Company name is required', 'warn'); return; }
    setBusy(true);
    try {
      const payload = { name: f.name, letterhead: f.letterhead, ntn: f.ntn, strn: f.strn, gst_rate: f.gst_rate, addr: f.addr, phone: f.phone, email: f.email, bank: f.bank, color: f.color };
      if (isNew) await api.createCompany(payload);
      else        await api.updateCompany(c.id, payload);
      window.toast(isNew ? 'Company created' : 'Changes saved', 'ok');
      if (window.__reloadCompanies) window.__reloadCompanies();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed to save', 'error');
    } finally { setBusy(false); }
  };

  const remove = async () => {
    if (!confirm('Remove this company profile?')) return;
    setBusy(true);
    try {
      await api.deleteCompany(c.id);
      window.toast('Company removed', 'ok');
      if (window.__reloadCompanies) window.__reloadCompanies();
      close();
    } catch (err) { window.toast(err.message || 'Failed to remove', 'error'); }
    finally { setBusy(false); }
  };

  return (
    <Modal wide title={isNew ? 'Add Company' : 'Edit Company'} sub={isNew ? 'New invoicing letterhead — GST registered' : f.name} onClose={close}
      foot={<>
        {!isNew && <Btn variant="ghost" style={{ marginRight: 'auto', color: 'var(--bad)' }} onClick={remove} disabled={busy}>Remove Company</Btn>}
        <Btn variant="ghost" onClick={close} disabled={busy}>Cancel</Btn>
        <Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>{busy ? 'Saving…' : isNew ? 'Create Company' : 'Save Changes'}</Btn>
      </>}>
      <div style={{ display: 'grid', gap: 16 }}>
        <Fld label="Registered Name"><input className="input-block" value={f.name} onChange={(e) => set('name', e.target.value)} placeholder="Electromed Surgical (Pvt) Ltd" /></Fld>
        <Fld label="Letterhead Tagline"><input className="input-block" value={f.letterhead} onChange={(e) => set('letterhead', e.target.value)} placeholder="Surgical & Hospital Supplies" /></Fld>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
          <Fld label="NTN"><input className="input-block mono" value={f.ntn} onChange={(e) => set('ntn', e.target.value)} placeholder="0000000-0" /></Fld>
          <Fld label="STRN"><input className="input-block mono" value={f.strn} onChange={(e) => set('strn', e.target.value)} placeholder="32-77-0000-000-00" /></Fld>
          <Fld label="GST Rate (%)"><input className="input-block mono" value={f.gst_rate} onChange={(e) => set('gst_rate', e.target.value.replace(/\D/g, ''))} /></Fld>
        </div>
        <Fld label="Registered Address"><textarea className="input-block" rows="2" value={f.addr} onChange={(e) => set('addr', e.target.value)} placeholder="Street, city" /></Fld>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Phone"><input className="input-block mono" value={f.phone} onChange={(e) => set('phone', e.target.value)} placeholder="+92 …" /></Fld>
          <Fld label="Billing Email"><input className="input-block" value={f.email} onChange={(e) => set('email', e.target.value)} placeholder="billing@…" /></Fld>
        </div>
        <Fld label="Bank Account (invoice footer)"><input className="input-block" value={f.bank} onChange={(e) => set('bank', e.target.value)} placeholder="Bank · branch · IBAN" /></Fld>
        <Fld label="Letterhead Color">
          <div className="row" style={{ gap: 10 }}>
            {swatches.map((s) => (
              <button key={s} type="button" onClick={() => set('color', s)} style={{ width: 40, height: 40, borderRadius: 11, background: s, border: f.color === s ? '3px solid var(--lime)' : '3px solid transparent', display: 'grid', placeItems: 'center' }}>
                {f.color === s && <Icons.check size={16} stroke={3} style={{ color: '#fff' }} />}
              </button>
            ))}
          </div>
        </Fld>
      </div>
    </Modal>
  );
}

function BranchModal({ data: b, close }) {
  const isNew = !b;
  const [f, setF]       = useState({ name: '', city: '', code: '', email: '', address: '', phone: '', manager: '', staff: 0, status: 'active', ...(b || {}) });
  const [busy, setBusy]       = useState(false);
  const [confirmDel, setConfirmDel] = useState(false);
  const [users, setUsers]     = useState([]);
  const set = (k, v) => setF((p) => ({ ...p, [k]: v }));

  useEffect(() => {
    api.getUsers().then(r => setUsers(Array.isArray(r) ? r : (r.users || []))).catch(() => {});
  }, []);

  const save = async () => {
    if (!f.name.trim()) { window.toast('Branch name is required', 'warn'); return; }
    setBusy(true);
    try {
      const payload = { name: f.name, city: f.city, code: f.code, email: f.email, address: f.address, phone: f.phone, manager: f.manager, staff: parseInt(f.staff) || 0, status: f.status };
      if (isNew) await api.createBranch(payload);
      else        await api.updateBranch(b.id, payload);
      window.toast(isNew ? 'Branch created' : 'Branch saved', 'ok');
      if (window.__reloadBranches) window.__reloadBranches();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed to save', 'error');
    } finally { setBusy(false); }
  };

  const remove = async () => {
    setBusy(true);
    try {
      await api.deleteBranch(b.id);
      window.toast('Branch removed', 'ok');
      if (window.__reloadBranches) window.__reloadBranches();
      close();
    } catch (err) { window.toast(err.message || 'Failed to remove', 'error'); }
    finally { setBusy(false); }
  };

  const mgrs = users.filter(u => ['admin', 'owner', 'Branch Manager'].includes(u.role || u.display_role));

  return (
    <>
    {confirmDel && <ConfirmDeleteModal
      title="Remove Branch"
      body={`Remove "${b.name}"? This will soft-delete the branch and cannot be undone without a super-admin restore.`}
      onCancel={() => setConfirmDel(false)}
      onConfirm={remove}
      confirmLabel="Remove Branch"
    />}
    <Modal title={isNew ? 'Add Branch' : 'Edit Branch'} sub={isNew ? 'New location with its own stock & invoice sequence' : f.name} onClose={close}
      foot={<>
        {!isNew && <Btn variant="danger" icon={<Icons.trash size={15} />} style={{ marginRight: 'auto' }} onClick={() => setConfirmDel(true)} disabled={busy}>Remove</Btn>}
        <Btn variant="ghost" onClick={close} disabled={busy}>Cancel</Btn>
        <Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>{busy ? 'Saving…' : isNew ? 'Create Branch' : 'Save Changes'}</Btn>
      </>}>
      <div style={{ display: 'grid', gap: 16 }}>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Branch Name"><input className="input-block" value={f.name} onChange={(e) => set('name', e.target.value)} placeholder="Karachi HQ" /></Fld>
          <Fld label="City"><input className="input-block" value={f.city} onChange={(e) => set('city', e.target.value)} placeholder="Karachi" /></Fld>
        </div>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Branch Code"><input className="input-block mono" value={f.code || ''} onChange={(e) => set('code', e.target.value.toUpperCase())} placeholder="KHI" /></Fld>
          <Fld label="Branch Email"><input className="input-block" type="email" value={f.email || ''} onChange={(e) => set('email', e.target.value)} placeholder="karachi@electromed.pk" /></Fld>
        </div>
        <Fld label="Address"><input className="input-block" value={f.address || ''} onChange={(e) => set('address', e.target.value)} placeholder="Street, area" /></Fld>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Phone"><input className="input-block mono" value={f.phone || ''} onChange={(e) => set('phone', e.target.value)} placeholder="+92 …" /></Fld>
          <Fld label="Headcount"><input className="input-block mono" value={f.staff} onChange={(e) => set('staff', e.target.value.replace(/\D/g, ''))} /></Fld>
        </div>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Fld label="Branch Manager">
            <select className="input-block" value={f.manager || ''} onChange={(e) => set('manager', e.target.value)}>
              <option value="">— Unassigned —</option>
              {mgrs.map((m) => <option key={m.id} value={m.name}>{m.name}</option>)}
            </select>
          </Fld>
          <Fld label="Status">
            <select className="input-block" value={f.status || 'active'} onChange={(e) => set('status', e.target.value)}>
              <option value="active">Active</option>
              <option value="inactive">Inactive</option>
            </select>
          </Fld>
        </div>
        {isNew && <div className="row" style={{ gap: 11, padding: '13px 15px', background: 'var(--surface-2)', borderRadius: 12 }}><Icons.box size={18} style={{ color: 'var(--lime-700)', flexShrink: 0 }} /><span className="tiny muted">A fresh inventory ledger & invoice number sequence will be created for this branch.</span></div>}
      </div>
    </Modal>
    </>
  );
}

function PermPreview({ perms }) {
  return (
    <div className="card" style={{ overflow: 'hidden' }}>
      {PERM_MODULES.map((mod, ix) => (
        <div key={mod} className="row" style={{ justifyContent: 'space-between', padding: '10px 16px', borderTop: ix ? '1px solid var(--line)' : 'none' }}>
          <span style={{ fontWeight: 600, fontSize: 13.5 }}>{mod}</span>
          <span style={{ fontWeight: 700, fontSize: 13, color: perms[mod] === 'None' ? 'var(--ink-3)' : perms[mod] === 'Manage' ? 'var(--ok)' : 'var(--info)' }}>{perms[mod]}</span>
        </div>
      ))}
    </div>
  );
}

function InviteModal({ close, data }) {
  const D = window.DATA;
  const onDone = data && data.onDone;
  const { data: branches } = useBranches();

  // A branch manager may only invite roles below them, into their own branch.
  const isSuper    = api.isSuperAdmin();
  const myBranchId = (api.user && api.user.branch_id) || '';

  const [email,  setEmail]  = useState('');
  const [phone,  setPhone]  = useState('');
  const [role,   setRole]   = useState('Sales Executive');
  const [branch, setBranch] = useState(!isSuper ? myBranchId : '');
  const [method, setMethod] = useState('Email');
  const [busy,        setBusy]       = useState(false);
  const [sentLink,    setSentLink]   = useState('');
  const [sentPreview, setSentPreview] = useState('');
  const [waUrl,       setWaUrl]      = useState('');
  const [waSent,      setWaSent]     = useState(false); // delivered via branch gateway
  const [waFrom,      setWaFrom]     = useState('');

  React.useEffect(() => {
    if (branch) return;
    if (!isSuper && myBranchId) setBranch(myBranchId);
    else if (branches.length)  setBranch(branches[0].id);
  }, [branches.length]);

  // Roles this user may assign: never Owner; non-super also never Branch Manager
  const assignableRoles = ROLES.filter(r => r.key !== 'Owner' && (isSuper || r.key !== 'Branch Manager'));
  const roleObj = ROLES.find(r => r.key === role) || ROLES[2];

  // Build WhatsApp/SMS URL from link and phone
  const buildDeliveryUrl = (link) => {
    if (!phone.trim()) return '';
    const msg = `You've been invited to join Electromed Corporation as ${role}.\n\nSet up your account:\n${link}\n\n(Valid 7 days)`;
    const num = phone.replace(/\D/g, '');
    const n   = num.startsWith('92') ? num : '92' + num.replace(/^0/, '');
    if (method === 'WhatsApp') return `https://wa.me/${n}?text=${encodeURIComponent(msg)}`;
    if (method === 'SMS')      return `sms:+${n}?body=${encodeURIComponent(msg)}`;
    return '';
  };

  const send = async () => {
    if (!email.trim()) { window.toast('Email address is required', 'warn'); return; }
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())) { window.toast('Enter a valid email address', 'warn'); return; }
    if ((method === 'WhatsApp' || method === 'SMS') && !phone.trim()) {
      window.toast('Phone number is required for ' + method, 'warn'); return;
    }
    setBusy(true);
    try {
      const res = await api.createInvite({
        email: email.trim(), role,
        branch_id: branch,
        permissions: roleObj.perms,
        method,
        phone: phone.trim(),
      });
      setSentLink(res.link);
      setSentPreview(res.emailPreviewUrl || '');
      setWaSent(!!res.whatsappSent);
      setWaFrom(res.whatsappFrom || '');
      // Only offer the manual wa.me link when the gateway did NOT auto-send
      setWaUrl(res.whatsappSent ? '' : buildDeliveryUrl(res.link));
      if (onDone) onDone();
      window.toast('Invite created for ' + email.trim(), 'ok');
    } catch (err) {
      window.toast(err.message || 'Failed to create invite', 'error');
      setBusy(false);
    }
  };

  if (sentLink) {
    const isEmail = method === 'Email';
    const isWA    = method === 'WhatsApp';
    const isSMS   = method === 'SMS';

    return (
      <Modal wide title="Invite Ready ✓" sub={`For ${email} · ${role}`} onClose={close}
        foot={<Btn variant="primary" icon={<Icons.check size={16} />} onClick={close}>Done</Btn>}>
        <div style={{ display: 'grid', gap: 14 }}>

          {/* WhatsApp auto-delivered from the branch's linked number */}
          {isWA && waSent && (
            <div className="row" style={{ gap: 10, padding: '14px 16px', background: 'var(--ok-bg)', border: '1px solid var(--ok)', borderRadius: 12 }}>
              <span style={{ fontSize: 20 }}>✅</span>
              <div>
                <div style={{ fontWeight: 700, color: 'var(--ok)' }}>Invite sent on WhatsApp</div>
                <div className="tiny muted" style={{ marginTop: 2 }}>Delivered to {phone} from your branch's linked WhatsApp{waFrom ? ` (${waFrom})` : ''}.</div>
              </div>
            </div>
          )}

          {/* Branch number not linked → offer manual send + hint */}
          {isWA && !waSent && (
            <div className="tiny muted" style={{ padding: '10px 13px', background: 'var(--warn-bg)', border: '1px solid var(--warn)', borderRadius: 10, lineHeight: 1.55 }}>
              Your branch's WhatsApp isn't linked, so this couldn't be sent automatically. Use the button below (sends from your own WhatsApp), or link a number in <b>Settings → Transaction Messages</b> to auto-send from the business number.
            </div>
          )}

          {/* WhatsApp / SMS — manual send link (fallback / SMS) */}
          {(isWA || isSMS) && waUrl && (
            <a href={waUrl} target="_blank" rel="noreferrer" style={{
              display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 12,
              padding: '16px 20px', borderRadius: 14, textDecoration: 'none',
              background: isWA ? '#25D366' : '#0A84FF', color: '#fff',
              fontWeight: 800, fontSize: 16,
            }}>
              <span style={{ fontSize: 22 }}>{isWA ? '💬' : '📱'}</span>
              {isWA ? 'Send via WhatsApp' : 'Send via SMS'} →
            </a>
          )}

          {/* Email status */}
          {isEmail && sentPreview && (
            <div style={{ padding: '14px 16px', background: 'var(--warn-bg)', border: '1px solid var(--warn)', borderRadius: 12 }}>
              <div style={{ fontWeight: 700, color: 'var(--warn)', marginBottom: 6 }}>⚠ SMTP Password Not Set</div>
              <div className="tiny muted" style={{ marginBottom: 10, lineHeight: 1.6 }}>
                Email preview is ready. To send <b>real emails</b>, go to <b>Settings → Email Settings</b> and enter your Gmail App Password, then resend.
              </div>
              <div className="row" style={{ gap: 8 }}>
                <a href={sentPreview} target="_blank" rel="noreferrer" style={{ display: 'inline-block', padding: '9px 16px', background: 'var(--warn)', color: '#fff', borderRadius: 9, fontWeight: 700, fontSize: 13, textDecoration: 'none' }}>Preview Email in Browser ↗</a>
              </div>
            </div>
          )}
          {isEmail && !sentPreview && (
            <div className="row" style={{ gap: 10, padding: '13px 15px', background: 'var(--ok-bg)', border: '1px solid var(--ok)', borderRadius: 12 }}>
              <Icons.check size={18} style={{ color: 'var(--ok)', flexShrink: 0 }} />
              <div style={{ fontWeight: 700 }}>Email sent to <b>{email}</b></div>
            </div>
          )}

          {/* Invite link to copy */}
          <div style={{ background: 'var(--surface-2)', borderRadius: 12, padding: '14px 16px' }}>
            <div className="tiny muted" style={{ fontWeight: 700, marginBottom: 8 }}>INVITE LINK — share as backup (valid 7 days)</div>
            <div className="row" style={{ gap: 8 }}>
              <input className="input-block mono" style={{ flex: 1, fontSize: 11 }} value={sentLink} readOnly onClick={e => e.target.select()} />
              <Btn variant="ghost" onClick={() => { navigator.clipboard.writeText(sentLink); window.toast('Link copied!', 'ok'); }}>Copy</Btn>
            </div>
          </div>

          <div className="tiny muted" style={{ padding: '10px 12px', background: 'var(--surface-2)', borderRadius: 10, lineHeight: 1.6 }}>
            <b>What happens next:</b> Invitee clicks the link → enters their name + creates a password → account is created with <b>{role}</b> access → they are signed in immediately.
          </div>
        </div>
      </Modal>
    );
  }

  return (
    <Modal wide title="Invite User" sub="Send an access invitation to a new team member" onClose={close}
      foot={<><Btn variant="ghost" onClick={close}>Cancel</Btn><Btn variant="primary" icon={<Icons.bell size={16} />} onClick={send} disabled={busy}>{busy ? 'Sending…' : 'Send Invite'}</Btn></>}>
      <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 18 }}>
        <div style={{ display: 'grid', gap: 14, alignContent: 'start' }}>

          <Fld label="Email Address (required)">
            <input className="input-block" type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="name@electromed.pk" autoFocus />
          </Fld>

          <Fld label="Deliver Invite Via">
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8 }}>
              {['Email', 'WhatsApp', 'SMS'].map(m => (
                <button key={m} type="button" onClick={() => setMethod(m)} style={{
                  padding: '10px 6px', borderRadius: 11, fontWeight: 700, fontSize: 13,
                  border: method === m ? '2px solid var(--lime-700)' : '2px solid var(--line)',
                  background: method === m ? 'var(--lime-soft)' : 'var(--surface-2)',
                  color: method === m ? 'var(--lime-700)' : 'var(--ink-2)', cursor: 'pointer',
                }}>
                  {m === 'Email' ? '✉ Email' : m === 'WhatsApp' ? '💬 WhatsApp' : '📱 SMS'}
                </button>
              ))}
            </div>
          </Fld>

          {(method === 'WhatsApp' || method === 'SMS') && (
            <Fld label={`Phone Number — for ${method}`}>
              <input className="input-block mono" value={phone} onChange={e => setPhone(e.target.value)}
                placeholder="0312-1234567 or +923121234567" autoFocus />
              <div className="tiny muted" style={{ marginTop: 5 }}>Pakistan number — starts with 03xx or +923xx</div>
            </Fld>
          )}

          {method === 'Email' && (
            <div style={{ padding: '11px 13px', background: 'var(--surface-2)', borderRadius: 10 }}>
              <div className="tiny muted" style={{ lineHeight: 1.55 }}>
                A branded invite email will be sent to <b>{email || 'the address above'}</b>.
                If your SMTP is not yet configured, a preview link will be shown instead.
              </div>
            </div>
          )}

          <Fld label="Assign Role">
            <select className="input-block" value={role} onChange={e => setRole(e.target.value)}>
              {assignableRoles.map(r => <option key={r.key}>{r.key}</option>)}
            </select>
          </Fld>
          <Fld label="Home Branch">
            {isSuper ? (
              <select className="input-block" value={branch} onChange={e => setBranch(e.target.value)}>
                <option value="All">All Branches</option>
                {branches.map(b => <option key={b.id} value={b.id}>{b.label || b.city || b.name}</option>)}
              </select>
            ) : (
              <div className="input-block" style={{ background: 'var(--surface-2)', color: 'var(--ink-2)', cursor: 'default', display: 'flex', alignItems: 'center', gap: 8 }}>
                <Icons.pin size={14} style={{ color: 'var(--ink-3)', flexShrink: 0 }} />
                {(branches.find(b => String(b.id) === String(myBranchId)) || {}).city ||
                 (branches.find(b => String(b.id) === String(myBranchId)) || {}).name || 'Your branch'}
                <span className="tiny muted" style={{ marginLeft: 'auto' }}>locked to your branch</span>
              </div>
            )}
          </Fld>
        </div>

        <div>
          <div className="row" style={{ gap: 8, marginBottom: 10 }}>
            <Icons.shield size={16} style={{ color: roleObj.color }} />
            <span style={{ fontWeight: 800, fontSize: 14 }}>{roleObj.key} can…</span>
          </div>
          <PermPreview perms={roleObj.perms} />
        </div>
      </div>
    </Modal>
  );
}

function AccessModal({ data: m, close }) {
  const onDone = m.onDone;
  const { data: branches } = useBranches();
  const isSuper = api.isSuperAdmin();
  const base = ROLES.find((r) => r.key === m.role) || ROLES[2];
  const [name,         setName]         = useState(m.name || '');
  const [email,        setEmail]        = useState(m.email || '');
  const [role,         setRole]         = useState(m.role);
  const [perms,        setPerms]        = useState(() => ({ ...base.perms }));
  const [branch,       setBranch]       = useState(m.branch_id || 'All');
  const [busy,         setBusy]         = useState(false);
  const [loadingPerms, setLoadingPerms] = useState(false);
  const isOwner = m.role === 'Owner';

  // Load real effective permissions from backend on open
  useEffect(() => {
    if (!m.isUser || isOwner) return;
    setLoadingPerms(true);
    api.getUserPermissions(m.id).then(data => {
      const eff = data.effective || {};
      const derived = {};
      for (const [displayMod, { mod }] of Object.entries(MOD_MAP)) {
        const modPerms = eff[mod] || {};
        const hasManage = ['create','edit','delete'].some(a => modPerms[a] && modPerms[a].granted);
        const hasView   = modPerms['view'] && modPerms['view'].granted;
        derived[displayMod] = hasManage ? 'Manage' : hasView ? 'View' : 'None';
      }
      setPerms(derived);
    }).catch(() => {}).finally(() => setLoadingPerms(false));
  }, [m.id]);

  const applyRole = (rk) => {
    setRole(rk);
    const r = ROLES.find((x) => x.key === rk);
    if (r) setPerms({ ...r.perms });
  };

  const saveAccess = async () => {
    if (!m.isUser) return;
    if (!name.trim()) { window.toast('Name is required', 'warn'); return; }
    setBusy(true);
    try {
      await api.updateUser(m.id, {
        name:      name.trim(),
        role,
        branch_id: branch === 'All' ? null : branch,
      });
      // Granular per-module overrides are an admin-only capability
      // (users:assign_permissions). Branch managers manage their team by
      // assigning a ROLE — its permission set applies automatically.
      if (isSuper) {
        const permArray = [];
        for (const [displayMod, { mod, manageActions }] of Object.entries(MOD_MAP)) {
          const level   = perms[displayMod] || 'None';
          const granted = level === 'None' ? [] : level === 'View' ? ['view'] : manageActions;
          for (const action of ALL_ACTIONS) {
            permArray.push({ module: mod, action, granted: granted.includes(action) });
          }
        }
        await api.setUserPermissions(m.id, permArray);
      }
      window.toast('Access updated for ' + name.trim(), 'ok');
      if (onDone) onDone();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed to update access', 'error');
      setBusy(false);
    }
  };

  // ── Permission-gated destructive actions ──────────────────────────
  const isActive      = m.status === 'Active';
  const canSuspend    = !m.you && m.isUser && !isOwner && window.can('users', 'edit');
  const canDelete     = !m.you && m.isUser && !isOwner && window.can('users', 'delete');

  const doSuspend = async () => {
    const action = isActive ? 'Suspend' : 'Reactivate';
    if (!window.confirm(action + ' ' + m.name + '? ' + (isActive ? 'They will not be able to log in.' : 'They will regain access.'))) return;
    setBusy(true);
    try {
      await api.updateUserStatus(m.id, isActive ? 'suspended' : 'active');
      window.toast(m.name + (isActive ? ' suspended' : ' reactivated'), 'ok');
      if (onDone) onDone();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed', 'error');
      setBusy(false);
    }
  };

  const doDelete = async () => {
    if (!window.confirm('Permanently delete ' + m.name + '?\n\nThis cannot be undone. All their data remains but the account is removed.')) return;
    setBusy(true);
    try {
      await api.deleteUser(m.id);
      window.toast(m.name + ' deleted', 'ok');
      if (onDone) onDone();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed to delete user', 'error');
      setBusy(false);
    }
  };

  const doRevokeInvite = async () => {
    if (!window.confirm('Revoke the invite for ' + m.email + '?')) return;
    setBusy(true);
    try {
      await api.revokeInvite(m.inviteId || m.id);
      window.toast('Invite revoked', 'ok');
      if (onDone) onDone();
      close();
    } catch (err) {
      window.toast(err.message || 'Failed to revoke invite', 'error');
      setBusy(false);
    }
  };

  return (
    <Modal wide title={m.name} sub={m.email} onClose={close}
      foot={<>
        <div className="row" style={{ gap: 8, marginRight: 'auto' }}>
          {canSuspend && (
            <Btn variant="ghost" style={{ color: isActive ? 'var(--warn)' : 'var(--ok)' }} onClick={doSuspend} disabled={busy}>
              {isActive ? 'Suspend' : 'Reactivate'}
            </Btn>
          )}
          {canDelete && (
            <Btn variant="ghost" style={{ color: 'var(--bad)' }} onClick={doDelete} disabled={busy}>
              Delete User
            </Btn>
          )}
          {!m.isUser && m.status === 'Invited' && (
            <Btn variant="ghost" style={{ color: 'var(--bad)' }} onClick={doRevokeInvite} disabled={busy}>
              Revoke Invite
            </Btn>
          )}
        </div>
        <Btn variant="ghost" onClick={close}>Cancel</Btn>
        {m.isUser && <Btn variant="primary" icon={<Icons.check size={16} />} onClick={saveAccess} disabled={busy || isOwner}>{busy ? 'Saving…' : 'Save Changes'}</Btn>}
      </>}>
      <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 14, marginBottom: 14 }}>
        <Fld label="Full Name"><input className="input-block" value={name} onChange={e => setName(e.target.value)} disabled={isOwner} placeholder="Full name" /></Fld>
        <Fld label="Email Address"><input className="input-block" type="email" value={email} onChange={e => setEmail(e.target.value)} disabled={isOwner} placeholder="email@example.com" /></Fld>
      </div>
      <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 14, marginBottom: 18 }}>
        <Fld label="Role"><select className="input-block" value={role} onChange={(e) => applyRole(e.target.value)} disabled={isOwner}>{(isSuper ? ROLES : ROLES.filter(r => r.key !== 'Owner' && r.key !== 'Branch Manager')).map((r) => <option key={r.key}>{r.key}</option>)}</select></Fld>
        <Fld label="Branch Access">
          {isSuper ? (
            <select className="input-block" value={branch} onChange={(e) => setBranch(e.target.value)} disabled={isOwner}><option value="All">All Branches</option>{branches.map((b) => <option key={b.id} value={b.id}>{b.label || b.city || b.name}</option>)}</select>
          ) : (
            <div className="input-block" style={{ background: 'var(--surface-2)', color: 'var(--ink-2)', cursor: 'default', display: 'flex', alignItems: 'center', gap: 8 }}>
              <Icons.pin size={14} style={{ color: 'var(--ink-3)', flexShrink: 0 }} />
              {(branches.find(b => String(b.id) === String(branch)) || {}).city || (branches.find(b => String(b.id) === String(branch)) || {}).name || 'Your branch'}
              <span className="tiny muted" style={{ marginLeft: 'auto' }}>locked</span>
            </div>
          )}
        </Fld>
      </div>
      {isOwner && <div className="row" style={{ gap: 10, padding: '12px 15px', background: 'var(--lime-soft, #e8f8f0)', borderRadius: 12, marginBottom: 14 }}><Icons.shield size={17} style={{ color: 'var(--lime-700)' }} /><span className="tiny" style={{ fontWeight: 600 }}>Owner access can't be reduced.</span></div>}
      {!m.isUser && m.status === 'Invited' && <div className="row" style={{ gap: 10, padding: '12px 15px', background: 'var(--warn-bg)', borderRadius: 12, marginBottom: 14 }}><Icons.clock size={17} style={{ color: 'var(--warn)' }} /><span className="tiny" style={{ fontWeight: 600 }}>Invite pending — user has not accepted yet.</span></div>}
      <div className="tiny muted" style={{ fontWeight: 700, marginBottom: 10 }}>
        MODULE PERMISSIONS{loadingPerms && <span style={{ fontWeight: 400 }}> · loading…</span>}
        {!isSuper && <span style={{ fontWeight: 400 }}> · set by the assigned role</span>}
      </div>
      {!isSuper && (
        <div className="row" style={{ gap: 10, padding: '11px 14px', background: 'var(--surface-2)', borderRadius: 10, marginBottom: 10 }}>
          <Icons.shield size={16} style={{ color: 'var(--ink-3)', flexShrink: 0 }} />
          <span className="tiny muted">These follow the <b>role</b> you assign above. Custom per-module overrides require an administrator.</span>
        </div>
      )}
      <div className="card" style={{ overflow: 'hidden' }}>
        {PERM_MODULES.map((mod, ix) => (
          <div key={mod} className="row" style={{ justifyContent: 'space-between', padding: '12px 16px', borderTop: ix ? '1px solid var(--line)' : 'none' }}>
            <span style={{ fontWeight: 700 }}>{mod}</span>
            <PermSeg value={isOwner ? 'Manage' : (perms[mod] || 'None')} disabled={isOwner || !m.isUser || loadingPerms || !isSuper} onChange={(v) => setPerms((p) => ({ ...p, [mod]: v }))} />
          </div>
        ))}
      </div>
    </Modal>
  );
}

function RoleModal({ data: r, close }) {
  const [perms, setPerms] = useState(() => ({ ...r.perms }));
  // Role TEMPLATES are global (apply to every branch) → editing is admin-only.
  // Branch managers view role definitions here and ASSIGN them from Members.
  const isSuper  = api.isSuperAdmin();
  const viewOnly = r.key === 'Owner' || !isSuper;
  return (
    <Modal wide title={r.key} sub={`${r.members} ${r.members === 1 ? 'user' : 'users'} · ${r.desc}`} onClose={close}
      foot={viewOnly ? <Btn variant="ghost" onClick={close}>Close</Btn> : <><Btn variant="ghost" onClick={close}>Cancel</Btn><Btn variant="primary" icon={<Icons.check size={16} />} onClick={close}>Save Role</Btn></>}>
      {r.key === 'Owner' && <div className="row" style={{ gap: 10, padding: '12px 15px', background: 'var(--surface-2)', borderRadius: 12, marginBottom: 14 }}><Icons.shield size={17} style={{ color: r.color }} /><span className="tiny" style={{ fontWeight: 600 }}>The Owner role is system-defined and always has full access.</span></div>}
      {!isSuper && r.key !== 'Owner' && <div className="row" style={{ gap: 10, padding: '12px 15px', background: 'var(--surface-2)', borderRadius: 12, marginBottom: 14 }}><Icons.shield size={17} style={{ color: 'var(--ink-3)' }} /><span className="tiny" style={{ fontWeight: 600 }}>Role definitions are global and managed by an administrator. To change a person's access, assign them a role from the <b>Members</b> tab.</span></div>}
      <div className="card" style={{ overflow: 'hidden' }}>
        {PERM_MODULES.map((mod, ix) => (
          <div key={mod} className="row" style={{ justifyContent: 'space-between', padding: '12px 16px', borderTop: ix ? '1px solid var(--line)' : 'none' }}>
            <span style={{ fontWeight: 700 }}>{mod}</span>
            <PermSeg value={r.key === 'Owner' ? 'Manage' : perms[mod]} disabled={viewOnly} onChange={(v) => setPerms((p) => ({ ...p, [mod]: v }))} />
          </div>
        ))}
      </div>
    </Modal>
  );
}

window.Settings = Settings;

/* ---------- Help & Support page ---------- */
function Help({ go }) {
  const D = window.DATA;
  const faqs = [
    ['How do I issue a GST vs non-GST invoice?', 'In Sales → New Sale, pick the company letterhead and toggle GST / Non-GST at the Invoice step. Existing invoices can be switched from the invoice detail view.'],
    ['How does consignment stock work?', 'Inventory → Stock Movements → Move Stock → Consignment. Units stay on your books until the distributor sells and settles them.'],
    ['Where are sleep-test reports stored?', 'Sales → Sleep Tests. Open a study to view AHI, SpO₂, diagnosis and recommendation, or upload a pending report.'],
    ['How are rent reminders triggered?', 'Settings → Reminders sets the lead time. The scheduler auto-notifies the customer via SMS / WhatsApp before the due date.'],
  ];
  return (
    <div className="view-enter">
      <PageHead eyebrow="System · Support" title="Help & Support"
        sub="Guides, contacts and platform status for the Electromed team." />
      <div className="grid" style={{ gridTemplateColumns: 'repeat(3,1fr)', marginBottom: 18 }}>
        {[[Icons.phone, 'Call support', '+92 21 111 327 327', 'Mon–Sat · 9am–7pm'], [Icons.bell, 'Email us', 'support@electromed.pk', 'Replies within 4 hrs'], [Icons.spark, 'Platform status', 'All systems operational', 'v2.4 · updated today']].map(([Ic, t, v, s], ix) => (
          <div key={ix} className="card card-pad">
            <div style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--lime-soft)', display: 'grid', placeItems: 'center', marginBottom: 12 }}><Ic size={19} style={{ color: 'var(--lime-700)' }} /></div>
            <div className="tiny muted" style={{ fontWeight: 700 }}>{t}</div>
            <div style={{ fontWeight: 800, fontSize: 16, marginTop: 3 }}>{v}</div>
            <div className="tiny muted" style={{ marginTop: 3 }}>{s}</div>
          </div>
        ))}
      </div>
      <div className="card">
        <div className="card-pad" style={{ paddingBottom: 6 }}><div style={{ fontWeight: 800, fontSize: 17 }}>Frequently Asked</div></div>
        {faqs.map(([q, a], ix) => (
          <div key={ix} style={{ padding: '14px 22px', borderTop: '1px solid var(--line)' }}>
            <div className="row" style={{ gap: 9, fontWeight: 700, marginBottom: 5 }}><Icons.help size={16} style={{ color: 'var(--lime-700)', flexShrink: 0 }} />{q}</div>
            <div className="tiny muted" style={{ paddingLeft: 25, lineHeight: 1.55 }}>{a}</div>
          </div>
        ))}
      </div>
    </div>
  );
}
window.Help = Help;
