import { useEffect, useState } from 'react'
import { useI18n } from '../i18n'
import { localizeError } from '../utils/errors'
import { Button, Field, Callout, Spinner } from '../components/ui'
import { ConfirmDialog, statusLabel, roleLabel } from '../components/d2'
import { useD2Session } from '../hooks/useD2Session'
import {
  createInvitations, getOperatorAccount, listInvitations, listOperatorAccounts,
  operatorDeleteAccount, operatorPauseAccount, operatorReactivateAccount, operatorRecoveryInvitation,
  revokeInvitation,
  type D2AccountEvent, type D2Invitation, type D2OperatorAccount,
} from '../api/identity'

type Msg = { tone: 'ok' | 'bad' | 'info'; text: string } | null
type Tab = 'invite' | 'accounts'
type ActionKind = 'pause' | 'reactivate' | 'delete' | 'recovery'

async function copy(text: string): Promise<void> {
  try {
    await navigator.clipboard?.writeText(text)
  } catch {
    /* clipboard unavailable — user can select manually */
  }
}

export function D2OperatorPage({ onNav }: { onNav: (r: string) => void }) {
  const { t } = useI18n()
  const { isOperator } = useD2Session()
  const [tab, setTab] = useState<Tab>('invite')
  const [busy, setBusy] = useState(false)
  const [msg, setMsg] = useState<Msg>(null)

  // Invitations
  const [role, setRole] = useState('customer')
  const [count, setCount] = useState('1')
  const [ttlHours, setTtlHours] = useState('24')
  const [newCodes, setNewCodes] = useState<{ id: string; code: string }[] | null>(null)
  const [invitations, setInvitations] = useState<D2Invitation[] | null>(null)

  // Accounts
  const [accounts, setAccounts] = useState<D2OperatorAccount[] | null>(null)
  const [detail, setDetail] = useState<{ account: D2OperatorAccount; events: D2AccountEvent[] } | null>(null)
  const [recoveryCode, setRecoveryCode] = useState<string | null>(null)
  const [confirm, setConfirm] = useState<{ kind: ActionKind; id: string } | null>(null)

  async function loadInvitations() {
    try { setInvitations(await listInvitations()) }
    catch (e) { setMsg({ tone: 'bad', text: localizeError(e, t, 'd2.operator.error') }) }
  }
  async function loadAccounts() {
    try { setAccounts(await listOperatorAccounts()) }
    catch (e) { setMsg({ tone: 'bad', text: localizeError(e, t, 'd2.operator.error') }) }
  }

  useEffect(() => {
    if (!isOperator) return
    if (tab === 'invite') void loadInvitations()
    else void loadAccounts()
  }, [tab, isOperator]) // eslint-disable-line react-hooks/exhaustive-deps

  if (!isOperator) {
    return (
      <section className="card" aria-labelledby="d2op-h">
        <h2 id="d2op-h">{t('d2.operator.title')}</h2>
        <Callout tone="warn">{t('d2.operator.onlyOperator')}</Callout>
        <Button onClick={() => onNav('id/account')}>{t('d2.back')}</Button>
      </section>
    )
  }

  async function onCreate() {
    setBusy(true); setMsg(null)
    try {
      const n = Math.max(1, Number(count) || 1)
      const ttl = Math.max(1, Number(ttlHours) || 1) * 3600
      const codes = await createInvitations(role, n, ttl)
      setNewCodes(codes)
      await loadInvitations()
    } catch (e) {
      setMsg({ tone: 'bad', text: localizeError(e, t, 'd2.operator.error') })
    } finally {
      setBusy(false)
    }
  }

  async function onRevokeInvite(id: string) {
    setBusy(true); setMsg(null); setConfirm(null)
    try {
      await revokeInvitation(id)
      await loadInvitations()
    } catch (e) {
      setMsg({ tone: 'bad', text: localizeError(e, t, 'd2.operator.error') })
    } finally {
      setBusy(false)
    }
  }

  async function openDetail(id: string) {
    setBusy(true); setMsg(null); setRecoveryCode(null)
    try {
      setDetail(await getOperatorAccount(id))
    } catch (e) {
      setMsg({ tone: 'bad', text: localizeError(e, t, 'd2.operator.error') })
    } finally {
      setBusy(false)
    }
  }

  async function runAction(kind: ActionKind, id: string) {
    setBusy(true); setMsg(null); setConfirm(null)
    try {
      if (kind === 'pause') await operatorPauseAccount(id)
      else if (kind === 'reactivate') await operatorReactivateAccount(id)
      else if (kind === 'delete') await operatorDeleteAccount(id)
      else if (kind === 'recovery') { setRecoveryCode(await operatorRecoveryInvitation(id)) }
      setMsg({ tone: 'ok', text: t('d2.operator.done') })
      if (kind === 'delete') { setDetail(null); await loadAccounts() }
      else await openDetail(id)
    } catch (e) {
      setMsg({ tone: 'bad', text: localizeError(e, t, 'd2.operator.error') })
    } finally {
      setBusy(false)
    }
  }

  const confirmMsgKey: Record<ActionKind, 'd2.operator.pauseConfirm' | 'd2.operator.reactivateConfirm'
    | 'd2.operator.deleteConfirm' | 'd2.operator.recoveryConfirm'> = {
    pause: 'd2.operator.pauseConfirm', reactivate: 'd2.operator.reactivateConfirm',
    delete: 'd2.operator.deleteConfirm', recovery: 'd2.operator.recoveryConfirm',
  }

  return (
    <section className="card" aria-labelledby="d2op-h">
      <h2 id="d2op-h">{t('d2.operator.title')}</h2>

      <div className="tabs" role="tablist" aria-label={t('d2.operator.title')}>
        <button role="tab" aria-selected={tab === 'invite'} className={`tab ${tab === 'invite' ? 'active' : ''}`}
                onClick={() => { setDetail(null); setTab('invite') }}>{t('d2.operator.tab.invite')}</button>
        <button role="tab" aria-selected={tab === 'accounts'} className={`tab ${tab === 'accounts' ? 'active' : ''}`}
                onClick={() => { setDetail(null); setTab('accounts') }}>{t('d2.operator.tab.accounts')}</button>
      </div>

      {tab === 'invite' && (
        <>
          <fieldset className="action-group">
            <legend>{t('d2.operator.newInvite')}</legend>
            <div className="field">
              <label htmlFor="op_role">{t('d2.operator.inviteRole')}</label>
              <select id="op_role" className="d2-select" value={role} onChange={(e) => setRole(e.target.value)}>
                <option value="customer">{t('d2.role.customer')}</option>
                <option value="operator">{t('d2.role.operator')}</option>
              </select>
            </div>
            <Field id="op_count" label={t('d2.operator.inviteCount')} type="number" min={1} value={count}
                   onChange={(e) => setCount(e.target.value)} />
            <Field id="op_ttl" label={t('d2.operator.inviteTtl')} type="number" min={1} value={ttlHours}
                   onChange={(e) => setTtlHours(e.target.value)} />
            <Button onClick={onCreate} disabled={busy}>
              {busy ? <Spinner label={t('d2.working')} /> : t('d2.operator.create')}
            </Button>
          </fieldset>

          {newCodes && (
            <div className="action-group" role="region" aria-label={t('d2.operator.codesTitle')}>
              <strong>{t('d2.operator.codesTitle')}</strong>
              <Callout tone="warn">{t('d2.operator.codesWarn')}</Callout>
              <ul className="d2-list">
                {newCodes.map((c) => (
                  <li key={c.id} className="d2-item">
                    <code className="mono">{c.code}</code>
                    <Button onClick={() => copy(c.code)}>{t('d2.copy')}</Button>
                  </li>
                ))}
              </ul>
              <Button onClick={() => copy(newCodes.map((c) => c.code).join('\n'))}>{t('d2.copyAll')}</Button>
            </div>
          )}

          <h3>{t('d2.operator.inviteList')}</h3>
          {invitations === null ? (
            <Spinner label={t('d2.loading')} />
          ) : invitations.length === 0 ? (
            <p className="muted empty-state">{t('d2.operator.inviteEmpty')}</p>
          ) : (
            <ul className="d2-list">
              {invitations.map((inv) => (
                <li key={inv.id} className="d2-item">
                  <div className="d2-item-main">
                    <strong>{roleLabel(t, inv.role)}</strong>
                    <div className="d2-meta">
                      <span>{t('d2.operator.inviteUses')}: {inv.use_count}/{inv.max_uses}</span>
                      <span>{t('d2.operator.inviteExpires')}: {inv.expires_at}</span>
                      {inv.revoked && <span className="badge tone-bad">{t('d2.operator.inviteRevoked')}</span>}
                      {inv.claimed && <span className="badge tone-info">{t('d2.operator.inviteClaimed')}</span>}
                    </div>
                  </div>
                  {!inv.revoked && (
                    <div className="d2-item-actions">
                      <Button className="btn danger" onClick={() => setConfirm({ kind: 'pause', id: `inv:${inv.id}` })}
                              disabled={busy}>{t('d2.operator.inviteRevoke')}</Button>
                    </div>
                  )}
                </li>
              ))}
            </ul>
          )}
        </>
      )}

      {tab === 'accounts' && !detail && (
        <>
          <h3>{t('d2.operator.accountList')}</h3>
          {accounts === null ? (
            <Spinner label={t('d2.loading')} />
          ) : accounts.length === 0 ? (
            <p className="muted empty-state">{t('d2.operator.accountEmpty')}</p>
          ) : (
            <ul className="d2-list">
              {accounts.map((a) => (
                <li key={a.id} className="d2-item">
                  <div className="d2-item-main">
                    <strong>{a.display_alias}</strong>
                    <div className="d2-meta">
                      <span>{t('d2.operator.colHandle')}: {a.public_handle}</span>
                      <span>{t('d2.operator.colRole')}: {roleLabel(t, a.role)}</span>
                      <span>{t('d2.operator.colStatus')}: {statusLabel(t, a.status)}</span>
                      <span>{t('d2.operator.colPasskeys')}: {a.passkey_count}</span>
                      <span>{t('d2.operator.colSessions')}: {a.active_session_count}</span>
                    </div>
                  </div>
                  <div className="d2-item-actions">
                    <Button onClick={() => openDetail(a.id)} disabled={busy}>{t('d2.operator.view')}</Button>
                  </div>
                </li>
              ))}
            </ul>
          )}
        </>
      )}

      {tab === 'accounts' && detail && (
        <>
          <Button onClick={() => { setDetail(null); setRecoveryCode(null) }}>{t('d2.operator.backToList')}</Button>
          <h3>{t('d2.operator.detailTitle')}</h3>
          <dl className="summary-grid">
            <dt>{t('d2.operator.colHandle')}</dt><dd>{detail.account.public_handle}</dd>
            <dt>{t('d2.operator.colAlias')}</dt><dd>{detail.account.display_alias}</dd>
            <dt>{t('d2.operator.colRole')}</dt><dd>{roleLabel(t, detail.account.role)}</dd>
            <dt>{t('d2.operator.colStatus')}</dt><dd>{statusLabel(t, detail.account.status)}</dd>
            <dt>{t('d2.operator.colPasskeys')}</dt><dd>{detail.account.passkey_count}</dd>
            <dt>{t('d2.operator.colSessions')}</dt><dd>{detail.account.active_session_count}</dd>
          </dl>

          <div className="quick-actions">
            {detail.account.status === 'active' ? (
              <Button className="btn danger" onClick={() => setConfirm({ kind: 'pause', id: detail.account.id })}
                      disabled={busy}>{t('d2.operator.pause')}</Button>
            ) : (
              <Button onClick={() => setConfirm({ kind: 'reactivate', id: detail.account.id })}
                      disabled={busy}>{t('d2.operator.reactivate')}</Button>
            )}
            <Button onClick={() => setConfirm({ kind: 'recovery', id: detail.account.id })}
                    disabled={busy}>{t('d2.operator.recovery')}</Button>
            <Button className="btn danger" onClick={() => setConfirm({ kind: 'delete', id: detail.account.id })}
                    disabled={busy}>{t('d2.operator.delete')}</Button>
          </div>

          {recoveryCode && (
            <div className="action-group" role="region" aria-label={t('d2.operator.recoveryTitle')}>
              <strong>{t('d2.operator.recoveryTitle')}</strong>
              <Callout tone="warn">{t('d2.operator.recoveryWarn')}</Callout>
              <div className="row">
                <code className="mono">{recoveryCode}</code>
                <Button onClick={() => copy(recoveryCode)}>{t('d2.copy')}</Button>
              </div>
            </div>
          )}

          <h3>{t('d2.operator.events')}</h3>
          {detail.events.length === 0 ? (
            <p className="muted empty-state">{t('d2.operator.eventsEmpty')}</p>
          ) : (
            <ul className="d2-list">
              {detail.events.map((ev) => (
                <li key={ev.id} className="d2-item">
                  <div className="d2-item-main">
                    <strong>{ev.kind}</strong>
                    <div className="d2-meta">
                      <span>{ev.at}</span>
                      {ev.detail && <span>{ev.detail}</span>}
                    </div>
                  </div>
                </li>
              ))}
            </ul>
          )}
        </>
      )}

      <p aria-live="polite" className="sr-live">{busy ? t('d2.working') : ''}</p>
      {msg && <Callout tone={msg.tone}>{msg.text}</Callout>}

      {confirm && confirm.id.startsWith('inv:') && (
        <ConfirmDialog
          message={t('d2.operator.inviteRevokeConfirm')} confirmLabel={t('d2.operator.inviteRevoke')} busy={busy}
          onConfirm={() => onRevokeInvite(confirm.id.slice(4))} onCancel={() => setConfirm(null)}
        />
      )}
      {confirm && !confirm.id.startsWith('inv:') && (
        <ConfirmDialog
          message={t(confirmMsgKey[confirm.kind])}
          confirmLabel={t(`d2.operator.${confirm.kind}` as 'd2.operator.pause')}
          danger={confirm.kind === 'delete' || confirm.kind === 'pause'}
          busy={busy}
          onConfirm={() => runAction(confirm.kind, confirm.id)} onCancel={() => setConfirm(null)}
        />
      )}
    </section>
  )
}
