// Domain Dropdown + Add Domain modal + Manage Domains modal + Settings drawer

const Badge = ({ kind }) => {
  const map = {
    TOP: { bg: '#3a2a08', color: '#F59E0B', border: '#5c3e08' },
    NEW: { bg: '#0a3a33', color: '#14B8A6', border: '#0f5048' },
    HOT: { bg: '#0c2a4a', color: '#60A5FA', border: '#1e3f6b' },
  };
  const s = map[kind];
  return (
    <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9, letterSpacing: '0.12em', fontWeight: 600, padding: '2px 6px', borderRadius: 3, background: s.bg, color: s.color, border: `1px solid ${s.border}` }}>{kind}</span>
  );
};

const DomainDropdown = ({ open, onClose, domains, currentDomain, onSelect, onAddDomain, onToggleFav, onShowDns, onReverify, onRemove }) => {
  const [query, setQuery] = React.useState('');

  if (!open) return null;

  const filter = (list) => list.filter((d) => d.domain.includes(query.toLowerCase()));
  const customFiltered = filter(domains.custom);
  const sharedFiltered = filter(domains.shared);

  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 50 }} />
      <div style={{
        position: 'absolute', top: 46, right: 0, width: 420,
        background: '#141414', border: '1px solid #262626', borderRadius: 8,
        boxShadow: '0 10px 40px rgba(0,0,0,0.6)', zIndex: 51, overflow: 'hidden',
        animation: 'slideDown 150ms ease',
      }}>
        {/* Search */}
        <div style={{ padding: 10, borderBottom: '1px solid #1f1f1f', display: 'flex', alignItems: 'center', gap: 8 }}>
          <IconSearch size={13} stroke="#565656" />
          <input
            autoFocus
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="Search domains…"
            style={{ flex: 1, background: 'none', border: 'none', outline: 'none', color: '#EDEDED', fontFamily: "'JetBrains Mono', monospace", fontSize: 12 }}
          />
          <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9, color: '#404040', border: '1px solid #262626', padding: '2px 5px', borderRadius: 3 }}>ESC</span>
        </div>

        <div style={{ maxHeight: 420, overflowY: 'auto' }}>
          {/* Custom Domains */}
          {customFiltered.length > 0 && (
            <div>
              <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9, letterSpacing: '0.2em', color: '#565656', padding: '10px 14px 6px' }}>
                YOUR CUSTOM DOMAINS
              </div>
              {customFiltered.map((d) => (
                <DomainRow
                  key={d.id}
                  d={d}
                  current={currentDomain === d.domain}
                  onSelect={() => onSelect(d.domain)}
                  onToggleFav={() => onToggleFav(d.id, 'custom')}
                  onShowDns={onShowDns ? () => onShowDns(d) : undefined}
                  onReverify={onReverify ? () => onReverify(d) : undefined}
                  onRemove={onRemove ? () => onRemove(d) : undefined}
                />
              ))}
            </div>
          )}

          {/* Shared Domains */}
          {sharedFiltered.length > 0 && (
            <div>
              <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9, letterSpacing: '0.2em', color: '#565656', padding: '10px 14px 6px', borderTop: customFiltered.length > 0 ? '1px solid #1f1f1f' : 'none', marginTop: customFiltered.length > 0 ? 4 : 0 }}>
                SHARED DOMAINS · {sharedFiltered.length}
              </div>
              {sharedFiltered.map((d) => (
                <DomainRow key={d.id} d={d} current={currentDomain === d.domain} onSelect={() => onSelect(d.domain)} onToggleFav={() => onToggleFav(d.id, 'shared')} />
              ))}
            </div>
          )}
        </div>

        <button
          onClick={onAddDomain}
          style={{
            width: '100%', padding: '12px 14px', background: '#0f0f0f', border: 'none', borderTop: '1px solid #1f1f1f',
            color: '#EDEDED', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 8,
            fontFamily: "'Geist', system-ui, sans-serif", fontSize: 13, transition: 'background 120ms',
          }}
          onMouseEnter={(e) => (e.currentTarget.style.background = '#181818')}
          onMouseLeave={(e) => (e.currentTarget.style.background = '#0f0f0f')}
        >
          <IconPlus size={14} /> Add custom domain
        </button>
      </div>
    </>
  );
};

