'use client';

import { useCallback, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Ban, CheckCircle2, ChevronRight, FileKey2, Loader2 } from 'lucide-react';
import { useAuth } from '@/components/id/auth-provider';
import { IdShell } from '@/components/id/shell';
import { usePublicSettings } from '@/components/id/public-settings-provider';
import { useToast } from '@/components/id/toast-provider';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { useRequireAuth } from '@/hooks/use-require-auth';
import {
  fetchUserOAuthConsents,
  getApiErrorMessage,
  revokeOAuthConsent,
  type OAuthUserConsent
} from '@/lib/api';

function formatGrantedAt(value: string) {
  return new Intl.DateTimeFormat('ru-RU', {
    day: 'numeric',
    month: 'long',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  }).format(new Date(value));
}

export default function DataConsentsPage() {
  const router = useRouter();
  const { user, token } = useAuth();
  const { projectName } = usePublicSettings();
  const { isReady, isPinLocked } = useRequireAuth();
  const { showToast } = useToast();
  const [consents, setConsents] = useState<OAuthUserConsent[]>([]);
  const [loading, setLoading] = useState(true);
  const [selectedConsent, setSelectedConsent] = useState<OAuthUserConsent | null>(null);
  const [revoking, setRevoking] = useState(false);

  const loadConsents = useCallback(async () => {
    if (!user || !token || isPinLocked) return;
    setLoading(true);
    try {
      const response = await fetchUserOAuthConsents(user.id, token);
      setConsents(response.consents ?? []);
    } catch (error) {
      showToast(getApiErrorMessage(error, 'Не удалось загрузить доступы') ?? 'Ошибка');
    } finally {
      setLoading(false);
    }
  }, [isPinLocked, showToast, token, user]);

  useEffect(() => {
    if (isReady && user && !isPinLocked) void loadConsents();
  }, [isPinLocked, isReady, loadConsents, user]);

  async function handleRevoke() {
    if (!user || !token || !selectedConsent) return;
    setRevoking(true);
    try {
      await revokeOAuthConsent(user.id, selectedConsent.id, token);
      setConsents((current) => current.filter((item) => item.id !== selectedConsent.id));
      setSelectedConsent(null);
      showToast('Доступ отозван');
    } catch (error) {
      showToast(getApiErrorMessage(error, 'Не удалось отозвать доступ') ?? 'Ошибка');
    } finally {
      setRevoking(false);
    }
  }

  return (
    <IdShell active="/data">
      <button
        type="button"
        onClick={() => router.push('/data')}
        className="mb-6 text-sm text-[#3390ec] transition hover:underline"
      >
        ← Назад к данным
      </button>

      <h1 className="text-2xl font-medium">Доступы к данным</h1>
      <p className="mt-1 text-sm text-[#667085]">
        Настройте, к каким данным аккаунта есть доступ у сервисов. После отзыва при следующем входе доступ нужно будет подтвердить снова.
      </p>

      <div className="mt-6 overflow-hidden rounded-[24px] bg-[#f4f5f8]">
        {loading ? (
          <div className="flex items-center justify-center gap-2 px-4 py-10 text-sm text-[#667085]">
            <Loader2 className="h-4 w-4 animate-spin" />
            Загружаем приложения...
          </div>
        ) : consents.length === 0 ? (
          <p className="px-4 py-10 text-center text-sm text-[#667085]">Вы ещё не выдавали доступ ни одному приложению</p>
        ) : (
          consents.map((consent) => (
            <button
              key={consent.id}
              type="button"
              onClick={() => setSelectedConsent(consent)}
              className="flex w-full items-center gap-4 border-b border-[#eceef4] px-4 py-4 text-left transition last:border-b-0 hover:bg-[#fafbfd]"
            >
              <div className="flex h-11 w-11 items-center justify-center rounded-2xl bg-white">
                <FileKey2 className="h-5 w-5 text-[#667085]" />
              </div>
              <div className="min-w-0 flex-1">
                <div className="font-medium">{consent.clientName}</div>
                <div className="truncate text-sm text-[#667085]">Выданы {formatGrantedAt(consent.grantedAt)}</div>
              </div>
              <ChevronRight className="h-5 w-5 shrink-0 text-[#a8adbc]" />
            </button>
          ))
        )}
      </div>

      <Dialog open={Boolean(selectedConsent)} onOpenChange={(open) => !open && setSelectedConsent(null)}>
        <DialogContent className="rounded-[28px] sm:max-w-[480px]">
          {selectedConsent ? (
            <>
              <DialogHeader>
                <div className="mx-auto mb-2 flex h-12 w-12 items-center justify-center rounded-full bg-[#eef4ff] text-[#3390ec]">
                  <CheckCircle2 className="h-6 w-6" />
                </div>
                <DialogTitle className="text-center text-xl">{selectedConsent.clientName}</DialogTitle>
              </DialogHeader>
              <p className="text-center text-sm text-[#667085]">
                Выданы {formatGrantedAt(selectedConsent.grantedAt)}
              </p>
              <div className="mt-4 rounded-2xl bg-[#f4f5f8] p-4">
                <p className="text-sm font-medium">API {projectName}</p>
                <ul className="mt-3 space-y-2">
                  {selectedConsent.scopes.map((scope) => (
                    <li key={scope.slug} className="flex items-start gap-2 text-sm">
                      <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0 text-[#3390ec]" />
                      <div>
                        <div>{scope.description ?? scope.name}</div>
                      </div>
                    </li>
                  ))}
                </ul>
              </div>
              <p className="mt-4 text-center text-xs text-[#667085]">ID: {selectedConsent.id.slice(0, 8).toUpperCase()}</p>
              <div className="mt-6 space-y-3">
                <Button
                  variant="outline"
                  className="w-full rounded-xl"
                  disabled={revoking}
                  onClick={() => void handleRevoke()}
                >
                  {revoking ? (
                    <>
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      Отзываем...
                    </>
                  ) : (
                    <>
                      <Ban className="mr-2 h-4 w-4" />
                      Отозвать доступы
                    </>
                  )}
                </Button>
                <Button className="w-full rounded-xl" variant="secondary" onClick={() => setSelectedConsent(null)}>
                  Закрыть
                </Button>
              </div>
            </>
          ) : null}
        </DialogContent>
      </Dialog>
    </IdShell>
  );
}
