import { useState, useEffect, useCallback } from 'react';
import { Copy, Check, Plus, RefreshCw, Trash2 } from 'lucide-react';
import { api } from '@/lib/api';

interface Invitation {
  id: string;
  code: string;
  createdBy: { username: string | null; email: string | null };
  usedBy: { username: string | null; email: string | null } | null;
  createdAt: string;
  expiresAt: string | null;
  used: boolean;
}

function displayUser(u: { username: string | null; email: string | null }): string {
  return u.username || u.email || 'Unknown';
}

function StatusBadge({ used, expiresAt }: { used: boolean; expiresAt: string | null }) {
  if (used) {
    return <span className="text-xs px-2 py-0.5 rounded-full bg-surface-700 text-surface-400">Used</span>;
  }
  if (expiresAt && new Date(expiresAt) < new Date()) {
    return <span className="text-xs px-2 py-0.5 rounded-full bg-danger/20 text-danger">Expired</span>;
  }
  return <span className="text-xs px-2 py-0.5 rounded-full bg-accent/20 text-accent">Active</span>;
}

export function InvitationsPage() {
  const [invitations, setInvitations] = useState<Invitation[]>([]);
  const [loading, setLoading] = useState(true);
  const [generating, setGenerating] = useState(false);
  const [copiedCode, setCopiedCode] = useState<string | null>(null);
  const [revoking, setRevoking] = useState<string | null>(null);

  const fetchInvitations = useCallback(async () => {
    try {
      const result = await api.invites.list();
      setInvitations(result.invitations);
    } catch {
      // silent
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { fetchInvitations(); }, [fetchInvitations]);

  async function handleGenerate() {
    setGenerating(true);
    try {
      const result = await api.invites.create();
      const url = `${window.location.origin}?invite=${result.code}`;
      await navigator.clipboard.writeText(url);
      setCopiedCode(result.code);
      setTimeout(() => setCopiedCode(null), 2000);
      await fetchInvitations();
    } catch {
      // silent
    } finally {
      setGenerating(false);
    }
  }

  async function handleRevoke(id: string) {
    setRevoking(id);
    try {
      await api.invites.revoke(id);
      await fetchInvitations();
    } catch {
      // silent
    } finally {
      setRevoking(null);
    }
  }

  async function handleCopyCode(code: string) {
    const url = `${window.location.origin}?invite=${code}`;
    await navigator.clipboard.writeText(url);
    setCopiedCode(code);
    setTimeout(() => setCopiedCode(null), 2000);
  }

  const activeCount = invitations.filter(i => !i.used && (!i.expiresAt || new Date(i.expiresAt) > new Date())).length;
  const usedCount = invitations.filter(i => i.used).length;

  return (
    <div className="space-y-6 max-w-4xl">
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-2xl font-bold">Invitations</h2>
          <p className="text-sm text-surface-400 mt-1">
            {activeCount} active, {usedCount} used, {invitations.length} total
          </p>
        </div>
        <div className="flex gap-2">
          <button
            onClick={fetchInvitations}
            className="px-3 py-2 rounded bg-surface-800 hover:bg-surface-700 border border-surface-600 text-sm flex items-center gap-2"
          >
            <RefreshCw size={14} /> Refresh
          </button>
          <button
            onClick={handleGenerate}
            disabled={generating}
            className="px-4 py-2 rounded bg-accent hover:bg-accent-dark text-white font-medium text-sm flex items-center gap-2 disabled:opacity-50"
          >
            <Plus size={14} /> {generating ? 'Generating...' : 'Generate Invite'}
          </button>
        </div>
      </div>

      <div className="bg-surface-900 border border-surface-700 rounded-xl overflow-hidden">
        {loading ? (
          <div className="p-8 text-center text-surface-500">Loading invitations...</div>
        ) : invitations.length === 0 ? (
          <div className="p-8 text-center text-surface-500">
            No invitations yet. Generate one to get started.
          </div>
        ) : (
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-surface-700 text-left text-surface-400">
                <th className="px-4 py-3 font-medium">Code</th>
                <th className="px-4 py-3 font-medium">Created By</th>
                <th className="px-4 py-3 font-medium">Used By</th>
                <th className="px-4 py-3 font-medium">Created</th>
                <th className="px-4 py-3 font-medium">Status</th>
                <th className="px-4 py-3 font-medium w-10"></th>
              </tr>
            </thead>
            <tbody>
              {invitations.map((inv) => (
                <tr key={inv.id} className="border-b border-surface-800 hover:bg-surface-800/50">
                  <td className="px-4 py-3 font-mono text-surface-200">{inv.code}</td>
                  <td className="px-4 py-3 text-surface-300">{displayUser(inv.createdBy)}</td>
                  <td className="px-4 py-3 text-surface-300">
                    {inv.usedBy ? displayUser(inv.usedBy) : <span className="text-surface-600">—</span>}
                  </td>
                  <td className="px-4 py-3 text-surface-400">
                    {new Date(inv.createdAt).toLocaleDateString()}
                  </td>
                  <td className="px-4 py-3">
                    <StatusBadge used={inv.used} expiresAt={inv.expiresAt} />
                  </td>
                  <td className="px-4 py-3">
                    {!inv.used && (
                      <div className="flex items-center gap-2">
                        <button
                          onClick={() => handleCopyCode(inv.code)}
                          className="text-surface-400 hover:text-surface-200 transition-colors"
                          title="Copy invite link"
                        >
                          {copiedCode === inv.code ? <Check size={14} className="text-accent" /> : <Copy size={14} />}
                        </button>
                        <button
                          onClick={() => handleRevoke(inv.id)}
                          disabled={revoking === inv.id}
                          className="text-surface-400 hover:text-danger transition-colors disabled:opacity-50"
                          title="Revoke invitation"
                        >
                          <Trash2 size={14} />
                        </button>
                      </div>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}