const DomainRow = ({ d, current, onSelect, onToggleFav, onShowDns, onReverify, onRemove }) => {
  const [hovered, setHovered] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const menuRef = React.useRef(null);

  // Close menu on click outside
  React.useEffect(() => {
    if (!menuOpen) return;
    const onDocClick = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false); };
    const onEsc = (e) => { if (e.key === 'Escape') setMenuOpen(false); };
    document.addEventListener('mousedown', onDocClick);
    document.addEventListener('keydown', onEsc);
    return () => {
      document.removeEventListener('mousedown', onDocClick);
      document.removeEventListener('keydown', onEsc);
    };
  }, [menuOpen]);

  const isCustom = !!d.status;   // shared domains have no `status` field

  return (
    <div
      onClick={onSelect}
      onMouseEnter={(e) => { setHovered(true); if (!current) e.currentTarget.style.background = '#161616'; }}
      onMouseLeave={(e) => { setHovered(false); if (!current) e.currentTarget.style.background = 'transparent'; }}
      style={{
        display: 'flex', alignItems: 'center', gap: 10, padding: '9px 14px',
        cursor: 'pointer', borderLeft: `2px solid ${current ? '#10B981' : 'transparent'}`,
        background: current ? '#181818' : 'transparent', transition: 'background 100ms',
        position: 'relative',
      }}
    >
      <div style={{ width: 14, display: 'flex', justifyContent: 'center' }}>
        {d.premium ? <IconCrown size={12} stroke="#F59E0B" /> : null}
      </div>
      <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#EDEDED', flex: 1 }}>@{d.domain}</span>
      {d.status === 'pending' && <Badge kind="NEW" />}
      {d.badges?.map((b) => <Badge key={b} kind={b} />)}

      {/* Kebab menu — only for custom domains the user controls */}
      {isCustom && (
        <div ref={menuRef} style={{ position: 'relative' }}>
          <button
            onClick={(e) => { e.stopPropagation(); setMenuOpen((v) => !v); }}
            title="Domain actions"
            style={{
              background: menuOpen ? '#262626' : 'none', border: 'none', cursor: 'pointer',
              color: hovered || menuOpen ? '#EDEDED' : 'transparent',
              opacity: hovered || menuOpen ? 1 : 0,
              padding: 4, borderRadius: 3, display: 'flex', alignItems: 'center',
              transition: 'opacity 120ms, color 120ms, background 120ms',
            }}
          >
            <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
              <circle cx="12" cy="6" r="1.6" />
              <circle cx="12" cy="12" r="1.6" />
              <circle cx="12" cy="18" r="1.6" />
            </svg>
          </button>
          {menuOpen && (
            <div
              onClick={(e) => e.stopPropagation()}
              style={{
                position: 'absolute', top: '100%', right: 0, marginTop: 4, zIndex: 60,
                background: '#0f0f0f', border: '1px solid #262626', borderRadius: 6,
                boxShadow: '0 8px 24px rgba(0,0,0,0.6)', minWidth: 180, overflow: 'hidden',
                animation: 'slideDown 120ms ease',
              }}
            >
              <DomainMenuItem onClick={() => { onShowDns && onShowDns(); setMenuOpen(false); }}>DNS records</DomainMenuItem>
              <DomainMenuItem onClick={() => { onReverify && onReverify(); setMenuOpen(false); }}>Re-verify</DomainMenuItem>
              <div style={{ borderTop: '1px solid #1f1f1f' }} />
              <DomainMenuItem
                danger
                onClick={() => {
                  if (confirm(`Remove @${d.domain}? Mail to this domain will stop being received.`)) {
                    onRemove && onRemove();
                  }
                  setMenuOpen(false);
                }}
              >
                Remove domain
              </DomainMenuItem>
            </div>
          )}
        </div>
      )}

      <button
        onClick={(e) => { e.stopPropagation(); onToggleFav(); }}
        style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, color: d.favorited ? '#F59E0B' : '#3a3a3a', display: 'flex' }}
      >
        <IconStar size={13} filled={d.favorited} />
      </button>
    </div>
  );
};

const DomainMenuItem = ({ children, onClick, danger }) => (
  <button
    onClick={onClick}
    style={{
      width: '100%', textAlign: 'left', padding: '9px 14px', fontSize: 12,
      fontFamily: "'Geist', system-ui, sans-serif", color: danger ? '#DC2626' : '#EDEDED',
      background: 'transparent', border: 'none', cursor: 'pointer',
      transition: 'background 100ms',
    }}
    onMouseEnter={(e) => (e.currentTarget.style.background = danger ? '#2a0e0e' : '#1a1a1a')}
    onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}
  >
    {children}
  </button>
);

//
// SHOW DNS RECORDS MODAL — re-open the DNS records for an existing custom domain
// at any time. Reuses the same DnsRow component as the add flow.
//
const ShowDnsRecordsModal = ({ open, onClose, domain, records }) => {
  if (!open || !records) return null;
  return (
    <ModalShell onClose={onClose} title={`DNS records for @${domain}`} subtitle="SET THESE AT YOUR DNS PROVIDER">
      <div style={{ padding: 24 }}>
        <p style={{ fontSize: 12, color: '#8A8A8A', margin: '0 0 16px', lineHeight: 1.5 }}>
          Each chip maps to a separate field in the registrar's UI (Type / Host / Mail Server / Priority).
        </p>
        <DnsRow
          type="MX"
          host={records.mx.host}
          value={records.mx.mailServer}
          priority={String(records.mx.priority ?? 10)}
          valueLabel="MAIL SERVER"
          note="Routes inbound mail to the relay."
        />
        <DnsRow
          type="TXT"
          host={records.txt.host}
          value={records.txt.value}
          note="Proves you own the domain."
        />
        <div style={{ marginTop: 8, padding: 12, background: '#0c1f2e', border: '1px solid #1e3f6b', borderRadius: 6 }}>
          <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.18em', color: '#60A5FA', marginBottom: 6 }}>VERIFY WITH</div>
          <code style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, color: '#EDEDED', display: 'block' }}>dig {domain} MX +short</code>
          <code style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, color: '#EDEDED', display: 'block', marginTop: 4 }}>dig _tempmail.{domain} TXT +short</code>
        </div>
      </div>
    </ModalShell>
  );
};

