// ════════════════════════════════════════════════════════════════
// /admin/invites — отдельная страница для управления приглашениями
// ════════════════════════════════════════════════════════════════

function InvitesPanel({ currentUser, onRoute }) {
  const A = window.SDH_ADMIN;
  const [openCreate, setOpenCreate] = React.useState(false);
  const [createdInvite, setCreatedInvite] = React.useState(null);
  const [shareInvite, setShareInvite] = React.useState(null);

  const pending = A.invites.filter(i => i.status === 'pending');
  const accepted = A.invites.filter(i => i.status === 'accepted');
  const archived = A.invites.filter(i => i.status === 'expired' || i.status === 'revoked');

  return (
    <div className="sdh-fade">
      <PageHeader
        section="управление"
        title="Приглашения и доступ"
        accent="приглашения"
        subtitle="Письма не уходят автоматически. Создаёте ссылку, копируете, передаёте получателю через свой канал. Срок действия ссылки 7 дней."
        right={
          <div style={{ display: 'flex', gap: 8 }}>
            <button className="sdh-btn" onClick={() => onRoute('admin.users')}>К пользователям</button>
            <button className="sdh-btn sdh-btn--bronze" onClick={() => setOpenCreate(true)}>
              <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5">
                <path d="M6 2v8M2 6h8" strokeLinecap="round" />
              </svg>
              Создать приглашение
            </button>
          </div>
        }
      />

      <section className="sdh-container" style={{ paddingBottom: 'var(--space-16)' }}>
        {/* Pending */}
        <Bucket title="в ожидании" count={pending.length} hue="amber"
          subtitle="Партнёр ещё не открыл ссылку. Можно переслать ещё раз или отозвать."
          help={{
            title: 'Pending приглашения',
            what: 'Созданные, но не принятые ссылки. Имеют срок 7 дней с момента создания.',
            why: 'Если pending больше недели — спросите получателя, открыл ли он ссылку. Если не открыл — отзовите и создайте новую. Старые ссылки накапливаются и засоряют картину.',
          }}>
          {pending.length === 0
            ? <EmptyState title="Нет ожидающих" hint="Все приглашения приняты или отозваны." />
            : pending.map(inv => (
              <InviteRow key={inv.id} invite={inv} onShare={() => setShareInvite(inv)} />
            ))}
        </Bucket>

        <div style={{ height: 'var(--space-8)' }} />

        {/* Accepted */}
        <Bucket title="принятые" count={accepted.length} hue="emerald"
          subtitle="Партнёр прошёл регистрацию, учётная запись активна.">
          {accepted.length === 0
            ? <EmptyState title="Никого пока" hint="Когда кто-то примет приглашение, он появится здесь." />
            : accepted.map(inv => <InviteRow key={inv.id} invite={inv} archived />)}
        </Bucket>

        <div style={{ height: 'var(--space-8)' }} />

        {/* Archived */}
        <Bucket title="истёкшие и отозванные" count={archived.length} hue="info"
          subtitle="Историческая лента. Можно создать новое приглашение тем же адресатам.">
          {archived.length === 0
            ? <EmptyState title="Пусто" hint="" />
            : archived.map(inv => <InviteRow key={inv.id} invite={inv} archived />)}
        </Bucket>
      </section>

      {openCreate && (
        <InviteModal currentUser={currentUser}
          onClose={() => setOpenCreate(false)}
          onCreated={(inv) => { setOpenCreate(false); setCreatedInvite(inv); }} />
      )}
      {createdInvite && <InviteCreatedModal invite={createdInvite} onClose={() => setCreatedInvite(null)} />}
      {shareInvite && <InviteCreatedModal invite={{ ...shareInvite, url: `https://analytics.simbiosislab.online/invite/${shareInvite.token}` }} onClose={() => setShareInvite(null)} />}
    </div>
  );
}

function Bucket({ title, count, hue, subtitle, help, children }) {
  return (
    <div>
      <div style={{
        display: 'flex', alignItems: 'baseline', gap: 'var(--space-3)',
        padding: '0 0 var(--space-4)',
        borderBottom: `1px solid var(--hue-${hue})`,
        marginBottom: 'var(--space-4)',
      }}>
        <span style={{
          fontFamily: 'var(--font-mono)', fontSize: 12, fontWeight: 600,
          color: `var(--hue-${hue})`, letterSpacing: '0.06em',
        }}>{title.toUpperCase()}</span>
        <span style={{
          fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-tertiary)',
        }}>{count}</span>
        <span style={{ flex: 1, height: 1 }} />
        {help && <span className="sdh-mono-label" style={{ marginBottom: 0 }}>
          <InfoLabel {...help}>что это</InfoLabel>
        </span>}
      </div>
      {subtitle && (
        <p className="sdh-quote" style={{ margin: '0 0 var(--space-4)', fontSize: 13 }}>
          {subtitle}
        </p>
      )}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {children}
      </div>
    </div>
  );
}

