import { useCallback, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import Modal from '../../../components/Modal.jsx'
import { Loading, ErrorState } from '../../../components/PageState.jsx'
import { useAsync } from '../../../lib/useAsync.js'
import { ago, dateTime } from '../../../lib/format.js'
import { api } from '../../../api/client.js'

// Staff queue for moderation appeals (bans/mutes appealed by players). Mirrors
// the Moderation.jsx tile/feed layout: a status-filter segmented control over a
// flat table, with per-row Claim / Resolve actions. Resolve opens a modal — no
// browser confirm()/alert() anywhere here.

const STATUS_TABS = [
  { key: 'open', label: 'Open', param: undefined },
  { key: 'pending', label: 'Pending', param: 'pending' },
  { key: 'under_review', label: 'Under review', param: 'under_review' },
  { key: 'approved', label: 'Approved', param: 'approved' },
  { key: 'denied', label: 'Denied', param: 'denied' },
  { key: 'withdrawn', label: 'Withdrawn', param: 'withdrawn' },
  { key: 'all', label: 'All', param: 'all' },
]

const STATUS_STYLE = {
  pending: { color: '#e0b070', background: 'rgba(224,176,112,0.12)', border: '1px solid rgba(224,176,112,0.4)' },
  under_review: { color: '#7fa8d0', background: 'rgba(127,168,208,0.14)', border: '1px solid rgba(127,168,208,0.4)' },
  approved: { color: '#7fd0a4', background: 'rgba(95,185,138,0.16)', border: '1px solid rgba(95,185,138,0.4)' },
  denied: { color: '#d98b84', background: 'rgba(217,139,132,0.16)', border: '1px solid rgba(217,139,132,0.4)' },
  withdrawn: { color: '#9fb0c6', background: 'rgba(127,153,189,0.14)', border: '1px solid var(--line)' },
}
const STATUS_LABEL = {
  pending: 'Pending',
  under_review: 'Under review',
  approved: 'Approved',
  denied: 'Denied',
  withdrawn: 'Withdrawn',
}

function excerpt(text, n = 90) {
  if (!text) return ''
  return text.length > n ? `${text.slice(0, n)}…` : text
}

export default function Appeals() {
  const navigate = useNavigate()
  const [tab, setTab] = useState('open')
  const [tick, setTick] = useState(0)
  const reload = useCallback(() => setTick((t) => t + 1), [])
  const [busyId, setBusyId] = useState('')
  const [resolving, setResolving] = useState(null) // the appeal being resolved
  const [notice, setNotice] = useState(null) // fields text and tone

  const activeTab = STATUS_TABS.find((t) => t.key === tab) || STATUS_TABS[0]
  const { loading, error, data } = useAsync(
    () => api.admin.getAppeals({ status: activeTab.param, limit: 100 }),
    [tab, tick],
  )

  const goUser = (id) => navigate(`/admin/moderation/user/${id}`)

  async function claim(appeal) {
    setBusyId(appeal.id)
    setNotice(null)
    try {
      await api.admin.claimAppeal(appeal.id)
      reload()
    } catch (err) {
      setNotice({ text: err.message || 'Could not claim this appeal.', tone: 'error' })
    } finally {
      setBusyId('')
    }
  }

  function onResolved(appeal, result) {
    setResolving(null)
    const { reversal } = result
    if (reversal?.attempted && reversal.ok) {
      setNotice({ text: `Discord ${appeal.action_type} lifted.`, tone: 'ok' })
    } else if (reversal?.attempted && !reversal.ok) {
      setNotice({ text: 'Reversal failed — reverse manually in Discord.', tone: 'error' })
    } else {
      setNotice(null)
    }
    reload()
  }

  if (loading) return <Loading />
  if (error) return <ErrorState message="Could not load appeals." />

  const rows = data || []

  return (
    <section>
      {/* Status filter */}
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 16 }}>
        {STATUS_TABS.map((t) => (
          <button
            key={t.key}
            onClick={() => setTab(t.key)}
            className="pill"
            style={tab === t.key ? activePill : undefined}
          >
            {t.label}
          </button>
        ))}
      </div>

      {notice && (
        <p
          className="sans"
          style={{ margin: '0 0 14px', color: notice.tone === 'error' ? '#d98b84' : '#7fd0a4', fontSize: '0.85rem' }}
        >
          {notice.text}
        </p>
      )}

      <div className="panel-flat">
        <table className="adm-table">
          <thead>
            <tr>
              <th className="adm-th">Target</th>
              <th className="adm-th">Action</th>
              <th className="adm-th">Appeal</th>
              <th className="adm-th">Submitted by</th>
              <th className="adm-th">Age</th>
              <th className="adm-th">Status</th>
              <th className="adm-th">Reversal</th>
              <th className="adm-th" />
            </tr>
          </thead>
          <tbody>
            {rows.length === 0 && (
              <tr>
                <td className="adm-td" colSpan={8} style={muted}>
                  No appeals match this filter.
                </td>
              </tr>
            )}
            {rows.map((a) => (
              <tr key={a.id}>
                <td className="adm-td">
                  <span className="link-accent" onClick={() => goUser(a.discord_user_id)}>
                    {a.action_target_tag || a.discord_user_id}
                  </span>
                </td>
                <td className="adm-td">
                  <span className={`badge badge-${a.action_type}`}>{a.action_type}</span>
                </td>
                <td className="adm-td" style={{ color: 'var(--text)', maxWidth: 320 }}>
                  {excerpt(a.submitted_text)}
                </td>
                <td className="adm-td dim">{a.submitter_username || '—'}</td>
                <td className="adm-td dim" title={dateTime(a.submitted_at)}>{ago(a.submitted_at)}</td>
                <td className="adm-td">
                  <span className="badge" style={STATUS_STYLE[a.status]}>{STATUS_LABEL[a.status] || a.status}</span>
                </td>
                <td className="adm-td dim">
                  {a.reversal_status === 'done' && <span style={{ color: '#7fd0a4' }}>Lifted</span>}
                  {a.reversal_status === 'failed' && <span style={{ color: '#d98b84' }}>Failed</span>}
                  {(!a.reversal_status || a.reversal_status === 'none') && '—'}
                </td>
                <td className="adm-td" style={{ textAlign: 'right', whiteSpace: 'nowrap' }}>
                  {a.status === 'pending' && (
                    <button
                      onClick={() => claim(a)}
                      disabled={busyId === a.id}
                      className="pill"
                      style={{ marginRight: 6 }}
                    >
                      {busyId === a.id ? 'Claiming…' : 'Claim'}
                    </button>
                  )}
                  {(a.status === 'pending' || a.status === 'under_review') && (
                    <button onClick={() => setResolving(a)} className="btn btn-primary btn-sq" style={{ padding: '5px 12px', fontSize: '0.82rem' }}>
                      Resolve
                    </button>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {resolving && (
        <ResolveModal appeal={resolving} onClose={() => setResolving(null)} onResolved={onResolved} />
      )}
    </section>
  )
}

function ResolveModal({ appeal, onClose, onResolved }) {
  const [status, setStatus] = useState('approved')
  const [staffResponse, setStaffResponse] = useState('')
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState('')

  async function submit() {
    setBusy(true)
    setError('')
    try {
      const result = await api.admin.resolveAppeal(appeal.id, {
        status,
        staff_response: staffResponse.trim() || undefined,
      })
      onResolved(appeal, result)
    } catch (err) {
      setError(err.message || 'Could not resolve this appeal.')
      setBusy(false)
    }
  }

  const verb = status === 'approved' ? 'approved' : 'denied'

  return (
    <Modal
      title={`Resolve appeal — ${appeal.action_target_tag || appeal.discord_user_id}`}
      onClose={onClose}
      width={560}
      footer={
        <>
          <button onClick={onClose} disabled={busy} className="pill">
            Cancel
          </button>
          <button onClick={submit} disabled={busy} className="btn btn-primary btn-sq">
            {busy ? 'Saving…' : `Mark ${verb}`}
          </button>
        </>
      }
    >
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        {error && <p className="sans" style={{ margin: 0, color: '#d98b84', fontSize: '0.85rem' }}>{error}</p>}

        <div>
          <span className="field-label">Submitted appeal</span>
          <div
            className="sans"
            style={{
              marginTop: 6,
              padding: '10px 12px',
              border: '1px solid var(--line)',
              borderRadius: 8,
              color: 'var(--text)',
              fontSize: '0.86rem',
              whiteSpace: 'pre-wrap',
              maxHeight: 200,
              overflow: 'auto',
            }}
          >
            {appeal.submitted_text}
          </div>
        </div>

        <div style={{ display: 'flex', gap: 10 }}>
          <button
            onClick={() => setStatus('approved')}
            className="pill"
            style={status === 'approved' ? { background: 'var(--blue)', color: 'var(--ink)', borderColor: '#7fd0a4' } : undefined}
          >
            Approve
          </button>
          <button
            onClick={() => setStatus('denied')}
            className="pill"
            style={status === 'denied' ? { background: 'var(--blue)', color: 'var(--ink)', borderColor: '#d98b84' } : undefined}
          >
            Deny
          </button>
        </div>

        <label>
          <span className="field-label">Staff response (optional)</span>
          <textarea
            className="textarea"
            placeholder="Message shown to the player…"
            value={staffResponse}
            onChange={(e) => setStaffResponse(e.target.value)}
            rows={4}
            style={{ width: '100%' }}
          />
        </label>
      </div>
    </Modal>
  )
}

const activePill = { background: 'var(--blue)', color: 'var(--ink)', borderColor: 'var(--accent)' }
const muted = { color: 'var(--muted)' }
