'use client';

import { useRef, useState } from 'react';
import Link from 'next/link';
import { ArrowRight, LoaderCircle, X } from 'lucide-react';
import { createReport, type ParticipantInput } from '@/app/actions/reports';
import { LiveDeviceCamera } from '@/components/camera/LiveDeviceCamera';
import { downscaleImage } from '@/lib/image';
import { cn } from '@/lib/cn';
import { QrCode } from './QrCode';
import { useMessages } from '@/i18n/client';

type Save =
  | { status: 'saving' }
  | { status: 'saved'; token: string }
  | { status: 'error'; message: string };

const EMPTY: ParticipantInput = { name: '', email: '', phone: '', consent: true };

/**
 * Full-screen kiosk for scanning many people at a venue:
 * participant details → camera → QR to open their report → next participant.
 */
export function KioskFlow({ event }: { event: { id: string; name: string } }) {
  const t = useMessages().admin.kiosk;
  const [form, setForm] = useState<ParticipantInput>(EMPTY);
  const [consent, setConsent] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [cameraOpen, setCameraOpen] = useState(false);
  const [save, setSave] = useState<Save | null>(null);
  const [round, setRound] = useState(0);
  const [count, setCount] = useState(0);
  const nameRef = useRef<HTMLInputElement>(null);

  const startCamera = (e: React.FormEvent) => {
    e.preventDefault();
    if (form.name.trim().length < 2) return setError(t.nameError);
    if (!consent) return setError(t.consentError);
    setError(null);
    setSave(null);
    setCameraOpen(true);
  };

  const nextParticipant = () => {
    setCameraOpen(false);
    setSave(null);
    setForm(EMPTY);
    setConsent(false);
    setRound((r) => r + 1);
    requestAnimationFrame(() => nameRef.current?.focus());
  };

  const input =
    'h-14 w-full rounded-2xl bg-white/[0.06] px-5 text-[17px] text-white ring-1 ring-white/15 transition-shadow placeholder:text-white/35 focus:ring-2 focus:ring-white/70 focus:outline-none';

  return (
    <div className="fixed inset-0 z-40 flex flex-col overflow-y-auto bg-night-950 text-white">
      <header className="flex h-16 shrink-0 items-center justify-between gap-4 border-b border-white/[0.08] px-5 sm:px-8">
        <div className="min-w-0">
          <p className="truncate text-sm font-semibold">{event.name}</p>
          <p className="text-xs text-white/50">{t.mode(count)}</p>
        </div>
        <Link
          href={`/admin/sesi/${event.id}`}
          className="inline-flex items-center gap-1.5 rounded-full px-3 py-2 text-[13px] font-medium text-white/70 transition-colors hover:bg-white/10 hover:text-white"
        >
          <X className="size-4" aria-hidden />
          {t.exit}
        </Link>
      </header>

      <main className="flex flex-1 items-center justify-center px-5 py-10">
        <form onSubmit={startCamera} className="w-full max-w-[480px]" noValidate>
          <p className="eyebrow text-white/50">{t.eyebrow}</p>
          <h1 className="mt-4 text-[34px] leading-[1.1] font-semibold tracking-[-0.025em] sm:text-[40px]">
            {t.title[0]}
            <br />
            {t.title[1]}
          </h1>

          <div className="mt-10 space-y-4">
            <label className="block">
              <span className="text-[13px] font-medium text-white/70">{t.name}</span>
              <input
                ref={nameRef}
                autoFocus
                autoComplete="off"
                value={form.name}
                onChange={(e) => setForm({ ...form, name: e.target.value })}
                placeholder={t.namePlaceholder}
                className={cn(input, 'mt-2')}
              />
            </label>
            <div className="grid gap-4 sm:grid-cols-2">
              <label className="block">
                <span className="text-[13px] font-medium text-white/70">{t.email}</span>
                <input
                  type="email"
                  inputMode="email"
                  autoComplete="off"
                  value={form.email}
                  onChange={(e) => setForm({ ...form, email: e.target.value })}
                  className={cn(input, 'mt-2')}
                />
              </label>
              <label className="block">
                <span className="text-[13px] font-medium text-white/70">{t.phone}</span>
                <input
                  type="tel"
                  inputMode="tel"
                  autoComplete="off"
                  value={form.phone}
                  onChange={(e) => setForm({ ...form, phone: e.target.value })}
                  className={cn(input, 'mt-2')}
                />
              </label>
            </div>

            <label className="flex cursor-pointer items-start gap-3 rounded-2xl bg-white/[0.04] p-4 ring-1 ring-white/10">
              <input
                type="checkbox"
                checked={consent}
                onChange={(e) => setConsent(e.target.checked)}
                className="mt-0.5 size-5 shrink-0 accent-white"
              />
              <span className="text-[13px] leading-relaxed text-white/70">
                {t.consent}
              </span>
            </label>
          </div>

          {error && (
            <p role="alert" className="mt-4 text-sm text-[#FF8A8F]">
              {error}
            </p>
          )}

          <button
            type="submit"
            className="group mt-8 inline-flex h-14 w-full items-center justify-center gap-2 rounded-full bg-white text-[15px] font-semibold text-ink transition-colors hover:bg-white/90"
          >
            {t.next}
            <ArrowRight className="size-4 transition-transform group-hover:translate-x-0.5" aria-hidden />
          </button>
        </form>
      </main>

      <LiveDeviceCamera
        key={round}
        isOpen={cameraOpen}
        onClose={() => setCameraOpen(false)}
        onSuccess={async (result, photo) => {
          setSave({ status: 'saving' });
          const res = await createReport({
            result,
            photo: await downscaleImage(photo),
            eventId: event.id,
            participant: { ...form, consent: consent as true },
          });
          if (res.ok) {
            setSave({ status: 'saved', token: res.data.shareToken });
            setCount((c) => c + 1);
          } else {
            setSave({ status: 'error', message: res.error });
          }
        }}
        renderActions={() => (
          <KioskResult save={save} name={form.name} onNext={nextParticipant} onRetry={() => setRound((r) => r + 1)} />
        )}
      />
    </div>
  );
}

