'use client';

import { Suspense, useCallback, useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { useRouter, useSearchParams } from 'next/navigation';
import { Loader2, ShieldCheck } from 'lucide-react';
import { BrandLogo } from '@/components/id/brand-logo';
import { useAuth } from '@/components/id/auth-provider';
import { Button } from '@/components/ui/button';
import { approveOAuthAuthorization, fetchAuthSession } from '@/lib/api';

function buildOAuthQuery(searchParams: URLSearchParams) {
  const params = new URLSearchParams();
  searchParams.forEach((value, key) => {
    if (key !== 'userId') params.set(key, value);
  });
  return params;
}

function OAuthAuthorizeContent() {
  const searchParams = useSearchParams();
  const router = useRouter();
  const { user, token, isPinLocked, isLoading } = useAuth();
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [sessionChecked, setSessionChecked] = useState(false);

  const oauthQuery = useMemo(() => buildOAuthQuery(searchParams), [searchParams]);

  const clientId = searchParams.get('client_id') ?? searchParams.get('clientId');
  const redirectUri = searchParams.get('redirect_uri') ?? searchParams.get('redirectUri');
  const scope = searchParams.get('scope') ?? 'openid profile';
  const state = searchParams.get('state');

  const returnUrl = useMemo(() => `/auth/oauth/authorize?${oauthQuery.toString()}`, [oauthQuery]);

  useEffect(() => {
    if (!searchParams.has('userId')) return;
    router.replace(returnUrl);
  }, [returnUrl, router, searchParams]);

  useEffect(() => {
    if (isLoading) return;
    if (!clientId || !redirectUri) return;
    if (isPinLocked) return;
    if (user && token) return;
    router.replace(`/auth/login?redirect=${encodeURIComponent(returnUrl)}`);
  }, [clientId, isLoading, isPinLocked, redirectUri, returnUrl, router, token, user]);

  useEffect(() => {
    if (isLoading || isPinLocked || !token || !user) {
      setSessionChecked(false);
      return;
    }

    let cancelled = false;
    void fetchAuthSession(token)
      .then(() => {
        if (!cancelled) setSessionChecked(true);
      })
      .catch(() => {
        if (!cancelled) {
          setSessionChecked(false);
          router.replace(`/auth/login?redirect=${encodeURIComponent(returnUrl)}`);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [isLoading, isPinLocked, returnUrl, router, token, user]);

  const approve = useCallback(async () => {
    if (!token || !user || isPinLocked) return;
    setSubmitting(true);
    setError(null);
    try {
      const data = await approveOAuthAuthorization(oauthQuery, token);
      if (!data.redirectUrl) {
        throw new Error('Сервер не вернул redirect URL');
      }
      window.location.href = data.redirectUrl;
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Ошибка OAuth авторизации');
    } finally {
      setSubmitting(false);
    }
  }, [isPinLocked, oauthQuery, token, user]);

  const cancel = useCallback(() => {
    if (!redirectUri) {
      router.push('/');
      return;
    }
    try {
      const url = new URL(redirectUri);
      url.searchParams.set('error', 'access_denied');
      url.searchParams.set('error_description', 'Пользователь отклонил запрос');
      if (state) url.searchParams.set('state', state);
      window.location.href = url.toString();
    } catch {
      router.push('/');
    }
  }, [redirectUri, router, state]);

  const authReady = Boolean(user && token && !isPinLocked && sessionChecked);

  if (isLoading || (clientId && redirectUri && !authReady && !isPinLocked)) {
    return (
      <div className="flex min-h-[60vh] items-center justify-center">
        <Loader2 className="h-6 w-6 animate-spin text-[#667085]" />
      </div>
    );
  }

  if (isPinLocked) {
    return (
      <div className="flex min-h-[60vh] items-center justify-center px-4 text-center">
        <p className="text-sm text-[#667085]">Подтвердите PIN-код, чтобы продолжить авторизацию приложения.</p>
      </div>
    );
  }

  if (!clientId || !redirectUri) {
    return (
      <div className="mx-auto max-w-md px-4 py-16 text-center">
        <h1 className="text-xl font-semibold">Некорректный OAuth запрос</h1>
        <p className="mt-3 text-sm text-[#667085]">Отсутствуют обязательные параметры client_id и redirect_uri.</p>
        <Link href="/" className="mt-6 inline-block text-[#3390ec] hover:underline">
          На главную
        </Link>
      </div>
    );
  }

  return (
    <div className="mx-auto flex min-h-[70vh] max-w-lg flex-col justify-center px-4 py-12">
      <div className="mb-8 flex justify-center">
        <BrandLogo />
      </div>
      <div className="rounded-[24px] border border-[#eceef4] bg-white p-6 shadow-sm">
        <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-[#eef4ff] text-[#3390ec]">
          <ShieldCheck className="h-6 w-6" />
        </div>
        <h1 className="text-2xl font-semibold">Разрешить доступ?</h1>
        <p className="mt-2 text-sm leading-relaxed text-[#667085]">
          Приложение <span className="font-medium text-[#1f2430]">{clientId}</span> запрашивает доступ к вашему аккаунту Lendry ID.
        </p>
        <div className="mt-4 space-y-2 rounded-2xl bg-[#f4f5f8] p-4 text-sm">
          <p>
            <span className="text-[#667085]">Пользователь:</span> {user?.displayName}
          </p>
          <p>
            <span className="text-[#667085]">Scopes:</span> {scope}
          </p>
          <p className="break-all">
            <span className="text-[#667085]">Redirect URI:</span> {redirectUri}
          </p>
        </div>
        {error ? <p className="mt-4 text-sm text-red-600">{error}</p> : null}
        <div className="mt-6 flex flex-col gap-3 sm:flex-row">
          <Button className="flex-1 rounded-xl" disabled={submitting || !authReady} onClick={() => void approve()}>
            {submitting ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
            Разрешить
          </Button>
          <Button variant="outline" className="flex-1 rounded-xl" disabled={submitting} onClick={cancel}>
            Отмена
          </Button>
        </div>
      </div>
    </div>
  );
}

export default function OAuthAuthorizePage() {
  return (
    <Suspense
      fallback={
        <div className="flex min-h-[60vh] items-center justify-center">
          <Loader2 className="h-6 w-6 animate-spin text-[#667085]" />
        </div>
      }
    >
      <OAuthAuthorizeContent />
    </Suspense>
  );
}
