// Admin/Manager console — customer (reseller) CRUD over /api/resellers, plus
// staff-account CRUD over /api/employees (admin only).
// URL: /demo.html?demo=admin
// Sign in against the employees table: admins get both views; managers get the
// Resellers view only (add/edit customers, no delete). Pre-filled demo login:
// admin / temppass.
//
// Access control (server-enforced in api/, mirrored in the UI):
//   Admin   — full CRUD on customers + staff accounts.
//   Manager — add/edit customers (no delete); no access to staff accounts.

const A = {
  bg: '#f7f8fa',
  surface: '#ffffff',
  border: '#e4e7ec',
  borderStrong: '#d0d5dd',
  text: '#101828',
  textMid: '#475467',
  textDim: '#667085',
  accent: '#2e5dff',
  accentDim: '#eaf0ff',
  ok: '#067647',
  okBg: '#ecfdf3',
  warn: '#b54708',
  warnBg: '#fffaeb',
  danger: '#b42318',
  dangerBg: '#fef3f2',
  row: '#fafbfc',
  font: '"Inter", system-ui, sans-serif',
  mono: '"JetBrains Mono", ui-monospace, monospace',
};

const ADMIN_WAREHOUSES = ['Shanghai', 'California', 'Germany'];
const ADMIN_TOKEN_KEY = 'gruv_admin_token';
const ADMIN_ROLE_KEY = 'gruv_admin_role';
const ADMIN_NAME_KEY = 'gruv_admin_name';
const ADMIN_DEMO_PASSWORD = 'temppass';
const TERMS_OPTIONS = ['NET30', 'NET45', 'NET60', 'NET90', 'Prepaid', 'COD'];
const TYPE_OPTIONS = ['Dealer', 'Distributor', 'Industry', 'Non-Profit'];
const BRAND_OPTIONS = ['Gruv Gear', 'Krane', 'All'];
const CARRIER_OPTIONS = ['DHL', 'FedEx', 'UPS'];
const REGION_TABS = ['All', 'Domestic', 'International'];

function useViewportWidth() {
  const [w, setW] = React.useState(() => (typeof window === 'undefined' ? 1440 : window.innerWidth));
  React.useEffect(() => {
    const r = () => setW(window.innerWidth);
    window.addEventListener('resize', r);
    return () => window.removeEventListener('resize', r);
  }, []);
  return w;
}

function csvEscape(v) {
  if (v == null) return '';
  const s = String(v);
  return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
}

// Reseller export as a header + rows matrix (array of arrays) — shared by the
// Excel (.xlsx) and CSV-fallback writers.
function buildResellersMatrix(rows) {
  const headers = [
    'Company', 'Country', 'Region', 'Warehouse', 'Type', 'Brand',
    'Terms', 'Discount %', 'Company email',
    'Primary contact', 'Primary email', 'Primary phone',
    'All contacts', 'Contacts count',
    'Default ship-to label', 'Default ship-to address',
    'Default carrier', 'Default carrier account',
    'Locations count', 'Notes',
  ];
  const matrix = [headers];
  for (const r of rows) {
    const cs = r.contacts || [];
    const primary = cs.find((c) => c.is_primary) || cs[0] || null;
    const allContacts = cs
      .map((c) => [c.name, c.email, c.phone].filter(Boolean).join(' '))
      .filter(Boolean).join('; ');
    const locs = r.ship_to_locations || [];
    const defaultLoc = locs.find((l) => l.is_default) || locs[0] || null;
    matrix.push([
      r.company_name, r.country, r.region, r.warehouse, r.type, r.brand,
      r.terms, r.discount_percent, r.email,
      primary?.name, primary?.email, primary?.phone,
      allContacts, cs.length,
      defaultLoc?.label, defaultLoc?.address,
      defaultLoc?.carrier, defaultLoc?.account_number,
      locs.length, r.notes,
    ]);
  }
  return matrix;
}

function buildResellersCsv(rows) {
  return buildResellersMatrix(rows).map((row) => row.map(csvEscape).join(',')).join('\r\n');
}

// Download a matrix as a real .xlsx workbook (SheetJS is loaded in demo.html).
// Falls back to a CSV download if SheetJS didn't load.
function downloadXlsx(filename, matrix, sheetName = 'Sheet1') {
  if (!window.XLSX) {
    const csv = matrix.map((row) => row.map(csvEscape).join(',')).join('\r\n');
    downloadCsv(filename.replace(/\.xlsx$/i, '.csv'), csv);
    return;
  }
  const ws = window.XLSX.utils.aoa_to_sheet(matrix);
  const wb = window.XLSX.utils.book_new();
  window.XLSX.utils.book_append_sheet(wb, ws, String(sheetName).slice(0, 31));
  window.XLSX.writeFile(wb, filename);
}