function KioskResult({
  save,
  name,
  onNext,
  onRetry,
}: {
  save: Save | null;
  name: string;
  onNext: () => void;
  onRetry: () => void;
}) {
  const t = useMessages().admin.kiosk;
  if (!save || save.status === 'saving') {
    return (
      <p className="flex items-center justify-center gap-2 py-6 text-sm text-white/60">
        <LoaderCircle className="size-4 animate-spin" aria-hidden />
        {t.saving}
      </p>
    );
  }

  if (save.status === 'error') {
    return (
      <div className="rounded-2xl bg-white/[0.04] p-5 text-center ring-1 ring-white/10">
        <p className="text-sm text-[#FF8A8F]">{save.message}</p>
        <button
          type="button"
          onClick={onRetry}
          className="mt-4 h-11 rounded-full bg-white px-6 text-sm font-semibold text-ink"
        >
          {t.retry}
        </button>
      </div>
    );
  }

  return (
    <div className="flex flex-col items-center gap-6 rounded-2xl bg-white/[0.04] p-6 text-center ring-1 ring-white/10 sm:flex-row sm:text-left">
      <QrCode path={`/r/${save.token}`} className="w-44 shrink-0" />
      <div>
        <p className="text-lg font-semibold">{t.scanThis(name.split(' ')[0])}</p>
        <p className="mt-2 text-sm leading-relaxed text-white/60">
          {t.scanText}
        </p>
        <button
          type="button"
          onClick={onNext}
          className="group mt-5 inline-flex h-12 items-center gap-2 rounded-full bg-white px-6 text-sm font-semibold text-ink transition-colors hover:bg-white/90"
        >
          {t.nextParticipant}
          <ArrowRight className="size-4 transition-transform group-hover:translate-x-0.5" aria-hidden />
        </button>
      </div>
    </div>
  );
}