function InviteRow({ invite, archived, onShare }) {
  const sentDate = invite.sent_at ? new Date(invite.sent_at) : null;
  const daysAgo = sentDate ? Math.round((new Date('2026-05-23T10:00:00Z') - sentDate) / 86400000) : null;
  const [busy, setBusy] = React.useState(null);  // 'resend' | 'revoke' | null

  async function handleResend() {
    if (!invite.id || invite.id === 'inv_new') return;
    setBusy('resend');
    if (window.SDH_USE_API && window.SDH_API) {
      try {
        await window.SDH_API.post(`/api/admin/invites/${invite.id}/resend`);
        alert('Приглашение поставлено в очередь (email отключён, ссылка остаётся в админке).');
      } catch (e) {
        alert('Ошибка: ' + ((e && e.message) || e));
      }
    } else {
      alert('Mock: resend OK');
    }
    setBusy(null);
  }
  async function handleRevoke() {
    if (!invite.id || invite.id === 'inv_new') return;
    if (!confirm(`Отозвать приглашение для ${invite.email}?`)) return;
    setBusy('revoke');
    if (window.SDH_USE_API && window.SDH_API) {
      try {
        await window.SDH_API.del(`/api/admin/invites/${invite.id}`);
        if (window.SDH_HYDRATE && window.SDH_HYDRATE.refreshInvites) {
          await window.SDH_HYDRATE.refreshInvites();
        }
      } catch (e) {
        alert('Ошибка: ' + ((e && e.message) || e));
        setBusy(null);
        return;
      }
    } else {
      // Mock: update in-memory
      if (window.SDH_ADMIN && Array.isArray(window.SDH_ADMIN.invites)) {
        const inv = window.SDH_ADMIN.invites.find(i => i.id === invite.id);
        if (inv) inv.status = 'revoked';
      }
    }
    setBusy(null);
  }

  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: '24px 1fr 120px 130px 1fr',
      gap: 12, alignItems: 'center',
      padding: '12px 16px',
      background: 'var(--surface-elevated)',
      border: '1px solid var(--border-subtle)',
      borderRadius: 'var(--radius-md)',
    }}>
      <StatusDot status={invite.status} label="" />
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 500, color: 'var(--text-primary)' }}>{invite.email}</div>
        {invite.note && <div style={{ fontSize: 11.5, color: 'var(--text-tertiary)', fontStyle: 'italic', marginTop: 2 }}>{invite.note}</div>}
      </div>
      <RoleBadge role={invite.role} size="sm" />
      <span style={{ fontSize: 12, color: 'var(--text-tertiary)' }}>
        {invite.status === 'accepted'
          ? `принято ${daysAgo} д назад`
          : invite.status === 'expired'
            ? `истекло ${daysAgo} д назад`
            : invite.status === 'revoked'
              ? `отозвано ${daysAgo} д назад`
              : `отправлено ${daysAgo} д назад`}
      </span>
      <div style={{ display: 'flex', gap: 4, justifyContent: 'flex-end' }}>
        {invite.status === 'pending' && (
          <React.Fragment>
            <button className="sdh-btn sdh-btn--bronze" style={{ fontSize: 11, padding: '4px 10px' }} onClick={onShare}>
              Скопировать ссылку
            </button>
            <button className="sdh-btn sdh-btn--ghost" style={{ fontSize: 11, padding: '4px 8px' }}
                    disabled={busy === 'resend'} onClick={handleResend}>
              {busy === 'resend' ? '...' : 'повторить'}
            </button>
            <button className="sdh-btn sdh-btn--ghost" style={{ fontSize: 11, padding: '4px 8px', color: 'var(--hue-rose)' }}
                    disabled={busy === 'revoke'} onClick={handleRevoke}>
              {busy === 'revoke' ? '...' : 'отозвать'}
            </button>
          </React.Fragment>
        )}
        {invite.status === 'accepted' && (
          <button className="sdh-btn sdh-btn--ghost" style={{ fontSize: 11, padding: '4px 8px' }}>в профиль</button>
        )}
        {archived && invite.status !== 'accepted' && (
          <button className="sdh-btn sdh-btn--ghost" style={{ fontSize: 11, padding: '4px 8px' }}>пригласить снова</button>
        )}
      </div>
    </div>
  );
}

window.InvitesPanel = InvitesPanel;
