// Clients list + Client detail (per-client Domains + Servers hub)

const ClientsScreen = ({ clients, domains, servers, approvals, role, onGoTo, onSelectClient, onAddClient, onEditClient, onDeleteClient }) => {
  const [q, setQ] = React.useState('');
  const [editing, setEditing] = React.useState(null);
  const [selected, setSelected] = React.useState(new Set());
  const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);
  const selectAllRef = React.useRef(null);
  const filtered = clients.filter(c => c.name.toLowerCase().includes(q.toLowerCase()));

  React.useEffect(() => {
    if (selectAllRef.current) {
      selectAllRef.current.indeterminate = selected.size > 0 && selected.size < filtered.length;
    }
  }, [selected.size, filtered.length]);

  const toggleSelect = (id) => {
    const newSet = new Set(selected);
    if (newSet.has(id)) newSet.delete(id);
    else newSet.add(id);
    setSelected(newSet);
  };

  const toggleSelectAll = () => {
    if (selected.size === filtered.length) {
      setSelected(new Set());
    } else {
      setSelected(new Set(filtered.map(c => c.id)));
    }
  };

  return (
    <>
      <div className="page-head">
        <div>
          <h1>Clients</h1>
          <div className="sub">
            {selected.size > 0
              ? `${selected.size} selected`
              : `${clients.length} active clients · click a row to see their domains & servers`}
          </div>
        </div>
        <div className="page-actions">
          {selected.size > 0 && role === 'admin' && (
            <button className="btn danger" onClick={() => setShowDeleteConfirm(true)}>
              <Icon name="trash" size={13}/> Delete {selected.size} client{selected.size === 1 ? '' : 's'}
            </button>
          )}
          {role === 'admin' && <button className="btn brand" onClick={() => setEditing({ mode: 'create' })}><Icon name="plus" size={13}/> Add client</button>}
        </div>
      </div>

      <div className="filters">
        <input className="filter-input" placeholder="Filter clients…" value={q} onChange={(e) => setQ(e.target.value)} style={{ width: 240 }} />
      </div>

      <div className="card">
        <div className="table-wrap">
          <table className="data">
            <thead>
              <tr>
                {role === 'admin' && (
                  <th style={{ width: 40 }}>
                    <input
                      ref={selectAllRef}
                      type="checkbox"
                      checked={selected.size > 0 && selected.size === filtered.length}
                      onChange={toggleSelectAll}
                      style={{ accentColor: 'var(--brand)', cursor: 'pointer' }}
                    />
                  </th>
                )}
                <th>Client</th>
                <th>Contact</th>
                <th>Domains</th>
                <th>Servers</th>
                <th>Health</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(c => {
                const ds = domains.filter(d => d.clientId === c.id);
                const ss = servers.filter(s => s.clientId === c.id);
                const all = [...ds, ...ss];
                const expired = all.filter(x => window.daysUntil(x.expiry) < 0).length;
                const soon = all.filter(x => { const n = window.daysUntil(x.expiry); return n >= 0 && n <= 30; }).length;
                return (
                  <tr key={c.id} style={{ cursor: 'pointer', background: selected.has(c.id) ? 'var(--bg-selected)' : '' }}>
                    {role === 'admin' && (
                      <td onClick={(e) => { e.stopPropagation(); toggleSelect(c.id); }}>
                        <input
                          type="checkbox"
                          checked={selected.has(c.id)}
                          onChange={() => toggleSelect(c.id)}
                          style={{ accentColor: 'var(--brand)', cursor: 'pointer' }}
                          onClick={(e) => e.stopPropagation()}
                        />
                      </td>
                    )}
                    <td onClick={() => onSelectClient(c.id)}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
                        <Avatar name={c.name} size={28} />
                        <div>
                          <div className="cell-primary">{c.name}</div>
                          <div className="cell-sub">{c.phone}</div>
                        </div>
                      </div>
                    </td>
                    <td><span className="mono" style={{ fontSize: 12 }}>{c.contact}</span></td>
                    <td>
                      <span className="badge brand">{ds.length}</span>
                    </td>
                    <td>
                      <span className="badge blue">{ss.length}</span>
                    </td>
                    <td>
                      {expired > 0 && <span className="badge red dot" style={{ marginRight: 4 }}>{expired} expired</span>}
                      {soon > 0 && <span className="badge amber dot" style={{ marginRight: 4 }}>{soon} expiring</span>}
                      {expired === 0 && soon === 0 && <span className="badge green dot">All good</span>}
                    </td>
                    <td>
                      <div className="row-actions">
                        <button className="btn sm" onClick={(e) => { e.stopPropagation(); onSelectClient(c.id); }}>
                          Open <Icon name="chevron" size={11}/>
                        </button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      {editing && (
        <ClientForm
          mode={editing.mode}
          initial={editing.entity}
          onClose={() => setEditing(null)}
          onSave={async (form) => {
            try {
              if (editing.mode === 'create') {
                await onAddClient(form);
              } else {
                await onEditClient(editing.entity.id, form);
              }
              setEditing(null);
            } catch (err) {
              alert(err.message || 'Save failed');
            }
          }}
        />
      )}

      {showDeleteConfirm && (
        <Modal
          title={`Delete ${selected.size} client${selected.size === 1 ? '' : 's'}?`}
          sub={`This will also delete all domains and servers associated with these clients.`}
          onClose={() => setShowDeleteConfirm(false)}
          footer={
            <>
              <button className="btn" onClick={() => setShowDeleteConfirm(false)}>Cancel</button>
              <button className="btn danger" onClick={async () => {
                try {
                  await onDeleteClient([...selected]);
                  setSelected(new Set());
                  setShowDeleteConfirm(false);
                } catch (err) {
                  alert(err.message || 'Delete failed');
                  setShowDeleteConfirm(false);
                }
              }}>
                <Icon name="trash" size={13}/> Delete permanently
              </button>
            </>
          }
        >
          <p style={{ margin: 0, fontSize: 13, color: 'var(--text-secondary)', lineHeight: 1.5 }}>
            This action cannot be undone. {selected.size} client{selected.size === 1 ? '' : 's'} and all their domains and servers will be permanently deleted.
          </p>
        </Modal>
      )}
    </>
  );
};

// ── Client detail ────────────────────────────────────────────
const ClientDetailScreen = ({ client, domains, servers, clients, approvals, role, onBack, onEdit, onView, onRenew, onAdd, onEditClient, onDeleteClient }) => {
  const [sort, setSort] = React.useState({ field: 'expiryStatus', dir: 'asc' });
  const [statusFilter, setStatusFilter] = React.useState('all');
  const [editingClient, setEditingClient] = React.useState(null);
  const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);
  const onSort = (field) => {
    setSort(prev => prev.field === field ? { field, dir: prev.dir === 'asc' ? 'desc' : 'asc' } : { field, dir: 'asc' });
  };

  const domainRows = domains
    .filter(d => d.clientId === client.id)
    .map(d => {
      const pending = approvals.find(a => a.kind === 'edit' && a.entity === 'domain' && a.entityId === d.id);
      return { entity: d, pending, effective: { ...d, ...(pending?.changes || {}) } };
    })
    .filter(r => {
      if (statusFilter === 'all') return true;
      const tone = window.expiryStatus(r.effective.expiry).tone;
      return tone === { expired: 'red', soon: 'amber', active: 'green' }[statusFilter];
    });
  const serverRows = servers
    .filter(s => s.clientId === client.id)
    .map(s => {
      const pending = approvals.find(a => a.kind === 'edit' && a.entity === 'server' && a.entityId === s.id);
      return { entity: s, pending, effective: { ...s, ...(pending?.changes || {}) } };
    })
    .filter(r => {
      if (statusFilter === 'all') return true;
      const tone = window.expiryStatus(r.effective.expiry).tone;
      return tone === { expired: 'red', soon: 'amber', active: 'green' }[statusFilter];
    });

  const sortKey = (e) => {
    if (sort.field === 'expiryStatus') {
      const s = window.expiryStatus(e.expiry);
      return [s.sort, s.n];
    }
    return [e[sort.field]];
  };
  const sortRows = (arr) => [...arr].sort((A, B) => {
    const a = sortKey(A.effective), b = sortKey(B.effective);
    for (let i = 0; i < a.length; i++) {
      if (a[i] !== b[i]) return ((typeof a[i] === 'number' ? a[i] - b[i] : String(a[i] || '').localeCompare(String(b[i] || '')))) * (sort.dir === 'asc' ? 1 : -1);
    }
    return 0;
  });

  const sortedDomains = sortRows(domainRows);
  const sortedServers = sortRows(serverRows);

  const all = [...domains.filter(d => d.clientId === client.id), ...servers.filter(s => s.clientId === client.id)];
  const expired = all.filter(x => window.daysUntil(x.expiry) < 0).length;
  const soon = all.filter(x => { const n = window.daysUntil(x.expiry); return n >= 0 && n <= 30; }).length;
  const pendingCount = approvals.filter(a => {
    if (a.kind === 'edit') {
      const e = a.entity === 'domain' ? domains.find(d => d.id === a.entityId) : servers.find(s => s.id === a.entityId);
      return e?.clientId === client.id;
    }
    return a.payload?.clientId === client.id;
  }).length;

  return (
    <>
      <div style={{ marginBottom: 14 }}>
        <button className="btn sm ghost" onClick={onBack}>
          <Icon name="chevron" size={12} style={{ transform: 'rotate(180deg)' }}/> Back to all clients
        </button>
      </div>

      <div className="page-head">
        <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
          <Avatar name={client.name} size={56} />
          <div>
            <h1>{client.name}</h1>
            <div className="sub">
              <span className="mono">{client.contact}</span> · {client.phone}
            </div>
          </div>
        </div>
        <div className="page-actions">
          <StyledSelect
            value={statusFilter}
            onChange={setStatusFilter}
            options={[
              { value: 'all',     label: 'All statuses', icon: 'archive' },
              { value: 'expired', label: 'Expired',      swatch: '#dc2626' },
              { value: 'soon',    label: 'Expiring ≤ 30 days', swatch: '#d97706' },
              { value: 'active',  label: 'Active',       swatch: '#16a34a' },
            ]}
            icon="filter"
            leadingTone="brand"
          />
          {role === 'admin' && (
            <>
              <button className="btn" onClick={() => setEditingClient(client)}><Icon name="edit" size={13}/> Edit client</button>
              <button className="btn" onClick={() => setShowDeleteConfirm(true)}><Icon name="trash" size={13}/> Delete client</button>
            </>
          )}
        </div>
      </div>

      <div className="stats" style={{ marginBottom: 18 }}>
        <div className="stat">
          <div className="stat-label"><span className="stat-icon"><Icon name="globe" size={13}/></span>Domains</div>
          <div className="stat-value">{domains.filter(d => d.clientId === client.id).length}</div>
          <div className="stat-trend">Registered to this client</div>
        </div>
        <div className="stat">
          <div className="stat-label"><span className="stat-icon blue"><Icon name="server" size={13}/></span>Servers</div>
          <div className="stat-value">{servers.filter(s => s.clientId === client.id).length}</div>
          <div className="stat-trend">VPS / dedicated</div>
        </div>
        <div className="stat">
          <div className="stat-label"><span className="stat-icon red"><Icon name="alert" size={13}/></span>Expired</div>
          <div className="stat-value">{expired}</div>
          <div className="stat-trend">{soon} more expiring ≤ 30d</div>
        </div>
        <div className="stat">
          <div className="stat-label"><span className="stat-icon amber"><Icon name="pending" size={13}/></span>Pending edits</div>
          <div className="stat-value">{pendingCount}</div>
          <div className="stat-trend">Awaiting admin approval</div>
        </div>
      </div>

      {sortedDomains.length > 0 && (
        <div className="subgroup" style={{ marginBottom: 18 }}>
          <div className="subgroup-head">
            <Icon name="globe" size={12} stroke={2}/> Domains · {sortedDomains.length}
            <div style={{ flex: 1 }}></div>
            <button className="btn sm" onClick={() => onAdd('domain')}>
              <Icon name="plus" size={11}/> Add domain
            </button>
          </div>
          <div className="table-wrap">
            <DomainsTable rows={sortedDomains} clients={clients} servers={servers} role={role} sort={sort} onSort={onSort}
              onEdit={onEdit} onView={onView} onRenew={onRenew} showClient={false} />
          </div>
        </div>
      )}

      {sortedServers.length > 0 && (
        <div className="subgroup" style={{ marginBottom: 18 }}>
          <div className="subgroup-head">
            <Icon name="server" size={12} stroke={2}/> Servers · {sortedServers.length}
            <div style={{ flex: 1 }}></div>
            <button className="btn sm" onClick={() => onAdd('server')}>
              <Icon name="plus" size={11}/> Add server
            </button>
          </div>
          <div className="table-wrap">
            <ServersTable rows={sortedServers} clients={clients} role={role} sort={sort} onSort={onSort}
              onEdit={onEdit} onView={onView} onRenew={onRenew} showClient={false} />
          </div>
        </div>
      )}

      {sortedDomains.length === 0 && sortedServers.length === 0 && (
        <Empty title="Nothing here yet" body={`No domains or servers match the filter for ${client.name}.`} />
      )}

      {editingClient && (
        <ClientForm
          mode="edit"
          initial={editingClient}
          onClose={() => setEditingClient(null)}
          onSave={async (form) => {
            try {
              await onEditClient(editingClient.id, form);
              setEditingClient(null);
            } catch (err) {
              alert(err.message || 'Save failed');
            }
          }}
        />
      )}

      {showDeleteConfirm && (
        <Modal
          title={`Delete ${client.name}?`}
          sub={`This will also delete ${domains.filter(d => d.clientId === client.id).length} domain(s) and ${servers.filter(s => s.clientId === client.id).length} server(s) associated with this client.`}
          onClose={() => setShowDeleteConfirm(false)}
          footer={
            <>
              <button className="btn" onClick={() => setShowDeleteConfirm(false)}>Cancel</button>
              <button className="btn danger" onClick={async () => {
                try {
                  await onDeleteClient(client.id);
                  setShowDeleteConfirm(false);
                  onBack();
                } catch (err) {
                  alert(err.message || 'Delete failed');
                  setShowDeleteConfirm(false);
                }
              }}>
                <Icon name="trash" size={13}/> Delete permanently
              </button>
            </>
          }
        >
          <p style={{ margin: 0, fontSize: 13, color: 'var(--text-secondary)', lineHeight: 1.5 }}>
            This action cannot be undone. All domains and servers belonging to {client.name} will be permanently deleted.
          </p>
        </Modal>
      )}
    </>
  );
};

window.ClientsScreen = ClientsScreen;
window.ClientDetailScreen = ClientDetailScreen;
