'use client';

import * as React from 'react';
import { Loader2, QrCode } from 'lucide-react';
import { QRCodeSVG } from 'qrcode.react';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import {
  approveQrLoginSession,
  createDeviceLinkQrSession,
  getApiErrorMessage,
  pollQrLoginSession,
  type QrLoginSession
} from '@/lib/api';

interface DeviceLinkQrDialogProps {
  open: boolean;
  userId: string;
  token: string;
  onOpenChange: (open: boolean) => void;
  onLinked?: () => void;
}

function formatCountdown(expiresAt: string) {
  const secondsLeft = Math.max(0, Math.ceil((new Date(expiresAt).getTime() - Date.now()) / 1000));
  const minutes = Math.floor(secondsLeft / 60);
  const seconds = secondsLeft % 60;
  return `${minutes}:${seconds.toString().padStart(2, '0')}`;
}

export function DeviceLinkQrDialog({ open, userId, token, onOpenChange, onLinked }: DeviceLinkQrDialogProps) {
  const [session, setSession] = React.useState<QrLoginSession | null>(null);
  const [loading, setLoading] = React.useState(false);
  const [approving, setApproving] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);
  const [successMessage, setSuccessMessage] = React.useState<string | null>(null);
  const [countdown, setCountdown] = React.useState('5:00');
  const approveStartedRef = React.useRef(false);
  const refreshInFlightRef = React.useRef(false);

  const refreshSession = React.useCallback(async () => {
    if (!userId || !token || refreshInFlightRef.current) return;
    refreshInFlightRef.current = true;
    setLoading(true);
    setError(null);
    setSuccessMessage(null);
    approveStartedRef.current = false;
    try {
      const created = await createDeviceLinkQrSession(userId, token);
      setSession(created);
    } catch (err) {
      setError(getApiErrorMessage(err, 'Не удалось создать QR-код') ?? 'Не удалось создать QR-код');
    } finally {
      setLoading(false);
      refreshInFlightRef.current = false;
    }
  }, [token, userId]);

  React.useEffect(() => {
    if (!open) {
      setSession(null);
      setError(null);
      setSuccessMessage(null);
      approveStartedRef.current = false;
      return;
    }
    void refreshSession();
  }, [open, refreshSession]);

  React.useEffect(() => {
    if (!open || !session?.expiresAt) return;
    const update = () => setCountdown(formatCountdown(session.expiresAt));
    update();
    const timer = window.setInterval(update, 1000);
    return () => window.clearInterval(timer);
  }, [open, session?.expiresAt]);

  React.useEffect(() => {
    if (!open || !session?.sessionId || !token || successMessage) return;

    let cancelled = false;

    const poll = async () => {
      try {
        const current = await pollQrLoginSession(session.sessionId);
        if (cancelled) return;

        if (current.status === 'EXPIRED') {
          if (!refreshInFlightRef.current) {
            await refreshSession();
          }
          return;
        }

        if (current.claimed && !approveStartedRef.current) {
          approveStartedRef.current = true;
          setApproving(true);
          setError(null);
          try {
            await approveQrLoginSession(session.sessionId, token);
            if (cancelled) return;
            const label = current.claimedDeviceName?.trim();
            setSuccessMessage(label ? `Устройство «${label}» подключено` : 'Новое устройство подключено');
            onLinked?.();
          } catch (err) {
            if (!cancelled) {
              approveStartedRef.current = false;
              setError(getApiErrorMessage(err, 'Не удалось подтвердить подключение') ?? 'Не удалось подтвердить подключение');
            }
          } finally {
            if (!cancelled) setApproving(false);
          }
        }
      } catch (err) {
        if (!cancelled) {
          setError(getApiErrorMessage(err, 'Не удалось проверить статус QR-кода') ?? 'Не удалось проверить статус QR-кода');
        }
      }
    };

    void poll();
    const timer = window.setInterval(() => void poll(), 2000);
    return () => {
      cancelled = true;
      window.clearInterval(timer);
    };
  }, [onLinked, open, refreshSession, session?.sessionId, successMessage, token]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>Подключить новое устройство</DialogTitle>
        </DialogHeader>

        {loading && !session ? (
          <div className="flex min-h-[280px] flex-col items-center justify-center gap-3 text-[#667085]">
            <Loader2 className="h-6 w-6 animate-spin" />
            <p className="text-sm">Генерируем QR-код...</p>
          </div>
        ) : null}

        {session?.qrPayload ? (
          <div className="space-y-4 text-center">
            <div className="mx-auto flex w-fit rounded-[24px] border border-[#eceef4] bg-white p-4 shadow-sm">
              <QRCodeSVG value={session.qrPayload} size={220} />
            </div>
            <p className="text-sm leading-relaxed text-[#667085]">
              Отсканируйте QR-код камерой на новом устройстве. Откроется страница входа, и устройство подключится к вашему аккаунту.
            </p>
            <p className="text-xs text-[#8f92a0]">
              Код действует <span className="font-medium text-[#1f2430]">{countdown}</span> и обновится автоматически
            </p>
            {approving ? (
              <p className="flex items-center justify-center gap-2 text-sm text-[#3390ec]">
                <Loader2 className="h-4 w-4 animate-spin" />
                Подключаем устройство...
              </p>
            ) : null}
            {successMessage ? <p className="text-sm font-medium text-[#1a7f37]">{successMessage}</p> : null}
            {error ? <p className="text-sm text-red-600">{error}</p> : null}
            <Button type="button" variant="outline" className="w-full rounded-xl" disabled={loading} onClick={() => void refreshSession()}>
              <QrCode className="mr-2 h-4 w-4" />
              {loading ? 'Обновляем...' : 'Обновить QR-код'}
            </Button>
          </div>
        ) : null}
      </DialogContent>
    </Dialog>
  );
}
