import { useEffect, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';

import { Alert } from '@/components/ui/Alert';
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';
import { SectionHeader } from '@/components/ui/SectionHeader';
import { TextField } from '@/components/ui/TextField';
import { ApiError, apiGet, apiPost } from '@/lib/api';

interface InvitationPreview {
  is_valid: boolean;
  reason: string | null;
  email_hint: string | null;
  expires_at: string;
  groups: string[];
}

export function RegisterPage() {
  const [params] = useSearchParams();
  const token = params.get('token') ?? '';
  const navigate = useNavigate();

  const [preview, setPreview] = useState<InvitationPreview | null>(null);
  const [previewError, setPreviewError] = useState<string | null>(null);
  const [email, setEmail] = useState('');
  const [displayName, setDisplayName] = useState('');
  const [password, setPassword] = useState('');
  const [confirm, setConfirm] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [done, setDone] = useState(false);

  useEffect(() => {
    if (!token) {
      setPreviewError('Missing invitation token in the URL.');
      return;
    }
    apiGet<InvitationPreview>(`/invitations/preview/${encodeURIComponent(token)}`, {
      anonymous: true,
    })
      .then((p) => {
        setPreview(p);
        if (p.email_hint) setEmail(p.email_hint);
      })
      .catch((err: unknown) =>
        setPreviewError(err instanceof Error ? err.message : 'Could not load invitation.'),
      );
  }, [token]);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    if (password !== confirm) {
      setError('Passwords do not match.');
      return;
    }
    setBusy(true);
    try {
      await apiPost(
        `/invitations/accept/${encodeURIComponent(token)}`,
        { email, password, display_name: displayName || undefined },
        { anonymous: true, noRefresh: true },
      );
      setDone(true);
      setTimeout(() => navigate('/login', { replace: true }), 1500);
    } catch (err) {
      if (err instanceof ApiError) {
        const payload = err.payload as { error?: string; message?: string } | null;
        setError(payload?.message ?? payload?.error ?? `HTTP ${err.status}`);
      } else {
        setError(err instanceof Error ? err.message : 'Registration failed.');
      }
    } finally {
      setBusy(false);
    }
  }

  if (done) {
    return (
      <div className="mx-auto max-w-md mt-12">
        <Alert accent="green">Account created. Redirecting to login…</Alert>
      </div>
    );
  }

  if (previewError) {
    return (
      <div className="mx-auto max-w-md mt-12">
        <Alert accent="red">{previewError}</Alert>
      </div>
    );
  }

  if (!preview) {
    return (
      <div className="mx-auto max-w-md mt-12">
        <Alert accent="cyan">Loading invitation…</Alert>
      </div>
    );
  }

  if (!preview.is_valid) {
    return (
      <div className="mx-auto max-w-md mt-12">
        <Alert accent="red">
          This invitation is not usable: <code>{preview.reason}</code>
        </Alert>
      </div>
    );
  }

  return (
    <div className="mx-auto max-w-xl mt-12">
      <SectionHeader
        prefix="Account"
        highlight="Registration"
        accent="green"
        description="Welcome — pick a password to join the platform."
      />
      <Card accent="green">
        <form onSubmit={handleSubmit} className="space-y-4">
          <TextField
            label="Email"
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            hint={preview.email_hint ? `Invited as ${preview.email_hint}` : undefined}
            required
          />
          <TextField
            label="Display name (optional)"
            value={displayName}
            onChange={(e) => setDisplayName(e.target.value)}
          />
          <TextField
            label="Password"
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
          <TextField
            label="Confirm password"
            type="password"
            value={confirm}
            onChange={(e) => setConfirm(e.target.value)}
            required
          />
          {preview.groups.length > 0 && (
            <Alert accent="cyan">
              You will be added to: {preview.groups.map((g) => `[${g}]`).join(' ')}
            </Alert>
          )}
          {error && <Alert accent="red">{error}</Alert>}
          <Button type="submit" accent="green" disabled={busy}>
            {busy ? 'Creating account…' : 'Create account'}
          </Button>
        </form>
      </Card>
    </div>
  );
}