function downloadCsv(filename, content) {
  // Prepend UTF-8 BOM so Excel detects encoding correctly.
  const blob = new Blob(['﻿' + content], { type: 'text/csv;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

function adminFetch(path, { token, method = 'GET', body } = {}) {
  return fetch(path, {
    method,
    headers: {
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
      ...(body ? { 'Content-Type': 'application/json' } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
  }).then(async (res) => {
    const text = await res.text();
    let json = {};
    try { json = text ? JSON.parse(text) : {}; } catch (_) {}
    if (!res.ok) {
      const err = new Error(json.error || `Request failed (${res.status})`);
      err.status = res.status;
      throw err;
    }
    return json;
  });
}

function AdminApp() {
  const [token, setToken] = React.useState(() => {
    try { return localStorage.getItem(ADMIN_TOKEN_KEY) || ''; } catch (_) { return ''; }
  });
  const [role, setRole] = React.useState(() => {
    try { return localStorage.getItem(ADMIN_ROLE_KEY) || ''; } catch (_) { return ''; }
  });
  const [name, setName] = React.useState(() => {
    try { return localStorage.getItem(ADMIN_NAME_KEY) || ''; } catch (_) { return ''; }
  });

  const signOut = () => {
    try {
      localStorage.removeItem(ADMIN_TOKEN_KEY);
      localStorage.removeItem(ADMIN_ROLE_KEY);
      localStorage.removeItem(ADMIN_NAME_KEY);
    } catch (_) {}
    window.location.href = '/demo.html?demo=inventory-ledger';
  };

  const [view, setView] = React.useState('resellers');
  const isAdmin = role === 'admin';
  // Managers never see the Employees view; if their stored view is stale, snap back.
  const activeView = isAdmin ? view : 'resellers';

  if (!token) {
    return <AdminLogin onSignIn={({ token: t, role: r, name: n }) => {
      try {
        localStorage.setItem(ADMIN_TOKEN_KEY, t);
        localStorage.setItem(ADMIN_ROLE_KEY, r || '');
        localStorage.setItem(ADMIN_NAME_KEY, n || '');
      } catch (_) {}
      setToken(t);
      setRole(r || '');
      setName(n || '');
    }} />;
  }
  return (
    <div style={{
      minHeight: '100dvh', background: A.bg, color: A.text, fontFamily: A.font,
      display: 'flex', flexDirection: 'column',
    }}>
      <AdminTopBar onSignOut={signOut} view={activeView} setView={setView} role={role} name={name} />
      {activeView === 'resellers'
        ? <AdminResellers token={token} onSignOut={signOut} role={role} />
        : <AdminEmployees token={token} onSignOut={signOut} />}
    </div>
  );
}

// ── LOGIN ───────────────────────────────────────────────────────────────────
function AdminLogin({ onSignIn }) {
  const [username, setUsername] = React.useState('admin');
  const [password, setPassword] = React.useState(ADMIN_DEMO_PASSWORD);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  const [captcha, setCaptcha] = React.useState('');
  const [captchaReset, setCaptchaReset] = React.useState(0);

  const submit = async (e) => {
    e?.preventDefault?.();
    setBusy(true);
    setError('');
    try {
      const { token, role, name } = await adminFetch('/api/admin/login', {
        method: 'POST',
        body: { username, password, recaptchaToken: captcha },
      });
      onSignIn({ token, role, name });
    } catch (err) {
      setError(err.message);
      setCaptchaReset((n) => n + 1);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={{
      minHeight: '100dvh', background: A.bg, fontFamily: A.font, color: A.text,
      display: 'grid', placeItems: 'center', padding: 20,
    }}>
      <form onSubmit={submit} style={{
        width: '100%', maxWidth: 380, background: A.surface,
        border: `1px solid ${A.border}`, borderRadius: 14, padding: 28,
        boxShadow: '0 20px 50px rgba(15,23,42,0.08)',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
          <BrandLogo size={32} radius={8} />
          <div style={{ fontSize: 13, color: A.textDim }}>Gruv Gear · Admin</div>
        </div>
        <h1 style={{ margin: '12px 0 6px', fontSize: 24, fontWeight: 700, letterSpacing: -0.4 }}>Sign in</h1>
        <p style={{ margin: '0 0 22px', fontSize: 13, color: A.textDim, lineHeight: 1.5 }}>
          Demo credentials are pre-filled below.
        </p>

        <Field label="Username">
          <input value={username} onChange={(e) => setUsername(e.target.value)}
            autoComplete="username" style={inputStyle} />
        </Field>
        <Field label="Password">
          <input type="password" value={password} onChange={(e) => setPassword(e.target.value)}
            autoComplete="current-password" style={inputStyle} />
        </Field>

        {error ? <div style={{
          background: A.dangerBg, color: A.danger, border: `1px solid ${A.danger}22`,
          padding: '8px 12px', borderRadius: 8, fontSize: 13, marginBottom: 12,
        }}>{error}</div> : null}

        <Recaptcha onToken={setCaptcha} resetSignal={captchaReset} />

        <button type="submit" disabled={busy || (recaptchaEnabled() && !captcha)} style={{
          width: '100%', height: 44, marginTop: 16, border: 'none', borderRadius: 10,
          background: busy || (recaptchaEnabled() && !captcha) ? A.textDim : A.accent, color: '#fff',
          fontSize: 15, fontWeight: 600, fontFamily: A.font,
          cursor: busy ? 'wait' : 'pointer',
        }}>{busy ? 'Signing in…' : 'Sign in'}</button>
      </form>
    </div>
  );
}

// ── RESELLERS PAGE ──────────────────────────────────────────────────────────
function AdminResellers({ token, onSignOut, role }) {
  const vw = useViewportWidth();
  const isPhone = vw < 760;
  // Managers can add/edit customers; only admins can delete them.
  const canDelete = role === 'admin';

  const [resellers, setResellers] = React.useState(null);
  const [error, setError] = React.useState('');
  const [search, setSearch] = React.useState('');
  const [region, setRegion] = React.useState('All');
  const [sort, setSort] = React.useState({ key: 'company_name', dir: 'asc' });
  const [editing, setEditing] = React.useState(null);
  const [expanded, setExpanded] = React.useState(() => new Set());

  const load = React.useCallback(async () => {
    setError('');
    try {
      const { resellers } = await adminFetch('/api/resellers', { token });
      setResellers(resellers);
    } catch (err) {
      if (err.status === 401) {
        onSignOut();
        return;
      }
      setError(err.message);
    }
  }, [token, onSignOut]);

  React.useEffect(() => { load(); }, [load]);

  const onSort = React.useCallback((key) => {
    setSort((s) => {
      if (s.key !== key) return { key, dir: 'asc' };
      if (s.dir === 'asc') return { key, dir: 'desc' };
      return { key: null, dir: null };
    });
  }, []);

  const filtered = React.useMemo(() => {
    if (!resellers) return [];
    let rows = resellers;
    if (region !== 'All') rows = rows.filter((r) => r.region === region);
    const q = search.trim().toLowerCase();
    if (q) {
      rows = rows.filter((r) => {
        const contactBits = (r.contacts || []).flatMap((c) => [c.name, c.email, c.phone]);
        return [r.company_name, r.email, r.username, r.country, r.warehouse, r.brand, r.type, r.terms, ...contactBits]
          .filter(Boolean)
          .some((v) => String(v).toLowerCase().includes(q));
      });
    }
    if (sort.key) {
      const key = sort.key;
      rows = [...rows].sort((a, b) => {
        const av = (a[key] ?? '').toString().toLowerCase();
        const bv = (b[key] ?? '').toString().toLowerCase();
        if (av < bv) return sort.dir === 'asc' ? -1 : 1;
        if (av > bv) return sort.dir === 'asc' ? 1 : -1;
        return 0;
      });
    }
    return rows;
  }, [resellers, region, search, sort]);

  const onSave = async (payload, existingId) => {
    if (existingId) {
      await adminFetch(`/api/resellers/${existingId}`, { token, method: 'PATCH', body: payload });
    } else {
      await adminFetch('/api/resellers', { token, method: 'POST', body: payload });
    }
    setEditing(null);
    await load();
  };

  const onDelete = async (reseller) => {
    if (!window.confirm(`Delete ${reseller.company_name || reseller.email}? This cannot be undone.`)) return;
    try {
      await adminFetch(`/api/resellers/${reseller.id}`, { token, method: 'DELETE' });
      await load();
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <React.Fragment>
      <div style={{
        padding: isPhone ? '14px 12px' : '20px 20px',
        maxWidth: isPhone ? '100%' : 1700, width: '100%', margin: '0 auto', flex: 1, minWidth: 0,
      }}>
        <div style={{
          display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap', marginBottom: 14,
        }}>
          <div style={{ flex: '1 1 auto', minWidth: 200 }}>
            <h1 style={{
              margin: 0, fontSize: isPhone ? 22 : 26, fontWeight: 700, letterSpacing: -0.4,
            }}>Resellers</h1>
            <div style={{ marginTop: 4, fontSize: 13, color: A.textDim }}>
              {resellers == null ? 'Loading…' : `${filtered.length} of ${resellers.length} shown`}
            </div>
          </div>
          <input
            placeholder="Search company, contact, email, country…"
            value={search} onChange={(e) => setSearch(e.target.value)}
            style={{ ...inputStyle, height: 40, minWidth: 220, flex: '1 1 260px', maxWidth: 360 }}
          />
          <button onClick={() => setEditing('new')} style={primaryBtn}>+ Add reseller</button>
        </div>

        <RegionTabs
          region={region}
          setRegion={setRegion}
          right={
            <button
              type="button"
              onClick={() => {
                const ds = new Date().toISOString().slice(0, 10);
                const tag = region === 'All' ? 'all' : region.toLowerCase();
                downloadXlsx(`gruv-resellers-${tag}-${ds}.xlsx`, buildResellersMatrix(filtered), 'Resellers');
              }}
              disabled={!filtered.length}
              title={filtered.length ? `Download ${filtered.length} row${filtered.length === 1 ? '' : 's'} as Excel (.xlsx)` : 'No rows in the current view'}
              style={{
                ...secondaryBtnA, height: 32, fontSize: 12, padding: '0 12px',
                opacity: filtered.length ? 1 : 0.5,
                cursor: filtered.length ? 'pointer' : 'not-allowed',
              }}
            >↓ Export Excel ({filtered.length})</button>
          }
        />

        {error ? (
          <div style={{
            background: A.dangerBg, color: A.danger, border: `1px solid ${A.danger}33`,
            padding: '10px 14px', borderRadius: 8, fontSize: 13, marginBottom: 14,
          }}>{error}</div>
        ) : null}

        {resellers == null ? (
          <div style={{ padding: 40, textAlign: 'center', color: A.textDim }}>Loading resellers…</div>
        ) : filtered.length === 0 ? (
          <div style={{
            background: A.surface, border: `1px solid ${A.border}`, borderRadius: 12,
            padding: 40, textAlign: 'center', color: A.textDim,
          }}>No resellers match your filters.</div>
        ) : isPhone ? (
          <ResellerCardList resellers={filtered} onEdit={setEditing} onDelete={onDelete} canDelete={canDelete} expanded={expanded} setExpanded={setExpanded} />
        ) : (
          <ResellerTable resellers={filtered} sort={sort} onSort={onSort} onEdit={setEditing} onDelete={onDelete} canDelete={canDelete} expanded={expanded} setExpanded={setExpanded} />
        )}
      </div>

      {editing ? (
        <ResellerEditModal
          reseller={editing === 'new' ? null : editing}
          onClose={() => setEditing(null)}
          onSave={onSave}
        />
      ) : null}
    </React.Fragment>
  );
}

// ── EMPLOYEES PAGE ──────────────────────────────────────────────────────────
function AdminEmployees({ token, onSignOut }) {
  const vw = useViewportWidth();
  const isPhone = vw < 760;

  const [employees, setEmployees] = React.useState(null);
  const [error, setError] = React.useState('');
  const [editing, setEditing] = React.useState(null); // { role } for new, or employee row for edit

  const load = React.useCallback(async () => {
    setError('');
    try {
      const { employees } = await adminFetch('/api/employees', { token });
      setEmployees(employees);
    } catch (err) {
      if (err.status === 401) { onSignOut(); return; }
      setError(err.message);
    }
  }, [token, onSignOut]);

  React.useEffect(() => { load(); }, [load]);

  const onSave = async (payload, existingId) => {
    if (existingId) {
      await adminFetch(`/api/employees/${existingId}`, { token, method: 'PATCH', body: payload });
    } else {
      await adminFetch('/api/employees', { token, method: 'POST', body: payload });
    }
    setEditing(null);
    await load();
  };

  const onDelete = async (emp) => {
    if (!window.confirm(`Remove ${emp.name || emp.username}? This cannot be undone.`)) return;
    try {
      await adminFetch(`/api/employees/${emp.id}`, { token, method: 'DELETE' });
      await load();
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <div style={{
      padding: isPhone ? '14px 12px' : '20px 20px',
      maxWidth: isPhone ? '100%' : 1100, width: '100%', margin: '0 auto', flex: 1, minWidth: 0,
    }}>
      <div style={{
        display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap', marginBottom: 16,
      }}>
        <div style={{ flex: '1 1 auto', minWidth: 200 }}>
          <h1 style={{ margin: 0, fontSize: isPhone ? 22 : 26, fontWeight: 700, letterSpacing: -0.4 }}>Employees</h1>
          <div style={{ marginTop: 4, fontSize: 13, color: A.textDim }}>
            {employees == null ? 'Loading…' : `${employees.length} account${employees.length === 1 ? '' : 's'} · employees, managers & admin`}
          </div>
        </div>
        <button onClick={() => setEditing({ role: 'employee' })} style={secondaryBtnA}>+ Add employee</button>
        <button onClick={() => setEditing({ role: 'manager' })} style={primaryBtn}>+ Add manager</button>
      </div>

      {error ? (
        <div style={{
          background: A.dangerBg, color: A.danger, border: `1px solid ${A.danger}33`,
          padding: '10px 14px', borderRadius: 8, fontSize: 13, marginBottom: 14,
        }}>{error}</div>
      ) : null}

      {employees == null ? (
        <div style={{ padding: 40, textAlign: 'center', color: A.textDim }}>Loading employees…</div>
      ) : isPhone ? (
        <EmployeeCardList employees={employees} onEdit={setEditing} onDelete={onDelete} />
      ) : (
        <EmployeeTable employees={employees} onEdit={setEditing} onDelete={onDelete} />
      )}

      {editing ? (
        <EmployeeEditModal
          employee={editing.id ? editing : null}
          presetRole={editing.id ? undefined : editing.role}
          onClose={() => setEditing(null)}
          onSave={onSave}
        />
      ) : null}
    </div>
  );
}

function RoleBadge({ role }) {
  const palette = {
    admin:    { bg: A.accentDim, fg: A.accent },
    manager:  { bg: A.okBg,      fg: A.ok     },
    employee: { bg: A.row,       fg: A.textMid },
  }[role] || { bg: A.row, fg: A.textMid };
  return (
    <span style={{
      padding: '2px 10px', borderRadius: 999, fontSize: 11, fontWeight: 700,
      background: palette.bg, color: palette.fg, textTransform: 'capitalize',
    }}>{role}</span>
  );
}

function EmployeeTable({ employees, onEdit, onDelete }) {
  return (
    <div style={{
      background: A.surface, border: `1px solid ${A.border}`, borderRadius: 12, overflow: 'hidden',
    }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', tableLayout: 'fixed', fontSize: 13 }}>
        <colgroup>
          <col style={{ width: '24%' }} />
          <col style={{ width: '20%' }} />
          <col style={{ width: '14%' }} />
          <col style={{ width: '17%' }} />
          <col style={{ width: '11%' }} />
          <col style={{ width: '14%' }} />
        </colgroup>
        <thead>
          <tr style={{ background: A.row, color: A.textMid }}>
            <Th>Name</Th>
            <Th>Username</Th>
            <Th>Role</Th>
            <Th>Password</Th>
            <Th>Status</Th>
            <Th style={{ textAlign: 'right' }}>Actions</Th>
          </tr>
        </thead>
        <tbody>
          {employees.map((e) => {
            const isAdmin = e.role === 'admin';
            return (
              <tr key={e.id} style={{ borderTop: `1px solid ${A.border}` }}>
                <Td truncate title={e.name || ''}><strong style={{ fontWeight: 600 }}>{e.name || '—'}</strong></Td>
                <Td truncate mono title={e.username}>{e.username}</Td>
                <Td><RoleBadge role={e.role} /></Td>
                <Td><PasswordCell value={e.password || ''} /></Td>
                <Td>{e.active
                  ? <span style={{ color: A.ok, fontWeight: 600 }}>Active</span>
                  : <span style={{ color: A.textDim }}>Inactive</span>}</Td>
                <Td style={{ textAlign: 'right', whiteSpace: 'nowrap' }}>
                  <button onClick={() => onEdit(e)} style={miniBtn}>Edit</button>
                  <button
                    onClick={() => onDelete(e)}
                    disabled={isAdmin}
                    title={isAdmin ? 'The admin account cannot be deleted' : ''}
                    style={{
                      ...miniBtn, color: isAdmin ? A.textDim : A.danger, marginLeft: 6,
                      opacity: isAdmin ? 0.5 : 1, cursor: isAdmin ? 'not-allowed' : 'pointer',
                    }}
                  >Delete</button>
                </Td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function EmployeeCardList({ employees, onEdit, onDelete }) {
  return (
    <div style={{ display: 'grid', gap: 10 }}>
      {employees.map((e) => {
        const isAdmin = e.role === 'admin';
        return (
          <div key={e.id} style={{
            background: A.surface, border: `1px solid ${A.border}`, borderRadius: 10, padding: 14,
          }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10 }}>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ fontWeight: 600 }}>{e.name || '—'}</div>
                <div style={{ fontSize: 12, color: A.textDim, fontFamily: A.mono }}>{e.username}</div>
              </div>
              <RoleBadge role={e.role} />
            </div>
            <div style={{ marginTop: 10, display: 'grid', gap: 6, fontSize: 12, color: A.textMid }}>
              <AdminRow label="Password" value={<PasswordCell value={e.password || ''} />} />
              <AdminRow label="Status" value={e.active ? 'Active' : 'Inactive'} />
            </div>
            <div style={{ marginTop: 12, display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <button onClick={() => onEdit(e)} style={miniBtn}>Edit</button>
              {!isAdmin ? (
                <button onClick={() => onDelete(e)} style={{ ...miniBtn, color: A.danger }}>Delete</button>
              ) : null}
            </div>
          </div>
        );
      })}
    </div>
  );
}

function EmployeeEditModal({ employee, presetRole, onClose, onSave }) {
  const isNew = !employee;
  const isAdmin = employee?.role === 'admin';
  const [form, setForm] = React.useState(() => ({
    name:     employee?.name || '',
    username: employee?.username || '',
    email:    employee?.email || '',
    password: employee?.password || (isNew ? generateRandomPassword() : ''),
    role:     employee?.role || presetRole || 'employee',
    active:   employee ? employee.active !== false : true,
  }));
  const initialJsonRef = React.useRef(null);
  if (initialJsonRef.current === null) initialJsonRef.current = JSON.stringify(form);

  const [error, setError] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
  const isDirty = JSON.stringify(form) !== initialJsonRef.current;

  const requestClose = () => {
    if (isDirty && !window.confirm('You have unsaved changes. Discard them?')) return;
    onClose();
  };

  const submit = async (e) => {
    e?.preventDefault?.();
    setError('');
    if (!form.username.trim()) { setError('Username is required'); return; }
    if (!form.password.trim()) { setError('Password is required'); return; }
    setBusy(true);
    try {
      const payload = {
        name: form.name,
        username: form.username,
        email: form.email,
        password: form.password,
        active: form.active,
      };
      if (!isAdmin) payload.role = form.role;
      await onSave(payload, employee?.id);
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div onClick={requestClose} style={{
      position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.45)',
      display: 'grid', placeItems: 'start center', padding: '40px 12px', overflowY: 'auto', zIndex: 50,
    }}>
      <form onClick={(e) => e.stopPropagation()} onSubmit={submit} style={{
        width: '100%', maxWidth: 480, background: A.surface, borderRadius: 14,
        boxShadow: '0 30px 80px rgba(15,23,42,0.30)', overflow: 'hidden',
      }}>
        <div style={{
          padding: '16px 22px', borderBottom: `1px solid ${A.border}`,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{ fontSize: 16, fontWeight: 700 }}>
            {isNew ? `Add ${form.role}` : `Edit ${employee.name || employee.username}`}
          </div>
          {isAdmin ? <RoleBadge role="admin" /> : null}
          <div style={{ flex: 1 }} />
          <button type="button" onClick={requestClose} style={{
            border: 'none', background: 'transparent', color: A.textDim,
            fontSize: 20, cursor: 'pointer', padding: 4,
          }}>×</button>
        </div>

        <div style={{ padding: 22, display: 'grid', gap: 14 }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            <Field label="Name">
              <input value={form.name} onChange={set('name')} style={inputStyle} />
            </Field>
            <Field label="Role">
              <select value={form.role} onChange={set('role')} disabled={isAdmin}
                style={{ ...inputStyle, background: isAdmin ? A.row : '#fff', cursor: isAdmin ? 'not-allowed' : 'pointer' }}>
                {isAdmin ? <option value="admin">Admin</option> : null}
                <option value="employee">Employee</option>
                <option value="manager">Manager</option>
              </select>
            </Field>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            <Field label="Username *" hint="Used to sign in.">
              <input value={form.username} onChange={set('username')} style={inputStyle} />
            </Field>
            <Field label="Email">
              <input type="email" value={form.email} onChange={set('email')} style={inputStyle} />
            </Field>
          </div>

          <Field label="Password *">
            <div style={{ display: 'flex', gap: 6 }}>
              <input value={form.password} onChange={set('password')} style={{ ...inputStyle, flex: 1 }} />
              <button type="button"
                onClick={() => setForm((f) => ({ ...f, password: generateRandomPassword() }))}
                style={secondaryBtnA} title="Generate new password">↻</button>
            </div>
          </Field>

          <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: A.text, cursor: 'pointer' }}>
            <input type="checkbox" checked={form.active}
              onChange={(e) => setForm((f) => ({ ...f, active: e.target.checked }))} />
            Active (can sign in)
          </label>

          {isAdmin ? (
            <div style={{ fontSize: 12, color: A.textDim }}>
              This is the admin account — its role is fixed and it cannot be deleted.
            </div>
          ) : null}

          {error ? (
            <div style={{
              background: A.dangerBg, color: A.danger, border: `1px solid ${A.danger}33`,
              padding: '8px 12px', borderRadius: 8, fontSize: 13,
            }}>{error}</div>
          ) : null}
        </div>

        <div style={{
          padding: '14px 22px', borderTop: `1px solid ${A.border}`,
          display: 'flex', gap: 10, justifyContent: 'flex-end',
        }}>
          <button type="button" onClick={requestClose} style={secondaryBtnA}>Cancel</button>
          <button type="submit" disabled={busy} style={{
            ...primaryBtn, opacity: busy ? 0.7 : 1, cursor: busy ? 'wait' : 'pointer',
          }}>{busy ? 'Saving…' : (isNew ? 'Add account' : 'Save changes')}</button>
        </div>
      </form>
    </div>
  );
}

function AdminTopBar({ onSignOut, view, setView, role, name }) {
  const isAdmin = role === 'admin';
  return (
    <div style={{
      background: A.surface, borderBottom: `1px solid ${A.border}`,
      padding: '12px 20px', display: 'flex', alignItems: 'center', gap: 12,
    }}>
      <BrandLogo size={28} radius={7} />
      <div style={{ fontSize: 14, fontWeight: 600 }}>{isAdmin ? 'Admin' : 'Manager'}</div>
      {role ? <RoleBadge role={role} /> : null}
      <div style={{ flex: 1 }} />
      {/* Managers can manage customers but not staff accounts, so hide the toggle. */}
      {isAdmin ? <ViewSwitch view={view} setView={setView} /> : null}
      {name ? <div style={{ fontSize: 13, color: A.textMid, whiteSpace: 'nowrap' }}>{name}</div> : null}
      <button onClick={onSignOut} style={secondaryBtnA}>Sign out</button>
    </div>
  );
}

// Segmented toggle between the Resellers and Employees admin views (admin-only).
function ViewSwitch({ view, setView }) {
  const tabs = [
    { key: 'resellers', label: 'Resellers' },
    { key: 'employees', label: 'Employees' },
  ];
  return (
    <div style={{
      display: 'inline-flex', padding: 3, gap: 2, borderRadius: 10,
      background: A.bg, border: `1px solid ${A.border}`,
    }}>
      {tabs.map((t) => {
        const active = view === t.key;
        return (
          <button key={t.key} type="button" onClick={() => setView(t.key)} style={{
            height: 30, padding: '0 14px', border: 'none', borderRadius: 7,
            background: active ? A.surface : 'transparent',
            color: active ? A.accent : A.textMid,
            fontFamily: A.font, fontSize: 13, fontWeight: active ? 700 : 500,
            cursor: 'pointer',
            boxShadow: active ? '0 1px 2px rgba(15,23,42,0.10)' : 'none',
          }}>{t.label}</button>
        );
      })}
    </div>
  );
}

function RegionTabs({ region, setRegion, right }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'flex-end', marginBottom: 16,
      borderBottom: `1px solid ${A.border}`,
    }}>
      <div style={{ display: 'flex', gap: 4 }}>
        {REGION_TABS.map((r) => {
          const active = region === r;
          return (
            <button key={r} onClick={() => setRegion(r)} style={{
              padding: '10px 16px',
              background: 'transparent', border: 'none',
              borderBottom: active ? `2px solid ${A.accent}` : '2px solid transparent',
              color: active ? A.accent : A.textMid,
              fontFamily: A.font, fontWeight: active ? 700 : 500, fontSize: 14,
              cursor: 'pointer', marginBottom: -1,
            }}>{r}</button>
          );
        })}
      </div>
      <div style={{ flex: 1 }} />
      {right ? <div style={{ paddingBottom: 6 }}>{right}</div> : null}
    </div>
  );
}

// ── DESKTOP TABLE ──────────────────────────────────────────────────────────
function ResellerTable({ resellers, sort, onSort, onEdit, onDelete, canDelete = true, expanded, setExpanded }) {
  const toggleExpand = (id) => setExpanded((s) => {
    const next = new Set(s);
    if (next.has(id)) next.delete(id); else next.add(id);
    return next;
  });
  const stopPropagation = (e) => e.stopPropagation();

  return (
    <div style={{
      background: A.surface, border: `1px solid ${A.border}`, borderRadius: 12,
      overflow: 'hidden',
    }}>
      <table style={{
        width: '100%', borderCollapse: 'collapse',
        tableLayout: 'fixed', fontSize: 13,
      }}>
        <colgroup>
          <col style={{ width: '3%'  }} />{/* Expand chevron */}
          <col style={{ width: '16%' }} />{/* Company */}
          <col style={{ width: '12%' }} />{/* Contact */}
          <col style={{ width: '19%' }} />{/* Email */}
          <col style={{ width: '6%'  }} />{/* Terms */}
          <col style={{ width: '9%'  }} />{/* Country */}
          <col style={{ width: '8%'  }} />{/* Warehouse */}
          <col style={{ width: '6%'  }} />{/* Discount */}
          <col style={{ width: '5%'  }} />{/* Type */}
          <col style={{ width: '6%'  }} />{/* Brand */}
          <col style={{ width: '10%' }} />{/* Actions */}
        </colgroup>
        <thead>
          <tr style={{ background: A.row, color: A.textMid }}>
            <Th />
            <Th sortKey="company_name" currentSort={sort} onSort={onSort}>Company</Th>
            <Th>Contact</Th>
            <Th>Email</Th>
            <Th sortKey="terms" currentSort={sort} onSort={onSort}>Terms</Th>
            <Th sortKey="country" currentSort={sort} onSort={onSort}>Country</Th>
            <Th sortKey="warehouse" currentSort={sort} onSort={onSort}>Warehouse</Th>
            <Th align="right">Discount</Th>
            <Th sortKey="type" currentSort={sort} onSort={onSort}>Type</Th>
            <Th sortKey="brand" currentSort={sort} onSort={onSort}>Brand</Th>
            <Th style={{ textAlign: 'right' }}>Actions</Th>
          </tr>
        </thead>
        <tbody>
          {resellers.map((r) => {
            const primary = primaryContact(r);
            const contactName = primary?.name || '—';
            const contactEmail = primary?.email || r.email;
            const totalContacts = (r.contacts || []).length;
            const isExpanded = expanded.has(r.id);
            const canExpand = totalContacts > 0 || (r.ship_to_locations || []).length > 0;
            return (
              <React.Fragment key={r.id}>
                <tr
                  onClick={canExpand ? () => toggleExpand(r.id) : undefined}
                  style={{
                    borderTop: `1px solid ${A.border}`,
                    cursor: canExpand ? 'pointer' : 'default',
                    background: isExpanded ? A.accentDim : undefined,
                  }}
                >
                  <Td style={{ textAlign: 'center', color: A.textMid, paddingLeft: 12, paddingRight: 0 }}>
                    {canExpand ? (
                      <span style={{ fontSize: 11, opacity: 0.7 }}>{isExpanded ? '▾' : '▸'}</span>
                    ) : null}
                  </Td>
                  <Td truncate><strong style={{ fontWeight: 600 }} title={r.company_name || ''}>{r.company_name || '—'}</strong></Td>
                  <Td truncate title={contactName}>
                    {contactName}
                    {totalContacts > 1 ? (
                      <span style={{
                        marginLeft: 6, padding: '1px 6px', borderRadius: 10,
                        background: A.accentDim, color: A.accent, fontSize: 10, fontWeight: 700,
                      }}>+{totalContacts - 1}</span>
                    ) : null}
                  </Td>
                  <Td truncate>
                    {contactEmail ? (
                      <a href={`mailto:${contactEmail}`} onClick={stopPropagation} style={{
                        fontFamily: A.mono, fontSize: 12, color: A.accent, textDecoration: 'none',
                      }} title={contactEmail}>{contactEmail}</a>
                    ) : <span style={{ color: A.textDim }}>—</span>}
                  </Td>
                  <Td truncate title={r.terms || ''}>{r.terms ? <TermsBadge value={r.terms} /> : <span style={{ color: A.textDim }}>—</span>}</Td>
                  <Td truncate title={r.country || ''}>{r.country || '—'}</Td>
                  <Td><WarehouseChip warehouse={r.warehouse} /></Td>
                  <Td align="right" mono>{Number(r.discount_percent || 0).toFixed(0)}%</Td>
                  <Td truncate title={r.type || ''}>{r.type || '—'}</Td>
                  <Td truncate title={r.brand || ''}>{r.brand || '—'}</Td>
                  <Td style={{ textAlign: 'right', whiteSpace: 'nowrap' }} onClick={stopPropagation}>
                    <button onClick={() => onEdit(r)} style={miniBtn}>Edit</button>
                    {canDelete ? (
                      <button onClick={() => onDelete(r)} style={{ ...miniBtn, color: A.danger, marginLeft: 6 }}>Delete</button>
                    ) : null}
                  </Td>
                </tr>
                {isExpanded ? (
                  <tr>
                    <td colSpan={11} style={{ background: A.row, padding: 0, borderTop: `1px solid ${A.border}` }}>
                      <ExpandedResellerDetail reseller={r} />
                    </td>
                  </tr>
                ) : null}
              </React.Fragment>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function ExpandedResellerDetail({ reseller }) {
  const contacts = reseller.contacts || [];
  const locations = reseller.ship_to_locations || [];
  return (
    <div style={{ padding: '14px 18px 18px 38px' }}>
      <div style={{
        fontSize: 10, fontWeight: 700, color: A.textMid,
        textTransform: 'uppercase', letterSpacing: 0.6, marginBottom: 8,
      }}>Contacts ({contacts.length})</div>
      {contacts.length === 0 ? (
        <div style={{ fontSize: 13, color: A.textDim, fontStyle: 'italic' }}>No contacts yet.</div>
      ) : (
        <div style={{ display: 'grid', gap: 8 }}>
          {contacts.map((c) => (
            <div key={c.id || c.email} style={{
              display: 'grid',
              gridTemplateColumns: '20px minmax(140px, 1.2fr) minmax(200px, 1.6fr) minmax(110px, 1fr) auto',
              alignItems: 'center', columnGap: 12, rowGap: 4, padding: '10px 12px',
              background: '#fff', borderRadius: 8, border: `1px solid ${A.border}`,
            }}>
              <span style={{ color: c.is_primary ? A.warn : 'transparent', fontSize: 14 }} title={c.is_primary ? 'Primary' : ''}>★</span>
              <span style={{ fontWeight: 600, fontSize: 13 }}>{c.name || <em style={{ color: A.textDim }}>(no name)</em>}</span>
              {c.email ? (
                <a href={`mailto:${c.email}`} style={{
                  fontFamily: A.mono, fontSize: 12, color: A.accent, textDecoration: 'none',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{c.email}</a>
              ) : <span style={{ color: A.textDim, fontSize: 12 }}>—</span>}
              <span style={{ fontSize: 12, color: A.textMid, fontFamily: A.mono }}>{c.phone || ''}</span>
              {!c.active ? (
                <span style={{
                  padding: '2px 8px', borderRadius: 999, background: A.warnBg, color: A.warn,
                  fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.4,
                }}>Inactive</span>
              ) : <span />}
              <span style={{
                gridColumn: '2 / -1', display: 'flex', flexWrap: 'wrap', gap: 14,
                fontSize: 11, color: A.textDim, alignItems: 'center',
              }}>
                {c.department ? <span>{c.department}</span> : null}
                <span>
                  <span style={{ color: A.textDim, marginRight: 4, textTransform: 'uppercase', letterSpacing: 0.4, fontWeight: 700 }}>login</span>
                  <span style={{ fontFamily: A.mono, color: A.text }}>{c.username || <em>(none)</em>}</span>
                </span>
                <span>
                  <span style={{ color: A.textDim, marginRight: 4, textTransform: 'uppercase', letterSpacing: 0.4, fontWeight: 700 }}>pwd</span>
                  <PasswordCell value={c.password || ''} />
                </span>
              </span>
            </div>
          ))}
        </div>
      )}

      {locations.length > 0 ? (
        <>
          <div style={{
            fontSize: 10, fontWeight: 700, color: A.textMid,
            textTransform: 'uppercase', letterSpacing: 0.6, marginTop: 16, marginBottom: 8,
          }}>Ship-to locations ({locations.length})</div>
          <div style={{ display: 'grid', gap: 6 }}>
            {locations.map((l) => (
              <div key={l.id || l.label} style={{
                display: 'grid',
                gridTemplateColumns: '20px minmax(120px, 1fr) minmax(220px, 2.5fr) minmax(90px, auto) minmax(120px, auto)',
                alignItems: 'center', gap: 12, padding: '8px 12px',
                background: '#fff', borderRadius: 8, border: `1px solid ${A.border}`,
              }}>
                <span style={{ color: l.is_default ? A.warn : 'transparent', fontSize: 14 }} title={l.is_default ? 'Default' : ''}>★</span>
                <span style={{ fontWeight: 600, fontSize: 13 }}>{l.label || <em style={{ color: A.textDim }}>(no label)</em>}</span>
                <span style={{ fontSize: 12, color: A.textMid }}>{l.address || '—'}</span>
                <span style={{ fontSize: 12, color: A.textMid }}>{l.carrier || ''}</span>
                <span style={{ fontSize: 12, color: A.textMid, fontFamily: A.mono }}>{l.account_number || ''}</span>
              </div>
            ))}
          </div>
        </>
      ) : null}
    </div>
  );
}

function primaryContact(r) {
  const cs = r.contacts || [];
  if (!cs.length) return null;
  return cs.find((c) => c.is_primary) || cs[0];
}

function Th({ children, align, style, sortKey, currentSort, onSort }) {
  const sortable = !!sortKey;
  const active = sortable && currentSort?.key === sortKey;
  const dir = active ? currentSort.dir : null;
  const indicator = active ? (dir === 'asc' ? ' ↑' : ' ↓') : (sortable ? ' ↕' : '');
  return (
    <th
      onClick={sortable ? () => onSort(sortKey) : undefined}
      style={{
        textAlign: align || 'left', padding: '10px 10px', fontWeight: 600,
        fontSize: 11, letterSpacing: 0.4, textTransform: 'uppercase',
        borderBottom: `1px solid ${A.border}`, whiteSpace: 'nowrap',
        cursor: sortable ? 'pointer' : 'default',
        userSelect: 'none',
        color: active ? A.accent : undefined,
        ...style,
      }}
    >{children}<span style={{ opacity: active ? 1 : 0.4 }}>{indicator}</span></th>
  );
}

function Td({ children, align, mono, style, truncate, title, onClick }) {
  return (
    <td title={title} onClick={onClick} style={{
      padding: '10px 10px', verticalAlign: 'middle',
      textAlign: align || 'left',
      fontFamily: mono ? A.mono : undefined,
      ...(truncate ? { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } : {}),
      ...style,
    }}>{children}</td>
  );
}

function TermsBadge({ value }) {
  const palette = {
    NET30:   { bg: A.accentDim, fg: A.accent },
    NET60:   { bg: A.accentDim, fg: A.accent },
    NET90:   { bg: A.warnBg,    fg: A.warn   },
    Prepaid: { bg: A.okBg,      fg: A.ok     },
    COD:     { bg: A.okBg,      fg: A.ok     },
  }[value] || { bg: A.row, fg: A.textMid };
  return (
    <span style={{
      padding: '2px 8px', borderRadius: 999, fontSize: 11, fontWeight: 700,
      background: palette.bg, color: palette.fg, fontFamily: A.mono,
    }}>{value}</span>
  );
}

function WarehouseChip({ warehouse }) {
  if (!warehouse) return <span style={{ color: A.textDim }}>—</span>;
  const palette = {
    Shanghai:   { bg: '#fff7e6', fg: '#b54708' },
    California: { bg: '#eaf0ff', fg: '#2e5dff' },
    Germany:    { bg: '#ecfdf3', fg: '#067647' },
  }[warehouse] || { bg: A.row, fg: A.textMid };
  return (
    <span style={{
      padding: '2px 8px', borderRadius: 999, fontSize: 11, fontWeight: 600,
      background: palette.bg, color: palette.fg,
    }}>{warehouse}</span>
  );
}

function PasswordCell({ value }) {
  const [shown, setShown] = React.useState(false);
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
      <span style={{ fontFamily: A.mono, fontSize: 12 }}>
        {shown ? value : '••••••'}
      </span>
      <button
        onClick={() => setShown((s) => !s)}
        style={{
          border: 'none', background: 'transparent', color: A.accent,
          cursor: 'pointer', fontSize: 11, padding: 0, fontFamily: A.font,
        }}
      >{shown ? 'hide' : 'show'}</button>
    </span>
  );
}

// ── MOBILE CARDS ───────────────────────────────────────────────────────────
function ResellerCardList({ resellers, onEdit, onDelete, canDelete = true }) {
  return (
    <div style={{ display: 'grid', gap: 10 }}>
      {resellers.map((r) => {
        const primary = primaryContact(r);
        const contactEmail = primary?.email || r.email;
        return (
          <div key={r.id} style={{
            background: A.surface, border: `1px solid ${A.border}`, borderRadius: 10,
            padding: 14,
          }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10 }}>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ fontWeight: 600 }}>{r.company_name || '—'}</div>
                <div style={{ fontSize: 12, color: A.textDim }}>
                  {primary?.name || '—'}
                  {(r.contacts || []).length > 1 ? ` (+${r.contacts.length - 1} more)` : ''}
                </div>
              </div>
              <WarehouseChip warehouse={r.warehouse} />
            </div>
            <div style={{
              marginTop: 10, display: 'grid', gridTemplateColumns: '1fr', gap: 6,
              fontSize: 12, color: A.textMid,
            }}>
              <AdminRow label="Email" value={
                contactEmail ? <a href={`mailto:${contactEmail}`} style={{ color: A.accent, textDecoration: 'none', fontFamily: A.mono }}>{contactEmail}</a> : '—'
              } />
              <AdminRow label="Country" value={r.country || '—'} />
              <AdminRow label="Discount" value={`${Number(r.discount_percent || 0).toFixed(0)}%`} mono />
              {r.type ? <AdminRow label="Type" value={r.type} /> : null}
              {r.brand ? <AdminRow label="Brand" value={r.brand} /> : null}
              {r.terms ? <AdminRow label="Terms" value={<TermsBadge value={r.terms} />} /> : null}
              <AdminRow label="Contacts" value={`${(r.contacts || []).length} (tap Edit to manage logins)`} />
            </div>
            <div style={{ marginTop: 12, display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <button onClick={() => onEdit(r)} style={miniBtn}>Edit</button>
              {canDelete ? (
                <button onClick={() => onDelete(r)} style={{ ...miniBtn, color: A.danger }}>Delete</button>
              ) : null}
            </div>
          </div>
        );
      })}
    </div>
  );
}

function AdminRow({ label, value, mono }) {
  return (
    <div style={{ display: 'flex', gap: 8, alignItems: 'baseline' }}>
      <div style={{ width: 84, color: A.textDim, fontSize: 11, textTransform: 'uppercase', letterSpacing: 0.4 }}>{label}</div>
      <div style={{ flex: 1, fontFamily: mono ? A.mono : undefined, fontSize: 13, color: A.text, wordBreak: 'break-word' }}>{value}</div>
    </div>
  );
}

// ── EDIT MODAL ─────────────────────────────────────────────────────────────
function ResellerEditModal({ reseller, onClose, onSave }) {
  const isNew = !reseller;
  const [form, setForm] = React.useState(() => buildInitialForm(reseller));
  const initialJsonRef = React.useRef(null);
  if (initialJsonRef.current === null) initialJsonRef.current = JSON.stringify(form);

  const [error, setError] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));

  const isDirty = JSON.stringify(form) !== initialJsonRef.current;

  const requestClose = () => {
    if (isDirty && !window.confirm('You have unsaved changes. Discard them?')) return;
    onClose();
  };

  const submit = async (e) => {
    e?.preventDefault?.();
    setError('');
    if (!form.email.trim()) { setError('Company email is required'); return; }
    if (!form.contacts.length) { setError('At least one contact is required'); return; }
    setBusy(true);
    try {
      const payload = {
        email: form.email,
        company_name: form.company_name,
        country: form.country,
        region: form.region,
        warehouse: form.warehouse || null,
        discount_percent: form.discount_percent === '' ? 0 : Number(form.discount_percent),
        type: form.type,
        brand: form.brand,
        status: form.status,
        notes: form.notes,
        terms: form.terms || null,
        contacts: form.contacts,
        ship_to_locations: form.ship_to_locations,
      };
      await onSave(payload, reseller?.id);
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div
      onClick={requestClose}
      style={{
        position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.45)',
        display: 'grid', placeItems: 'start center',
        padding: '40px 12px', overflowY: 'auto', zIndex: 50,
      }}
    >
      <form
        onClick={(e) => e.stopPropagation()}
        onSubmit={submit}
        style={{
          width: '100%', maxWidth: 620, background: A.surface, borderRadius: 14,
          boxShadow: '0 30px 80px rgba(15,23,42,0.30)', overflow: 'hidden',
        }}
      >
        <div style={{
          padding: '16px 22px', borderBottom: `1px solid ${A.border}`,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{ fontSize: 16, fontWeight: 700 }}>
            {isNew ? 'Add reseller' : `Edit ${reseller.company_name || reseller.email}`}
          </div>
          {isDirty ? (
            <span style={{
              padding: '2px 8px', borderRadius: 999, background: A.warnBg, color: A.warn,
              fontSize: 11, fontWeight: 700,
            }}>Unsaved</span>
          ) : null}
          <div style={{ flex: 1 }} />
          <button type="button" onClick={requestClose} style={{
            border: 'none', background: 'transparent', color: A.textDim,
            fontSize: 20, cursor: 'pointer', padding: 4,
          }}>×</button>
        </div>

        <div style={{ padding: 22, display: 'grid', gap: 24 }}>
          <Section title="Company">
            <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 12 }}>
              <Field label="Company name">
                <input value={form.company_name} onChange={set('company_name')} style={inputStyle} />
              </Field>
              <Field label="Billing email *" hint="Used for billing/invoice copies. Logins are per contact.">
                <input type="email" required value={form.email} onChange={set('email')} style={inputStyle} />
              </Field>
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
              <Field label="Country">
                <input value={form.country} onChange={set('country')} style={inputStyle} />
              </Field>
              <Field label="Region">
                <select value={form.region} onChange={set('region')} style={inputStyle}>
                  <option value="">—</option>
                  <option>International</option>
                  <option>Domestic</option>
                </select>
              </Field>
              <Field label="Default warehouse">
                <select value={form.warehouse} onChange={set('warehouse')} style={inputStyle}>
                  <option value="">—</option>
                  {ADMIN_WAREHOUSES.map((w) => <option key={w}>{w}</option>)}
                </select>
              </Field>
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 12 }}>
              <Field label="Discount %">
                <input type="number" step="10" min="0" max="100"
                  value={form.discount_percent} onChange={set('discount_percent')} style={inputStyle} />
              </Field>
              <Field label="Type">
                <select value={form.type} onChange={set('type')} style={inputStyle}>
                  <option value="">—</option>
                  {TYPE_OPTIONS.map((t) => <option key={t}>{t}</option>)}
                </select>
              </Field>
              <Field label="Brands carried">
                <select value={form.brand} onChange={set('brand')} style={inputStyle}>
                  <option value="">—</option>
                  {BRAND_OPTIONS.map((b) => <option key={b}>{b}</option>)}
                </select>
              </Field>
              <Field label="Terms">
                <select value={form.terms} onChange={set('terms')} style={inputStyle}>
                  <option value="">—</option>
                  {TERMS_OPTIONS.map((t) => <option key={t}>{t}</option>)}
                </select>
              </Field>
            </div>
          </Section>

          <ContactsEditor
            contacts={form.contacts}
            setContacts={(updater) => setForm((f) => ({ ...f, contacts: typeof updater === 'function' ? updater(f.contacts) : updater }))}
          />

          <ShipToEditor
            locations={form.ship_to_locations}
            setLocations={(updater) => setForm((f) => ({ ...f, ship_to_locations: typeof updater === 'function' ? updater(f.ship_to_locations) : updater }))}
          />

          <Section title="Notes">
            <Field label="Internal notes">
              <textarea value={form.notes} onChange={set('notes')} rows={2}
                style={{ ...inputStyle, height: 'auto', resize: 'vertical', paddingTop: 10 }} />
            </Field>
          </Section>

          {error ? (
            <div style={{
              background: A.dangerBg, color: A.danger, border: `1px solid ${A.danger}33`,
              padding: '8px 12px', borderRadius: 8, fontSize: 13,
            }}>{error}</div>
          ) : null}
        </div>

        <div style={{
          padding: '14px 22px', borderTop: `1px solid ${A.border}`,
          display: 'flex', gap: 10, justifyContent: 'flex-end',
        }}>
          <button type="button" onClick={requestClose} style={secondaryBtnA}>Cancel</button>
          <button type="submit" disabled={busy} style={{
            ...primaryBtn, opacity: busy ? 0.7 : 1,
            cursor: busy ? 'wait' : 'pointer',
          }}>{busy ? 'Saving…' : (isNew ? 'Add reseller' : 'Save changes')}</button>
        </div>
      </form>
    </div>
  );
}

function buildInitialForm(reseller) {
  return {
    email:            reseller?.email || '',
    company_name:     reseller?.company_name || '',
    country:          reseller?.country || '',
    region:           reseller?.region || '',
    warehouse:        reseller?.warehouse || '',
    discount_percent: reseller?.discount_percent != null ? String(reseller.discount_percent) : '40',
    type:             reseller?.type || '',
    brand:            reseller?.brand || '',
    status:           reseller?.status || '',
    notes:            reseller?.notes || '',
    terms:            reseller?.terms || '',
    contacts:         (reseller?.contacts && reseller.contacts.length)
                        ? reseller.contacts.map(normalizeContactForForm)
                        : [blankContact(true)],
    ship_to_locations: (reseller?.ship_to_locations && reseller.ship_to_locations.length)
                         ? reseller.ship_to_locations.map(normalizeLocationForForm)
                         : [blankLocation(true)],
  };
}

function normalizeContactForForm(c) {
  return {
    name: c.name || '',
    email: c.email || '',
    phone: c.phone || '',
    username: c.username || '',
    password: c.password || '',
    department: c.department || '',
    product_categories: Array.isArray(c.product_categories) ? c.product_categories : [],
    is_primary: !!c.is_primary,
    active: c.active !== false,
  };
}

function normalizeLocationForForm(l) {
  return {
    label: l.label || '',
    address: l.address || '',
    carrier: l.carrier || '',
    account_number: l.account_number || '',
    is_default: !!l.is_default,
  };
}

function blankContact(isPrimary) {
  return {
    name: '', email: '', phone: '', username: '', password: generateRandomPassword(),
    department: '', product_categories: [], is_primary: !!isPrimary, active: true,
  };
}

function blankLocation(isDefault) {
  return { label: '', address: '', carrier: '', account_number: '', is_default: !!isDefault };
}

// ── MULTI-CONTACT EDITOR ───────────────────────────────────────────────────
function ContactsEditor({ contacts, setContacts }) {
  const [idx, setIdx] = React.useState(0);
  const safeIdx = Math.min(idx, contacts.length - 1);
  const current = contacts[safeIdx];

  const updateCurrent = (patch) => {
    setContacts((cs) => cs.map((c, i) => i === safeIdx ? { ...c, ...patch } : c));
  };

  const addNew = () => {
    setContacts((cs) => {
      const next = [...cs, blankContact(cs.length === 0)];
      setIdx(next.length - 1);
      return next;
    });
  };

  const deleteCurrent = () => {
    if (contacts.length <= 1) { window.alert('At least one contact is required.'); return; }
    const hasData = current.name || current.email || current.phone;
    if (hasData && !window.confirm('Delete this contact?')) return;
    setContacts((cs) => {
      const next = cs.filter((_, i) => i !== safeIdx);
      if (current.is_primary && next.length && !next.some((c) => c.is_primary)) {
        next[0] = { ...next[0], is_primary: true };
      }
      setIdx(Math.max(0, safeIdx - 1));
      return next;
    });
  };

  const setPrimary = () => {
    setContacts((cs) => cs.map((c, i) => ({ ...c, is_primary: i === safeIdx })));
  };

  const togglePCategory = (cat) => {
    const has = current.product_categories.includes(cat);
    updateCurrent({
      product_categories: has
        ? current.product_categories.filter((x) => x !== cat)
        : [...current.product_categories, cat],
    });
  };

  return (
    <Section
      title={`Contacts (${contacts.length})`}
      right={<button type="button" onClick={addNew} style={addMoreBtn}>+ Add contact</button>}
    >
      <PillRow>
        {contacts.map((c, i) => (
          <Pill key={i} active={i === safeIdx} onClick={() => setIdx(i)}>
            {c.name || c.email || `Contact ${i + 1}`}
            {c.is_primary ? ' ★' : ''}
            {!c.active ? ' (inactive)' : ''}
          </Pill>
        ))}
      </PillRow>

      <div style={sectionCard}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Field label="Name">
            <input value={current.name} onChange={(e) => updateCurrent({ name: e.target.value })}
              style={inputStyle} />
          </Field>
          <Field label="Department">
            <input value={current.department} onChange={(e) => updateCurrent({ department: e.target.value })}
              placeholder="Purchasing, AP, Ops…" style={inputStyle} />
          </Field>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Field label="Email">
            <input type="email" value={current.email} onChange={(e) => updateCurrent({ email: e.target.value })}
              style={inputStyle} />
          </Field>
          <Field label="Phone">
            <input value={current.phone} onChange={(e) => updateCurrent({ phone: e.target.value })}
              style={inputStyle} />
          </Field>
        </div>

        <div style={{
          padding: 12, background: '#fff', borderRadius: 8, border: `1px solid ${A.border}`,
          display: 'grid', gap: 12,
        }}>
          <div style={{
            fontSize: 10, fontWeight: 700, color: A.textMid,
            textTransform: 'uppercase', letterSpacing: 0.6,
          }}>Login credentials for this contact</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            <Field label="Username" hint="Defaults to email.">
              <input value={current.username}
                onChange={(e) => updateCurrent({ username: e.target.value })}
                placeholder={current.email} style={inputStyle} />
            </Field>
            <Field label="Password">
              <div style={{ display: 'flex', gap: 6 }}>
                <input value={current.password}
                  onChange={(e) => updateCurrent({ password: e.target.value })}
                  style={{ ...inputStyle, flex: 1 }} />
                <button type="button"
                  onClick={() => updateCurrent({ password: generateRandomPassword() })}
                  style={secondaryBtnA}>↻</button>
              </div>
            </Field>
          </div>
        </div>

        <Field label="Product categories they manage" hint="Comma-separated, e.g. Bags, Straps, FretWraps">
          <input
            value={current.product_categories.join(', ')}
            onChange={(e) => updateCurrent({
              product_categories: e.target.value.split(',').map((s) => s.trim()).filter(Boolean),
            })}
            style={inputStyle}
          />
        </Field>

        <div style={{ display: 'flex', alignItems: 'center', gap: 18, flexWrap: 'wrap' }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: A.text, cursor: 'pointer' }}>
            <input type="checkbox" checked={current.is_primary} onChange={setPrimary} />
            Primary contact
          </label>
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: A.text, cursor: 'pointer' }}>
            <input type="checkbox" checked={current.active}
              onChange={(e) => updateCurrent({ active: e.target.checked })} />
            Active (can place orders)
          </label>
          <div style={{ flex: 1 }} />
          <button type="button" onClick={deleteCurrent}
            style={{ ...miniBtn, color: A.danger, borderColor: A.danger + '44' }}>Delete contact</button>
        </div>
      </div>
    </Section>
  );
}

// ── MULTI-SHIP-TO EDITOR ───────────────────────────────────────────────────
function ShipToEditor({ locations, setLocations }) {
  const [idx, setIdx] = React.useState(0);
  const safeIdx = Math.min(idx, locations.length - 1);
  const current = locations[safeIdx];

  const updateCurrent = (patch) => {
    setLocations((ls) => ls.map((l, i) => i === safeIdx ? { ...l, ...patch } : l));
  };

  const addNew = () => {
    setLocations((ls) => {
      const next = [...ls, blankLocation(ls.length === 0)];
      setIdx(next.length - 1);
      return next;
    });
  };

  const deleteCurrent = () => {
    if (locations.length <= 1) { window.alert('At least one ship-to location is required.'); return; }
    const hasData = current.label || current.address || current.carrier;
    if (hasData && !window.confirm('Delete this ship-to location?')) return;
    setLocations((ls) => {
      const next = ls.filter((_, i) => i !== safeIdx);
      if (current.is_default && next.length && !next.some((l) => l.is_default)) {
        next[0] = { ...next[0], is_default: true };
      }
      setIdx(Math.max(0, safeIdx - 1));
      return next;
    });
  };

  const setDefault = () => {
    setLocations((ls) => ls.map((l, i) => ({ ...l, is_default: i === safeIdx })));
  };

  return (
    <Section
      title={`Ship-to locations (${locations.length})`}
      right={<button type="button" onClick={addNew} style={addMoreBtn}>+ Add ship-to</button>}
    >
      <PillRow>
        {locations.map((l, i) => (
          <Pill key={i} active={i === safeIdx} onClick={() => setIdx(i)}>
            {l.label || `Location ${i + 1}`}
            {l.is_default ? ' ★' : ''}
          </Pill>
        ))}
      </PillRow>

      <div style={sectionCard}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 2fr', gap: 12 }}>
          <Field label="Label" hint="Nickname for this destination.">
            <input value={current.label} onChange={(e) => updateCurrent({ label: e.target.value })}
              placeholder="Main warehouse" style={inputStyle} />
          </Field>
          <Field label="Address">
            <textarea value={current.address} onChange={(e) => updateCurrent({ address: e.target.value })}
              rows={2} placeholder="Street, city, state, postal code, country"
              style={{ ...inputStyle, height: 'auto', resize: 'vertical', paddingTop: 10 }} />
          </Field>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <Field label="Shipping carrier">
            <select value={current.carrier} onChange={(e) => updateCurrent({ carrier: e.target.value })}
              style={inputStyle}>
              <option value="">—</option>
              {CARRIER_OPTIONS.map((c) => <option key={c}>{c}</option>)}
            </select>
          </Field>
          <Field label="Account #" hint="Reseller's own account with this carrier.">
            <input value={current.account_number}
              onChange={(e) => updateCurrent({ account_number: e.target.value })}
              placeholder="199567890" style={inputStyle} />
          </Field>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 18, flexWrap: 'wrap' }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: A.text, cursor: 'pointer' }}>
            <input type="checkbox" checked={current.is_default} onChange={setDefault} />
            Default ship-to
          </label>
          <div style={{ flex: 1 }} />
          <button type="button" onClick={deleteCurrent}
            style={{ ...miniBtn, color: A.danger, borderColor: A.danger + '44' }}>Delete location</button>
        </div>
      </div>
    </Section>
  );
}

// A titled section block: larger heading + a thin divider, with its fields grouped below.
function Section({ title, right, children }) {
  return (
    <section style={{ display: 'grid', gap: 14 }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        paddingBottom: 10, borderBottom: `1px solid ${A.border}`,
      }}>
        <h2 style={{
          margin: 0, fontSize: 17, fontWeight: 700, color: A.text, letterSpacing: -0.3,
        }}>{title}</h2>
        {right ? <div style={{ marginLeft: 'auto' }}>{right}</div> : null}
      </div>
      {children}
    </section>
  );
}

function PillRow({ children }) {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 4 }}>
      {children}
    </div>
  );
}

function Pill({ active, onClick, children }) {
  return (
    <button type="button" onClick={onClick} style={{
      padding: '6px 12px', borderRadius: 999,
      background: active ? A.accent : '#fff',
      color: active ? '#fff' : A.text,
      border: `1px solid ${active ? A.accent : A.borderStrong}`,
      fontSize: 12, fontWeight: 600, fontFamily: A.font, cursor: 'pointer',
      maxWidth: 220, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
    }}>{children}</button>
  );
}

function Field({ label, hint, children }) {
  return (
    <label style={{ display: 'block' }}>
      <div style={{
        fontSize: 11, fontWeight: 600, color: A.textMid,
        textTransform: 'uppercase', letterSpacing: 0.4, marginBottom: 6,
      }}>{label}</div>
      {children}
      {hint ? <div style={{ marginTop: 6, fontSize: 11, color: A.textDim }}>{hint}</div> : null}
    </label>
  );
}

function generateRandomPassword() {
  return String(Math.floor(Math.random() * 900000) + 100000);
}

const inputStyle = {
  width: '100%', height: 40, padding: '0 12px',
  border: `1px solid ${A.borderStrong}`, borderRadius: 8,
  fontSize: 14, fontFamily: A.font, color: A.text, background: '#fff',
  outline: 'none',
};

const primaryBtn = {
  height: 40, padding: '0 18px', border: 'none', borderRadius: 8,
  background: A.accent, color: '#fff', fontSize: 14, fontWeight: 600,
  fontFamily: A.font, cursor: 'pointer',
};

const secondaryBtnA = {
  height: 40, padding: '0 14px', border: `1px solid ${A.borderStrong}`,
  borderRadius: 8, background: '#fff', color: A.text,
  fontSize: 13, fontWeight: 500, fontFamily: A.font, cursor: 'pointer',
};

const miniBtn = {
  height: 30, padding: '0 12px', border: `1px solid ${A.borderStrong}`,
  borderRadius: 6, background: '#fff', color: A.text,
  fontSize: 12, fontWeight: 500, fontFamily: A.font, cursor: 'pointer',
};

const addMoreBtn = {
  height: 28, padding: '0 12px', border: `1px dashed ${A.borderStrong}`,
  borderRadius: 999, background: '#fff', color: A.accent,
  fontSize: 12, fontWeight: 700, fontFamily: A.font, cursor: 'pointer',
};

// Grouped sub-panel holding the active contact / ship-to fields.
const sectionCard = {
  display: 'grid', gap: 14, padding: 16, marginTop: 4,
  background: A.row, borderRadius: 10, border: `1px solid ${A.border}`,
};
