﻿'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { motion } from 'framer-motion';
import { signIn } from 'next-auth/react';
import { useRouter } from 'next/navigation';
import { CheckCircle2, Loader2, MessageCircle, Send } from 'lucide-react';
import {
  formatApiErrorWithRequestId,
  formatRetryAfterHuman,
  getResponseErrorDetails,
} from '@/lib/api-client';
import { config } from '@/lib/config';
import { getRuntimeClientConfig } from '@/lib/runtime-client-config';
import { AUTH_ERROR_NEW_USER_PENDING_APPROVAL } from '@/lib/auth-error-codes';

type LoginStep = 'initial' | 'code' | 'loading' | 'success' | 'pending';

type TelegramLoginModalProps = {
  onClose: () => void;
  returnTo?: string;
};

const REDIRECT_DELAY_MS = 1500;

function normalizeSignInError(error: string): string {
  if (error === AUTH_ERROR_NEW_USER_PENDING_APPROVAL) {
    return 'Заявка отправлена и ожидает одобрения. После одобрения вы сможете войти.';
  }
  if (error === 'CredentialsSignin') {
    return 'Неверный код или сессия входа истекла.';
  }
  return error;
}

export default function TelegramLoginModal({
  onClose,
  returnTo = '/profile',
}: TelegramLoginModalProps) {
  const router = useRouter();
  const runtimeConfig = getRuntimeClientConfig();
  const projectName = runtimeConfig.projectName || config.projectName;
  const defaultBotUrl = runtimeConfig.telegramBotUrl || '#';

  const [step, setStep] = useState<LoginStep>('initial');
  const [code, setCode] = useState('');
  const [challengeId, setChallengeId] = useState('');
  const [botStartUrl, setBotStartUrl] = useState('');
  const [error, setError] = useState('');
  const [isRequestingCode, setIsRequestingCode] = useState(false);
  const redirectTimeoutRef = useRef<number | null>(null);

  const canClose = step !== 'loading' && step !== 'success';

  useEffect(() => {
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, []);

  useEffect(() => {
    if (!canClose) {
      return;
    }

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        onClose();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [canClose, onClose]);

  useEffect(() => {
    return () => {
      if (redirectTimeoutRef.current) {
        window.clearTimeout(redirectTimeoutRef.current);
      }
    };
  }, []);

  const buildApiError = useCallback(async (response: Response, fallback: string) => {
    const details = await getResponseErrorDetails(response, fallback);
    const retryAfter = formatRetryAfterHuman(details.retryAfterSec);
    const baseMessage = formatApiErrorWithRequestId(details);
    return retryAfter ? `${baseMessage}. Повторите через ${retryAfter}` : baseMessage;
  }, []);

  const handleGetCode = useCallback(async () => {
    setError('');
    setIsRequestingCode(true);

    try {
      const response = await fetch('/api/auth/telegram/start', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({}),
      });

      if (!response.ok) {
        setError(await buildApiError(response, 'Не удалось отправить код в Telegram.'));
        return;
      }

      const data = await response.json();
      setChallengeId(data.challengeId || '');
      setBotStartUrl(data.botStartUrl || '');
      setCode('');
      setStep('code');
    } catch {
      setError('Ошибка при запуске авторизации через Telegram.');
    } finally {
      setIsRequestingCode(false);
    }
  }, [buildApiError]);

  const handleVerifyCode = useCallback(async () => {
    if (code.length !== 6) {
      setError('Код должен состоять из 6 цифр.');
      return;
    }

    if (!challengeId) {
      setError('Сессия входа истекла. Получите код заново.');
      setStep('initial');
      return;
    }

    setError('');
    setStep('loading');

    try {
      const preflight = await fetch('/api/auth/providers');
      if (!preflight.ok) {
        setError(await buildApiError(preflight, 'Сервис авторизации временно недоступен.'));
        setStep('code');
        return;
      }

      const result = await signIn('credentials', {
        code,
        challengeId,
        redirect: false,
      });

      if (result?.error) {
        if (result.error === AUTH_ERROR_NEW_USER_PENDING_APPROVAL) {
          setError('');
          setStep('pending');
          return;
        }

        setError(normalizeSignInError(result.error));
        setStep('code');
        return;
      }

      setStep('success');
      redirectTimeoutRef.current = window.setTimeout(() => {
        onClose();
        router.push(returnTo, { scroll: false });
      }, REDIRECT_DELAY_MS);
    } catch {
      setError('Ошибка при входе через Telegram.');
      setStep('code');
    }
  }, [buildApiError, challengeId, code, onClose, returnTo, router]);

  return (
    <div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        onClick={canClose ? onClose : undefined}
        className="absolute inset-0 bg-black/60 backdrop-blur-sm"
      />

      <motion.div
        initial={{ opacity: 0, scale: 0.95, y: 10 }}
        animate={{ opacity: 1, scale: 1, y: 0 }}
        exit={{ opacity: 0, scale: 0.95, y: 10 }}
        className="relative z-10 w-full max-w-[420px] bg-[#0A0A0A]/95 border border-white/10 rounded-3xl p-8 overflow-hidden shadow-[0_0_60px_rgba(109,40,217,0.15)] flex flex-col items-center backdrop-blur-xl"
      >
        <div className="absolute top-[-50%] right-[-50%] w-[300px] h-[300px] bg-violet-500/10 rounded-full blur-3xl pointer-events-none" />
        <div className="absolute bottom-[-50%] left-[-50%] w-[300px] h-[300px] bg-[#2AABEE]/20 rounded-full blur-3xl pointer-events-none" />

        <div className="relative z-10 flex flex-col items-center w-full min-h-[300px] justify-center">
          {step === 'success' ? (
            <motion.div
              initial={{ scale: 0.8, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              className="flex flex-col items-center py-8"
            >
              <div className="w-20 h-20 rounded-full bg-green-500/10 border border-green-500/20 flex items-center justify-center mb-6 shadow-[0_0_40px_rgba(34,197,94,0.3)]">
                <CheckCircle2 className="w-10 h-10 text-green-400" />
              </div>
              <h2 className="text-2xl font-bold text-white mb-2 tracking-tight">Успешный вход!</h2>
              <p className="text-gray-400 text-sm">Перенаправляем в панель...</p>
            </motion.div>
          ) : step === 'pending' ? (
            <motion.div
              initial={{ scale: 0.8, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              className="flex flex-col items-center py-8 text-center"
            >
              <div className="mb-6 flex h-20 w-20 items-center justify-center rounded-full border border-violet-500/20 bg-violet-500/10 shadow-[0_0_40px_rgba(139,92,246,0.25)]">
                <MessageCircle className="h-10 w-10 text-violet-300" />
              </div>
              <h2 className="mb-2 text-2xl font-bold tracking-tight text-white">Заявка на рассмотрении</h2>
              <p className="max-w-xs text-sm leading-relaxed text-gray-400">
                Сейчас ваша заявка рассматривается администратором. Попробуйте войти позже.
              </p>
              <button
                type="button"
                onClick={onClose}
                className="mt-7 rounded-xl border border-white/10 bg-white/5 px-5 py-2.5 text-sm font-medium text-white transition-colors hover:bg-white/10"
              >
                Понятно
              </button>
            </motion.div>
          ) : (
            <>
              <div className="w-16 h-16 rounded-2xl bg-gradient-to-br from-violet-500 to-[#2AABEE] flex items-center justify-center shadow-[0_0_30px_rgba(139,92,246,0.3)] mb-6 mt-2">
                <Send className="w-8 h-8 text-white ml-[-2px] mt-[2px]" />
              </div>

              <div className="text-center mb-8">
                <h2 className="text-2xl font-bold tracking-tight text-white mb-2">
                  {step === 'initial' ? 'Вход через Telegram' : 'Введите код'}
                </h2>
                <p className="text-gray-400 text-sm">
                  {step === 'initial'
                    ? `Войдите в ${projectName} через Telegram и одноразовый код`
                    : 'Мы отправили одноразовый код в нашего Telegram-бота'}
                </p>
              </div>

              {step === 'initial' && (
                <>
                  <button
                    type="button"
                    onClick={handleGetCode}
                    disabled={isRequestingCode}
                    className="w-full bg-[#2AABEE] hover:bg-[#229ED9] disabled:bg-[#2AABEE]/60 disabled:cursor-not-allowed text-white font-medium py-3.5 px-4 rounded-xl transition-all shadow-[0_0_20px_rgba(42,171,238,0.3)] mb-6 flex items-center justify-center gap-2"
                  >
                    {isRequestingCode ? (
                      <>
                        <Loader2 className="w-5 h-5 animate-spin" />
                        Получаем код...
                      </>
                    ) : (
                      'Получить код'
                    )}
                  </button>

                  <div className="bg-white/5 border border-white/10 rounded-2xl p-5 mb-8 w-full text-left">
                    <h3 className="text-white text-sm font-semibold mb-3">Как войти</h3>
                    <ol className="text-sm text-gray-400 space-y-2 mb-4 pl-4 list-decimal marker:text-gray-600">
                      <li>Нажмите «Получить код».</li>
                      <li>Откройте Telegram-бота по кнопке из формы.</li>
                      <li>Бот отправит одноразовый код, а сайт подтвердит вход по нему.</li>
                    </ol>
                    <p className="text-xs text-gray-500 leading-relaxed">
                      Вводить Telegram ID больше не нужно: бот сам связывает аккаунт через ссылку запуска.
                    </p>
                  </div>
                </>
              )}

              {(step === 'code' || step === 'loading') && (
                <motion.div
                  initial={{ opacity: 0, y: 10 }}
                  animate={{ opacity: 1, y: 0 }}
                  className="w-full flex flex-col"
                >
                  <a
                    href={botStartUrl || defaultBotUrl}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="w-full flex items-center justify-center gap-2 bg-white/5 border border-white/10 hover:bg-white/10 text-white py-3 rounded-xl transition-colors mb-6 text-sm font-medium"
                  >
                    <MessageCircle className="w-4 h-4 text-[#2AABEE]" />
                    Открыть бота в Telegram
                  </a>

                  <div className="relative mb-6">
                    <input
                      type="text"
                      inputMode="numeric"
                      placeholder="X X X X X X"
                      value={code}
                      onChange={(event) => {
                        setCode(event.target.value.replace(/\D/g, '').slice(0, 6));
                        setError('');
                      }}
                      maxLength={6}
                      disabled={step === 'loading'}
                      className={`w-full bg-black/40 border rounded-xl py-4 text-center text-2xl font-mono tracking-[0.5em] text-white placeholder-gray-600 outline-none transition-all ${
                        error
                          ? 'border-red-500/50 focus:border-red-500 focus:bg-red-500/5'
                          : 'border-white/10 focus:border-violet-500/50 focus:bg-white/5'
                      } ${step === 'loading' ? 'opacity-50' : ''}`}
                    />
                    {error && (
                      <span className="absolute -bottom-5 left-0 right-0 text-center text-red-400 text-xs font-medium">
                        {error}
                      </span>
                    )}
                  </div>

                  <button
                    type="button"
                    onClick={handleVerifyCode}
                    disabled={step === 'loading' || code.length !== 6}
                    className="w-full bg-[#2AABEE] hover:bg-[#229ED9] disabled:bg-[#2AABEE]/50 disabled:text-white/70 disabled:cursor-not-allowed text-white font-medium py-3.5 px-4 rounded-xl transition-all shadow-[0_0_20px_rgba(42,171,238,0.3)] mb-6 flex items-center justify-center gap-2"
                  >
                    {step === 'loading' ? (
                      <>
                        <Loader2 className="w-5 h-5 animate-spin" />
                        Проверка кода...
                      </>
                    ) : (
                      'Подтвердить код'
                    )}
                  </button>
                </motion.div>
              )}

              <button
                type="button"
                onClick={onClose}
                disabled={!canClose}
                className="text-gray-500 hover:text-white transition-colors text-sm font-medium self-center px-4 py-2 disabled:opacity-30 disabled:hover:text-gray-500"
              >
                ← На главную
              </button>
            </>
          )}
        </div>
      </motion.div>
    </div>
  );
}