//
// ADD DOMAIN MODAL (multi-step)
//
const AddDomainModal = ({ open, onClose, onAdd }) => {
  const [step, setStep] = React.useState(1);
  const [domain, setDomain] = React.useState('');
  const [verifying, setVerifying] = React.useState(false);
  const [verifyResult, setVerifyResult] = React.useState(null);    // null | 'success' | { missing: string[] }
  const [registering, setRegistering] = React.useState(false);
  const [error, setError] = React.useState('');
  const [domainId, setDomainId] = React.useState(null);
  const [records, setRecords] = React.useState(null);              // { mx: {host, value}, txt: {host, value} }

  React.useEffect(() => {
    if (open) {
      setStep(1); setDomain(''); setVerifyResult(null); setError('');
      setDomainId(null); setRecords(null); setVerifying(false); setRegistering(false);
    }
  }, [open]);

  if (!open) return null;

  const valid = /^[a-z0-9][a-z0-9-]*(\.[a-z0-9][a-z0-9-]*)+$/i.test(domain);

  const goToStep2 = async () => {
    if (!valid || registering) return;
    setRegistering(true); setError('');
    try {
      const res = await tmApi.customer.addDomain(domain);
      setDomainId(res.id);
      setRecords(res.verificationRecords);
      setStep(2);
    } catch (e) {
      const code = e.code || 'http_error';
      if (code === 'domain_in_use') setError('This domain is already registered (by you or another user).');
      else if (code === 'rate_limited') setError('Too many domain additions. Try again later.');
      else setError(e.message || 'Could not add domain.');
    } finally {
      setRegistering(false);
    }
  };

  const runVerify = async () => {
    if (!domainId || verifying) return;
    setVerifying(true); setError('');
    try {
      const res = await tmApi.customer.verifyDomain(domainId);
      if (res.status === 'verified') {
        setVerifyResult('success');
        setStep(3);
      } else {
        setVerifyResult({ missing: res.missing || [] });
      }
    } catch (e) {
      setError(e.message || 'Verification check failed.');
    } finally {
      setVerifying(false);
    }
  };

  return (
    <ModalShell onClose={onClose} title="Add custom domain" subtitle={`Step ${step} of 3`}>
      {/* Stepper */}
      <div style={{ display: 'flex', gap: 6, padding: '0 24px 20px', borderBottom: '1px solid #1f1f1f' }}>
        {[1, 2, 3].map((n) => (
          <div key={n} style={{
            flex: 1, height: 2, borderRadius: 1,
            background: step >= n ? '#10B981' : '#262626',
            transition: 'background 200ms',
          }} />
        ))}
      </div>

      {step === 1 && (
        <div style={{ padding: 24 }}>
          <label style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.2em', color: '#8A8A8A', display: 'block', marginBottom: 10 }}>DOMAIN</label>
          <input
            autoFocus
            value={domain}
            onChange={(e) => { setDomain(e.target.value.toLowerCase().trim()); setError(''); }}
            onKeyDown={(e) => e.key === 'Enter' && valid && goToStep2()}
            placeholder="example.com"
            disabled={registering}
            style={{ width: '100%', background: '#0a0a0a', border: `1px solid ${(domain && !valid) || error ? '#DC2626' : '#262626'}`, color: '#EDEDED', fontFamily: "'JetBrains Mono', monospace", fontSize: 14, padding: '12px 14px', borderRadius: 6, outline: 'none', boxSizing: 'border-box' }}
          />
          <p style={{ fontSize: 12, color: '#565656', margin: '12px 0 0', lineHeight: 1.5 }}>
            Enter the root domain you control. You'll add MX + TXT records next.
          </p>
          {error && <p style={{ fontSize: 12, color: '#DC2626', margin: '10px 0 0', fontFamily: "'JetBrains Mono', monospace" }}>{error}</p>}
          <div style={{ display: 'flex', gap: 8, marginTop: 24, justifyContent: 'flex-end' }}>
            <MutedBtn onClick={onClose}>Cancel</MutedBtn>
            <PrimaryBtn disabled={!valid || registering} onClick={goToStep2}>
              {registering ? 'Registering…' : <>Continue <IconArrow size={12} stroke="#0A0A0A" /></>}
            </PrimaryBtn>
          </div>
        </div>
      )}

      {step === 2 && records && (
        <div style={{ padding: 24 }}>
          <p style={{ fontSize: 13, color: '#EDEDED', margin: '0 0 4px', lineHeight: 1.5 }}>Add these two records at your DNS provider.</p>
          <p style={{ fontSize: 12, color: '#8A8A8A', margin: '0 0 20px', lineHeight: 1.5 }}>
            Namecheap, Cloudflare, Route 53 — all the same fields: <strong style={{ color: '#EDEDED' }}>Type</strong>, <strong style={{ color: '#EDEDED' }}>Host</strong>, <strong style={{ color: '#EDEDED' }}>Value</strong>{`, `}<strong style={{ color: '#EDEDED' }}>Priority</strong> (MX only).
          </p>

          <DnsRow
            type="MX"
            host={records.mx.host}
            value={records.mx.mailServer}
            priority={String(records.mx.priority ?? 10)}
            valueLabel="MAIL SERVER"
            note="Routes inbound mail to the relay."
          />
          <DnsRow
            type="TXT"
            host={records.txt.host}
            value={records.txt.value}
            note="Proves you own the domain."
          />

          {verifyResult && verifyResult !== 'success' && Array.isArray(verifyResult.missing) && verifyResult.missing.length > 0 && (
            <div style={{ marginTop: 14, padding: 12, background: '#2a0e0e', border: '1px solid #5a1a1a', borderRadius: 6 }}>
              <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.18em', color: '#DC2626', marginBottom: 6 }}>NOT YET PROPAGATED</div>
              {verifyResult.missing.map((m, i) => (
                <div key={i} style={{ fontSize: 12, color: '#EDEDED', lineHeight: 1.5 }}>· {m}</div>
              ))}
              <div style={{ fontSize: 11, color: '#8A8A8A', marginTop: 6 }}>DNS typically propagates in 5–30 minutes. Try again shortly.</div>
            </div>
          )}
          {error && <p style={{ fontSize: 12, color: '#DC2626', margin: '10px 0 0', fontFamily: "'JetBrains Mono', monospace" }}>{error}</p>}

          <div style={{ display: 'flex', gap: 8, marginTop: 24, justifyContent: 'space-between', alignItems: 'center' }}>
            <button onClick={() => setStep(1)} style={{ background: 'none', border: 'none', color: '#8A8A8A', fontFamily: "'Geist', system-ui, sans-serif", fontSize: 12, cursor: 'pointer' }}>← Back</button>
            <div style={{ display: 'flex', gap: 8 }}>
              <MutedBtn onClick={() => { onAdd(domain, 'pending'); onClose(); }}>Verify later</MutedBtn>
              <PrimaryBtn onClick={runVerify} disabled={verifying}>
                {verifying ? 'Checking DNS…' : "I've added the records — Verify"}
              </PrimaryBtn>
            </div>
          </div>
        </div>
      )}

      {step === 3 && (
        <div style={{ padding: '40px 24px', textAlign: 'center' }}>
          <div style={{ width: 64, height: 64, borderRadius: '50%', background: 'rgba(16, 185, 129, 0.1)', border: '1px solid #10B981', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 20px' }}>
            <IconCheck size={30} stroke="#10B981" sw={2} />
          </div>
          <h3 style={{ fontSize: 20, fontWeight: 500, color: '#EDEDED', margin: '0 0 6px' }}>Domain verified</h3>
          <p style={{ fontSize: 13, color: '#8A8A8A', margin: '0 0 4px' }}>
            <span style={{ fontFamily: "'JetBrains Mono', monospace", color: '#10B981' }}>@{domain}</span> is active.
          </p>
          <p style={{ fontSize: 12, color: '#565656', margin: '0 0 24px' }}>Messages will start flowing in immediately.</p>
          <PrimaryBtn onClick={() => { onAdd(domain, 'verified'); onClose(); }}>Use this domain <IconArrow size={12} stroke="#0A0A0A" /></PrimaryBtn>
        </div>
      )}
    </ModalShell>
  );
};

// Color-coded label chips so each DNS field maps unambiguously to the
// matching column in the registrar's form (Type / Host / Mail Server /
// Priority on Namecheap, etc.).
const DNS_LABEL_COLORS = {
  TYPE:          { bg: '#3a0e0e', border: '#5a1a1a', color: '#F87171' },  // red
  HOST:          { bg: '#3a2a08', border: '#5c3e08', color: '#F59E0B' },  // orange
  VALUE:         { bg: '#2a3a08', border: '#3e5c08', color: '#FACC15' },  // yellow
  'MAIL SERVER': { bg: '#2a3a08', border: '#3e5c08', color: '#FACC15' },  // yellow
  PRIORITY:      { bg: '#0c2a4a', border: '#1e3f6b', color: '#60A5FA' },  // blue
};

const DnsLabelChip = ({ label }) => {
  const c = DNS_LABEL_COLORS[label] || { bg: '#1a1a1a', border: '#262626', color: '#8A8A8A' };
  return (
    <span style={{
      display: 'inline-block', minWidth: 96, textAlign: 'center',
      fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 600,
      letterSpacing: '0.15em', padding: '4px 8px', borderRadius: 3,
      background: c.bg, border: `1px solid ${c.border}`, color: c.color,
      flexShrink: 0,
    }}>{label}</span>
  );
};

const DnsRow = ({ type, host, value, priority, valueLabel, note }) => (
  <div style={{ background: '#0a0a0a', border: '1px solid #1f1f1f', borderRadius: 6, padding: 14, marginBottom: 10 }}>
    <CopyableField label="TYPE" value={type} />
    <CopyableField label="HOST" value={host} />
    {priority && <CopyableField label="PRIORITY" value={priority} />}
    <CopyableField label={valueLabel || 'VALUE'} value={value} />
    {note && <div style={{ fontSize: 11, color: '#565656', marginTop: 8, lineHeight: 1.4 }}>{note}</div>}
  </div>
);

const CopyableField = ({ label, value }) => {
  const [copied, setCopied] = React.useState(false);
  const copy = () => { navigator.clipboard?.writeText(value); setCopied(true); setTimeout(() => setCopied(false), 1200); };
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
      <DnsLabelChip label={label} />
      <code style={{ flex: 1, fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#EDEDED', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', padding: '6px 10px', background: '#080808', border: '1px solid #1f1f1f', borderRadius: 4 }}>{value}</code>
      <button onClick={copy} style={{ background: '#141414', border: '1px solid #262626', color: copied ? '#10B981' : '#8A8A8A', padding: '6px 10px', borderRadius: 4, fontSize: 10, fontFamily: "'JetBrains Mono', monospace", cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 4, letterSpacing: '0.1em', flexShrink: 0 }}>
        {copied ? <><IconCheck size={10} stroke="#10B981" /> COPIED</> : <><IconCopy size={10} /> COPY</>}
      </button>
    </div>
  );
};

//
// MANAGE INBOXES — lists addresses the customer has ACTIVELY USED (received
// at least one email). Lets them jump to an address or delete it.
//
const ManageInboxesModal = ({ open, onClose, onSelectAddress, currentAddress, toast }) => {
  const [inboxes, setInboxes] = React.useState(null);
  const [hoveredId, setHoveredId] = React.useState(null);
  const [menuOpenId, setMenuOpenId] = React.useState(null);

  const reload = () => {
    tmApi.customer.inboxes()
      .then((r) => setInboxes(r.inboxes))
      .catch((e) => toast?.('Load failed: ' + e.message, 'error'));
  };

  React.useEffect(() => {
    if (open) { reload(); }
    else { setInboxes(null); setMenuOpenId(null); setHoveredId(null); }
  }, [open]);

  React.useEffect(() => {
    if (!menuOpenId) return;
    const onDoc = (e) => {
      // close kebab menu when clicking anywhere outside
      if (!e.target.closest?.('[data-kebab-menu]')) setMenuOpenId(null);
    };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [menuOpenId]);

  if (!open) return null;

  const remove = async (i) => {
    setMenuOpenId(null);
    if (!confirm(`Delete ${i.address} and all ${i.emailCount} email${i.emailCount === 1 ? '' : 's'}? This cannot be undone.`)) return;
    try {
      await tmApi.customer.removeInbox(i.id);
      toast?.(`Removed ${i.address}`);
      reload();
    } catch (e) {
      toast?.('Delete failed: ' + e.message, 'error');
    }
  };

  const switchTo = (i) => {
    onSelectAddress?.(i.address);
    onClose();
  };

  return (
    <ModalShell
      onClose={onClose}
      title="Manage inboxes"
      subtitle={inboxes ? `${inboxes.length} ${inboxes.length === 1 ? 'inbox' : 'inboxes'} with mail` : 'Loading…'}
      wide
    >
      {!inboxes ? (
        <div style={{ padding: 60, textAlign: 'center', color: '#565656', fontFamily: "'JetBrains Mono', monospace", fontSize: 11, letterSpacing: '0.2em' }}>
          LOADING…
        </div>
      ) : inboxes.length === 0 ? (
        <div style={{ padding: 60, textAlign: 'center' }}>
          <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, color: '#565656', letterSpacing: '0.2em', marginBottom: 8 }}>
            ▒ NO MAIL YET ▒
          </div>
          <p style={{ fontSize: 13, color: '#8A8A8A', margin: '8px 0 4px' }}>You haven't received any mail on any address yet.</p>
          <p style={{ fontSize: 12, color: '#565656', margin: 0 }}>Pick an address using <kbd style={kbdStyle}>N</kbd> and have something send mail to it — it'll show up here.</p>
        </div>
      ) : (
        <table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: "'Geist', system-ui, sans-serif" }}>
          <thead>
            <tr style={{ borderBottom: '1px solid #1f1f1f' }}>
              <Th>EMAIL</Th>
              <Th>DOMAIN</Th>
              <Th style={{ textAlign: 'right' }}>EMAILS</Th>
              <Th style={{ textAlign: 'right', width: 60 }}> </Th>
            </tr>
          </thead>
          <tbody>
            {inboxes.map((i) => {
              const isCurrent = i.address === currentAddress;
              return (
                <tr
                  key={i.id}
                  onMouseEnter={() => setHoveredId(i.id)}
                  onMouseLeave={() => setHoveredId(null)}
                  onClick={() => switchTo(i)}
                  style={{
                    borderBottom: '1px solid #151515',
                    cursor: 'pointer',
                    background: isCurrent ? '#0f1f1a' : (hoveredId === i.id ? '#101010' : 'transparent'),
                    transition: 'background 100ms',
                  }}
                >
                  <td style={{ padding: '12px 24px', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#EDEDED' }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      {isCurrent && <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#10B981' }} title="Current address" />}
                      {i.address.split('@')[0]}
                    </div>
                  </td>
                  <td style={{ padding: '12px 24px', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#8A8A8A' }}>
                    @{i.domain}
                  </td>
                  <td style={{ padding: '12px 24px', textAlign: 'right', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#EDEDED' }}>
                    {i.emailCount}
                  </td>
                  <td
                    style={{ padding: '12px 24px', textAlign: 'right', position: 'relative' }}
                    onClick={(e) => e.stopPropagation()}
                    data-kebab-menu
                  >
                    <button
                      onClick={(e) => {
                        e.stopPropagation();
                        setMenuOpenId(menuOpenId === i.id ? null : i.id);
                      }}
                      title="Inbox actions"
                      style={{
                        background: menuOpenId === i.id ? '#262626' : 'none',
                        border: 'none',
                        cursor: 'pointer',
                        color: hoveredId === i.id || menuOpenId === i.id ? '#EDEDED' : 'transparent',
                        opacity: hoveredId === i.id || menuOpenId === i.id ? 1 : 0,
                        padding: 6, borderRadius: 3, display: 'inline-flex', alignItems: 'center',
                        transition: 'opacity 120ms, color 120ms, background 120ms',
                      }}
                    >
                      <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
                        <circle cx="12" cy="6" r="1.6" />
                        <circle cx="12" cy="12" r="1.6" />
                        <circle cx="12" cy="18" r="1.6" />
                      </svg>
                    </button>
                    {menuOpenId === i.id && (
                      <div
                        style={{
                          position: 'absolute', top: '100%', right: 14, marginTop: 4, zIndex: 60,
                          background: '#0f0f0f', border: '1px solid #262626', borderRadius: 6,
                          boxShadow: '0 8px 24px rgba(0,0,0,0.6)', minWidth: 190, overflow: 'hidden',
                          animation: 'slideDown 120ms ease',
                        }}
                      >
                        <InboxMenuItem onClick={() => { setMenuOpenId(null); switchTo(i); }}>
                          Open this inbox
                        </InboxMenuItem>
                        <InboxMenuItem onClick={() => {
                          navigator.clipboard?.writeText(i.address);
                          toast?.('Address copied');
                          setMenuOpenId(null);
                        }}>
                          Copy address
                        </InboxMenuItem>
                        <div style={{ borderTop: '1px solid #1f1f1f' }} />
                        <InboxMenuItem danger onClick={() => remove(i)}>
                          Delete inbox + emails
                        </InboxMenuItem>
                      </div>
                    )}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      )}
      <div style={{ padding: '16px 24px', borderTop: '1px solid #1f1f1f', fontSize: 12, color: '#565656' }}>
        Inboxes only show here once they've received at least one email. Empty addresses you've typed are kept silently and won't appear in this list.
      </div>
    </ModalShell>
  );
};

const InboxMenuItem = ({ children, onClick, danger }) => (
  <button
    onClick={onClick}
    style={{
      width: '100%', textAlign: 'left', padding: '10px 14px', fontSize: 12,
      fontFamily: "'Geist', system-ui, sans-serif", color: danger ? '#DC2626' : '#EDEDED',
      background: 'transparent', border: 'none', cursor: 'pointer',
      transition: 'background 100ms',
    }}
    onMouseEnter={(e) => (e.currentTarget.style.background = danger ? '#2a0e0e' : '#1a1a1a')}
    onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}
  >
    {children}
  </button>
);

const kbdStyle = {
  fontFamily: "'JetBrains Mono', monospace", fontSize: 10,
  padding: '1px 5px', border: '1px solid #262626', borderRadius: 3,
  background: '#0a0a0a', color: '#10B981',
};

//
// MANAGE DOMAINS
//
const ManageDomainsModal = ({ open, onClose, domains, onAdd, onRemove }) => {
  if (!open) return null;
  return (
    <ModalShell onClose={onClose} title="Manage domains" subtitle={`${domains.custom.length} custom · ${domains.shared.length} shared`} wide>
      <div style={{ padding: '4px 0 0' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: "'Geist', system-ui, sans-serif" }}>
          <thead>
            <tr style={{ borderBottom: '1px solid #1f1f1f' }}>
              <Th>DOMAIN</Th>
              <Th>STATUS</Th>
              <Th>ADDED</Th>
              <Th style={{ textAlign: 'right' }}>EMAILS</Th>
              <Th style={{ textAlign: 'right' }}>ACTIONS</Th>
            </tr>
          </thead>
          <tbody>
            {domains.custom.map((d) => (
              <tr key={d.id} style={{ borderBottom: '1px solid #151515' }}>
                <td style={{ padding: '14px 24px', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#EDEDED' }}>@{d.domain}</td>
                <td style={{ padding: '14px 24px' }}>
                  {d.status === 'verified' ? (
                    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 11, fontFamily: "'JetBrains Mono', monospace", color: '#10B981', letterSpacing: '0.1em' }}>
                      <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#10B981' }} /> VERIFIED
                    </span>
                  ) : (
                    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 11, fontFamily: "'JetBrains Mono', monospace", color: '#F59E0B', letterSpacing: '0.1em' }}>
                      <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#F59E0B' }} /> PENDING
                    </span>
                  )}
                </td>
                <td style={{ padding: '14px 24px', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#8A8A8A' }}>{d.added}</td>
                <td style={{ padding: '14px 24px', textAlign: 'right', fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#8A8A8A' }}>{d.count}</td>
                <td style={{ padding: '14px 24px', textAlign: 'right' }}>
                  <div style={{ display: 'inline-flex', gap: 6 }}>
                    {d.status === 'pending' && <MiniBtn>Re-verify</MiniBtn>}
                    <MiniBtn>DNS</MiniBtn>
                    <MiniBtn danger onClick={() => onRemove(d.id)}>Remove</MiniBtn>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        <div style={{ padding: 24, borderTop: '1px solid #1f1f1f', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <p style={{ fontSize: 12, color: '#565656', margin: 0 }}>
            Custom domains don't expire. Email retention is configurable per-domain.
          </p>
          <PrimaryBtn onClick={onAdd}><IconPlus size={12} stroke="#0A0A0A" /> Add domain</PrimaryBtn>
        </div>
      </div>
    </ModalShell>
  );
};

const Th = ({ children, style }) => (
  <th style={{ textAlign: 'left', fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500, letterSpacing: '0.2em', color: '#565656', padding: '12px 24px', ...style }}>{children}</th>
);

const MiniBtn = ({ children, onClick, danger }) => (
  <button onClick={onClick} style={{
    background: 'transparent', border: '1px solid #262626',
    color: danger ? '#DC2626' : '#EDEDED',
    fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.1em',
    padding: '4px 9px', borderRadius: 4, cursor: 'pointer', transition: 'background 120ms',
  }}
    onMouseEnter={(e) => (e.currentTarget.style.background = danger ? '#2a0e0e' : '#1a1a1a')}
    onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}
  >{children}</button>
);

//
// SETTINGS DRAWER
//
const SettingsDrawer = ({ open, onClose, settings, setSettings, onShowShortcuts, onSignOut, codePreview, onTestSound }) => {
  if (!open) return null;
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 100, animation: 'fadeIn 150ms' }} />
      <div style={{
        position: 'fixed', top: 0, right: 0, bottom: 0, width: 420,
        background: '#111111', borderLeft: '1px solid #1f1f1f',
        zIndex: 101, animation: 'slideInRight 200ms ease',
        display: 'flex', flexDirection: 'column', overflow: 'hidden',
      }}>
        <div style={{ padding: '18px 24px', borderBottom: '1px solid #1f1f1f', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <IconSettings size={16} stroke="#EDEDED" />
            <h3 style={{ margin: 0, fontSize: 14, fontWeight: 500, color: '#EDEDED', fontFamily: "'Geist', system-ui, sans-serif" }}>Settings</h3>
          </div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#8A8A8A', display: 'flex', padding: 4 }}><IconX size={14} /></button>
        </div>

        <div style={{ flex: 1, overflowY: 'auto', padding: '4px 0' }}>
          <Section label="INBOX">
            <Row label="Auto-refresh">
              <SegControl
                value={settings.refresh}
                onChange={(v) => setSettings({ ...settings, refresh: v })}
                options={[['off', 'Off'], ['10', '10s'], ['30', '30s'], ['60', '60s']]}
              />
            </Row>
            <Row label="Retention">
              <SegControl
                value={settings.retention}
                onChange={(v) => setSettings({ ...settings, retention: v })}
                options={[['24', '24h'], ['72', '72h'], ['7', '7d'], ['30', '30d']]}
              />
            </Row>
            <Row label="Verification codes">
              <Toggle value={settings.showCodes} onChange={(v) => setSettings({ ...settings, showCodes: v })} />
            </Row>
            <Row label="Sound on new mail">
              <Toggle value={settings.sound} onChange={(v) => {
                setSettings({ ...settings, sound: v });
                // Preview the ding when turning ON. Force=true bypasses the
                // settings-state check (the new value hasn't propagated yet).
                if (v && onTestSound) onTestSound();
              }} />
            </Row>
          </Section>

          <Section label="DISPLAY">
            <Row label="Density">
              <SegControl
                value={settings.density}
                onChange={(v) => setSettings({ ...settings, density: v })}
                options={[['compact', 'Compact'], ['cozy', 'Cozy'], ['roomy', 'Roomy']]}
              />
            </Row>
          </Section>

          <Section label="HELP">
            <Row label="Keyboard shortcuts">
              <button onClick={onShowShortcuts} style={linkBtn}>View <IconArrow size={11} stroke="#8A8A8A" /></button>
            </Row>
            <Row label="Documentation">
              <button style={linkBtn}>Open <IconArrow size={11} stroke="#8A8A8A" /></button>
            </Row>
          </Section>

          <Section label="SESSION">
            <div style={{ padding: '10px 24px' }}>
              <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, color: '#565656', marginBottom: 4 }}>ACCESS CODE</div>
              <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#EDEDED', letterSpacing: '0.05em' }}>{codePreview || '????-XXXX-XXXX-????'}</div>
            </div>
            <div style={{ padding: '12px 24px 20px' }}>
              <button onClick={onSignOut} style={{ width: '100%', padding: '10px 14px', background: 'transparent', border: '1px solid #262626', color: '#DC2626', fontFamily: "'Geist', system-ui, sans-serif", fontSize: 13, borderRadius: 6, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}>
                <IconLock size={13} stroke="#DC2626" /> Sign out
              </button>
            </div>
          </Section>
        </div>
      </div>
    </>
  );
};

const linkBtn = {
  background: 'none', border: 'none', color: '#8A8A8A', cursor: 'pointer',
  fontFamily: "'Geist', system-ui, sans-serif", fontSize: 12,
  display: 'flex', alignItems: 'center', gap: 4,
};

const Section = ({ label, children }) => (
  <div style={{ padding: '18px 0 6px' }}>
    <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9, letterSpacing: '0.25em', color: '#565656', padding: '0 24px 10px' }}>{label}</div>
    {children}
  </div>
);

const Row = ({ label, children }) => (
  <div style={{ padding: '10px 24px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
    <span style={{ fontSize: 13, color: '#EDEDED' }}>{label}</span>
    {children}
  </div>
);

const SegControl = ({ value, onChange, options }) => (
  <div style={{ display: 'flex', background: '#0a0a0a', border: '1px solid #1f1f1f', borderRadius: 5, padding: 2 }}>
    {options.map(([v, label]) => (
      <button key={v} onClick={() => onChange(v)} style={{
        background: value === v ? '#262626' : 'transparent', border: 'none',
        color: value === v ? '#EDEDED' : '#8A8A8A',
        fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.08em',
        padding: '5px 9px', borderRadius: 3, cursor: 'pointer',
      }}>{label}</button>
    ))}
  </div>
);

const Toggle = ({ value, onChange }) => (
  <button onClick={() => onChange(!value)} style={{
    width: 32, height: 18, borderRadius: 9, background: value ? '#10B981' : '#262626',
    border: 'none', cursor: 'pointer', position: 'relative', transition: 'background 150ms',
  }}>
    <div style={{
      position: 'absolute', top: 2, left: value ? 16 : 2, width: 14, height: 14,
      borderRadius: '50%', background: '#EDEDED', transition: 'left 150ms ease',
    }} />
  </button>
);

//
// SHORTCUTS MODAL
//
const ShortcutsModal = ({ open, onClose }) => {
  if (!open) return null;
  const shortcuts = [
    ['R', 'Refresh inbox'],
    ['N', 'Save / pin selected email'],
    ['D', 'Delete selected email'],
    ['J', 'Next email'],
    ['K', 'Previous email'],
    ['/', 'Focus address input'],
    ['C', 'Copy current address'],
    ['G', 'Open domain selector'],
    ['?', 'Show this help'],
    ['Esc', 'Close modal / dropdown'],
  ];
  return (
    <ModalShell onClose={onClose} title="Keyboard shortcuts" subtitle="Press any key to activate">
      <div style={{ padding: '4px 24px 24px' }}>
        {shortcuts.map(([k, desc]) => (
          <div key={k} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 0', borderBottom: '1px solid #1a1a1a' }}>
            <span style={{ fontSize: 13, color: '#EDEDED' }}>{desc}</span>
            <kbd style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, padding: '3px 8px', border: '1px solid #262626', borderBottom: '2px solid #262626', borderRadius: 4, background: '#0a0a0a', color: '#10B981', minWidth: 20, textAlign: 'center' }}>{k}</kbd>
          </div>
        ))}
      </div>
    </ModalShell>
  );
};

//
// QR MODAL
//
const QRModal = ({ open, onClose, address }) => {
  if (!open) return null;
  // Generate fake QR pattern
  const grid = React.useMemo(() => {
    const seed = address.split('').reduce((a, c) => a + c.charCodeAt(0), 0);
    const arr = [];
    for (let i = 0; i < 25; i++) {
      const row = [];
      for (let j = 0; j < 25; j++) {
        row.push((seed * (i + 1) * (j + 1) + i * j) % 3 === 0);
      }
      arr.push(row);
    }
    // finder patterns
    const setFinder = (r, c) => {
      for (let i = 0; i < 7; i++) for (let j = 0; j < 7; j++) {
        const edge = i === 0 || i === 6 || j === 0 || j === 6;
        const inner = i >= 2 && i <= 4 && j >= 2 && j <= 4;
        arr[r + i][c + j] = edge || inner;
      }
    };
    setFinder(0, 0); setFinder(0, 18); setFinder(18, 0);
    return arr;
  }, [address]);

  return (
    <ModalShell onClose={onClose} title="QR code" subtitle="Scan to copy address">
      <div style={{ padding: 24, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
        <div style={{ background: '#EDEDED', padding: 18, borderRadius: 8 }}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(25, 1fr)', gap: 0, width: 220, height: 220 }}>
            {grid.flat().map((on, i) => (
              <div key={i} style={{ background: on ? '#0A0A0A' : 'transparent', aspectRatio: '1 / 1' }} />
            ))}
          </div>
        </div>
        <div style={{ marginTop: 18, fontFamily: "'JetBrains Mono', monospace", fontSize: 12, color: '#EDEDED', padding: '8px 14px', background: '#0a0a0a', border: '1px solid #1f1f1f', borderRadius: 5 }}>
          {address}
        </div>
      </div>
    </ModalShell>
  );
};

//
// GENERIC MODAL SHELL
//
const ModalShell = ({ onClose, title, subtitle, children, wide }) => (
  <>
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.6)', zIndex: 200, animation: 'fadeIn 150ms' }} />
    <div style={{
      position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
      width: '100%', maxWidth: wide ? 720 : 520,
      background: '#111111', border: '1px solid #1f1f1f', borderRadius: 10,
      zIndex: 201, animation: 'zoomIn 180ms ease',
      overflow: 'hidden', maxHeight: '85vh', display: 'flex', flexDirection: 'column',
    }}>
      <div style={{ padding: '18px 24px', borderBottom: '1px solid #1f1f1f', display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexShrink: 0 }}>
        <div>
          <h3 style={{ margin: 0, fontSize: 15, fontWeight: 500, color: '#EDEDED' }}>{title}</h3>
          {subtitle && <p style={{ margin: '2px 0 0', fontSize: 11, fontFamily: "'JetBrains Mono', monospace", color: '#565656', letterSpacing: '0.1em' }}>{subtitle}</p>}
        </div>
        <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#8A8A8A', padding: 4, display: 'flex' }}><IconX size={14} /></button>
      </div>
      <div style={{ flex: 1, overflowY: 'auto' }}>{children}</div>
    </div>
  </>
);

const PrimaryBtn = ({ children, onClick, disabled }) => (
  <button onClick={onClick} disabled={disabled} style={{
    background: '#10B981', color: '#0A0A0A', border: 'none',
    padding: '9px 14px', borderRadius: 5,
    fontFamily: "'Geist', system-ui, sans-serif", fontSize: 13, fontWeight: 600,
    cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.4 : 1,
    display: 'inline-flex', alignItems: 'center', gap: 6, transition: 'background 120ms',
  }}
    onMouseEnter={(e) => !disabled && (e.currentTarget.style.background = '#0ea371')}
    onMouseLeave={(e) => (e.currentTarget.style.background = '#10B981')}
  >{children}</button>
);

const MutedBtn = ({ children, onClick }) => (
  <button onClick={onClick} style={{
    background: 'transparent', color: '#EDEDED', border: '1px solid #262626',
    padding: '9px 14px', borderRadius: 5,
    fontFamily: "'Geist', system-ui, sans-serif", fontSize: 13,
    cursor: 'pointer', transition: 'background 120ms',
  }}
    onMouseEnter={(e) => (e.currentTarget.style.background = '#1a1a1a')}
    onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}
  >{children}</button>
);

Object.assign(window, {
  DomainDropdown, AddDomainModal, ManageDomainsModal, ManageInboxesModal,
  SettingsDrawer, ShortcutsModal, QRModal, ShowDnsRecordsModal,
  Badge, PrimaryBtn, MutedBtn, ModalShell,
});
