import { useCallback, useEffect, useState } from 'react'
import { Loading, ErrorState } from '../../../components/PageState.jsx'
import { dateTime } from '../../../lib/format.js'
import { api } from '../../../api/client.js'

// Admin email invites: send an invite at a chosen access level, see recent
// invites and their status, revoke pending ones. When email delivery isn't
// configured the create response hands back the accept link to copy manually.

const ROLES = ['player', 'moderator', 'editor', 'admin']
const ROLE_BADGE = { admin: 'badge-admin', editor: 'badge-editor', moderator: 'badge-moderator', player: 'badge-player' }
const STATUS_COLOR = { pending: 'var(--accent)', accepted: '#7fd0a4', revoked: 'var(--muted)' }

function CopyLink({ url }) {
  const [copied, setCopied] = useState(false)
  async function copy() {
    try {
      await navigator.clipboard.writeText(url)
      setCopied(true)
      setTimeout(() => setCopied(false), 1800)
    } catch {
      /* clipboard blocked — the link is selectable in the box regardless */
    }
  }
  return (
    <div style={{ display: 'flex', gap: 8, alignItems: 'stretch' }}>
      <code
        onClick={(e) => { const r = document.createRange(); r.selectNodeContents(e.currentTarget); const s = window.getSelection(); s.removeAllRanges(); s.addRange(r) }}
        style={{ flex: 1, wordBreak: 'break-all', color: 'var(--head)', background: 'var(--panel-flat)', padding: '8px 10px', borderRadius: 6, border: '1px solid var(--line)', cursor: 'text', fontSize: '0.8rem' }}
      >
        {url}
      </code>
      <button type="button" onClick={copy} className="btn btn-sq" style={{ flex: 'none' }}>
        {copied ? 'Copied ✓' : 'Copy'}
      </button>
    </div>
  )
}

function CreateInvite({ onCreated }) {
  const [email, setEmail] = useState('')
  const [role, setRole] = useState('player')
  const [sendEmail, setSendEmail] = useState(true)
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState('')
  const [result, setResult] = useState(null) // fields emailed, acceptUrl, emailError

  async function submit(e) {
    e.preventDefault()
    setError(''); setResult(null)
    if (!email.trim()) return setError('Enter an email address.')
    setBusy(true)
    try {
      const res = await api.admin.createInvite(email.trim(), role, sendEmail)
      setResult(res)
      setEmail('')
      await onCreated()
    } catch (err) {
      setError(err.message || 'Could not create the invite.')
    } finally {
      setBusy(false)
    }
  }

  const submitLabel = sendEmail ? 'Create & email' : 'Create link'

  let resultText
  if (result?.emailed) {
    resultText = 'Invitation emailed. You can also share this single-use link:'
  } else {
    const emailNote = result?.emailError ? ` (email not sent: ${result.emailError})` : ''
    resultText = `Invite created${emailNote}. Share this single-use link:`
  }

  return (
    <div className="panel" style={{ padding: 22, marginBottom: 22 }}>
      <div className="field-label" style={{ marginBottom: 10 }}>Invite someone</div>
      <form onSubmit={submit} style={{ display: 'flex', gap: 12, alignItems: 'flex-end', flexWrap: 'wrap' }}>
        <label style={{ flex: '1 1 240px' }}>
          <span className="field-label">Email</span>
          <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} className="input" placeholder="person@example.com" />
        </label>
        <label>
          <span className="field-label">Access level</span>
          <select value={role} onChange={(e) => setRole(e.target.value)} className="select">
            {ROLES.map((r) => <option key={r} value={r}>{r}</option>)}
          </select>
        </label>
        <button type="submit" disabled={busy} className="btn btn-primary btn-sq">
          {busy ? 'Creating…' : submitLabel}
        </button>
      </form>

      <label className="sans" style={{ display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 12, fontSize: '0.85rem', color: 'var(--ink)', cursor: 'pointer' }}>
        <input type="checkbox" checked={sendEmail} onChange={(e) => setSendEmail(e.target.checked)} />
        Email the invitation (otherwise just generate a link to share)
      </label>

      {error && <p className="sans" style={{ margin: '12px 0 0', color: '#d98b84', fontSize: '0.85rem' }}>{error}</p>}
      {result && (
        <div style={{ marginTop: 14 }}>
          <p className="sans" style={{ margin: '0 0 8px', fontSize: '0.84rem', color: result.emailed ? '#7fd0a4' : 'var(--muted)' }}>
            {resultText}
          </p>
          <CopyLink url={result.acceptUrl} />
        </div>
      )}
    </div>
  )
}

export default function InvitesAdmin() {
  const [invites, setInvites] = useState(null)
  const [error, setError] = useState('')

  const load = useCallback(async () => {
    setError('')
    try {
      setInvites(await api.admin.listInvites())
    } catch {
      setError('Could not load invites.')
    }
  }, [])
  useEffect(() => { load() }, [load])

  async function revoke(id) {
    if (!window.confirm('Revoke this pending invitation?')) return
    try {
      await api.admin.revokeInvite(id)
      await load()
    } catch {
      /* surfaced by the row staying; keep it simple */
    }
  }

  if (error) return <ErrorState message={error} />

  return (
    <section>
      <CreateInvite onCreated={load} />

      {!invites ? (
        <Loading />
      ) : (
        <div className="panel-flat">
          <table className="adm-table">
            <thead>
              <tr>
                <th className="adm-th">Email</th>
                <th className="adm-th">Role</th>
                <th className="adm-th">Status</th>
                <th className="adm-th">Expires</th>
                <th className="adm-th">Created</th>
                <th className="adm-th" />
              </tr>
            </thead>
            <tbody>
              {invites.length === 0 && (
                <tr><td className="adm-td" colSpan={6} style={{ color: 'var(--muted)' }}>No invites yet.</td></tr>
              )}
              {invites.map((iv) => {
                const status = iv.status === 'pending' && iv.expired ? 'expired' : iv.status
                return (
                  <tr key={iv.id}>
                    <td className="adm-td" style={{ color: 'var(--text)' }}>{iv.email}</td>
                    <td className="adm-td"><span className={`badge ${ROLE_BADGE[iv.role] || 'badge-editor'}`}>{iv.role}</span></td>
                    <td className="adm-td" style={{ color: STATUS_COLOR[iv.status] || 'var(--muted)', textTransform: 'capitalize' }}>{status}</td>
                    <td className="adm-td dim">{dateTime(iv.expiresAt)}</td>
                    <td className="adm-td dim">{dateTime(iv.createdAt)}</td>
                    <td className="adm-td" style={{ textAlign: 'right' }}>
                      {iv.status === 'pending' && (
                        <button type="button" className="pill" style={{ fontSize: '0.72rem', color: '#d98b84', borderColor: '#5b2020' }} onClick={() => revoke(iv.id)}>
                          Revoke
                        </button>
                      )}
                    </td>
                  </tr>
                )
              })}
            </tbody>
          </table>
        </div>
      )}
    </section>
  )
}
