'use client';

import { useCallback, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
  ChevronRight,
  Clock3,
  Fingerprint,
  KeyRound,
  Laptop,
  LogOut,
  Mail,
  Monitor,
  type LucideIcon,
  Phone,
  ShieldCheck,
  Smartphone,
  Speaker,
  Tv
} from 'lucide-react';
import { useAuth } from '@/components/id/auth-provider';
import { IdShell } from '@/components/id/shell';
import { useToast } from '@/components/id/toast-provider';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { ActiveDevice, apiFetch, SignInEvent } from '@/lib/api';
import { useRequireAuth } from '@/hooks/use-require-auth';

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

const deviceIcons: Record<string, LucideIcon> = {
  WEB: Monitor,
  DESKTOP: Monitor,
  IOS: Smartphone,
  ANDROID: Smartphone,
  TV: Tv,
  SMART_SPEAKER: Speaker,
  OTHER: Laptop
};

type DialogMode = 'pin' | 'password' | 'backupEmail' | 'backupPhone' | null;

const dialogConfig: Record<Exclude<DialogMode, null>, { title: string; placeholder: string; type: string }> = {
  pin: { title: 'Установить PIN-код', placeholder: 'PIN из 4-6 цифр', type: 'password' },
  password: { title: 'Установить пароль', placeholder: 'Новый пароль (мин. 8 символов)', type: 'password' },
  backupEmail: { title: 'Резервная почта', placeholder: 'backup@example.com', type: 'email' },
  backupPhone: { title: 'Резервный телефон', placeholder: '+79991234567', type: 'tel' }
};

export default function SecurityPage() {
  const router = useRouter();
  const { user, token, logout } = useAuth();
  const { isReady } = useRequireAuth();
  const { showToast } = useToast();
  const [devices, setDevices] = useState<ActiveDevice[]>([]);
  const [history, setHistory] = useState<SignInEvent[]>([]);
  const [isSecurityLoading, setIsSecurityLoading] = useState(true);
  const [isRevoking, setIsRevoking] = useState(false);
  const [dialogMode, setDialogMode] = useState<DialogMode>(null);
  const [dialogValue, setDialogValue] = useState('');
  const [isDialogSaving, setIsDialogSaving] = useState(false);

  const loadSecurity = useCallback(async () => {
    if (!user || !token) return;
    setIsSecurityLoading(true);
    try {
      const [devicesResponse, historyResponse] = await Promise.all([
        apiFetch<{ devices: ActiveDevice[] }>(`/security/users/${user.id}/devices`, {}, token),
        apiFetch<{ events: SignInEvent[] }>(`/security/users/${user.id}/sign-in-history`, {}, token)
      ]);
      setDevices(devicesResponse.devices ?? []);
      setHistory(historyResponse.events ?? []);
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось загрузить безопасность');
    } finally {
      setIsSecurityLoading(false);
    }
  }, [showToast, token, user]);

  useEffect(() => {
    if (!isReady || !user) return;
    void loadSecurity();
  }, [isReady, loadSecurity, user]);

  async function revokeDevice(deviceId: string) {
    if (!user || !token) return;
    try {
      await apiFetch(`/security/users/${user.id}/devices/${deviceId}/revoke`, { method: 'POST' }, token);
      setDevices((current) => current.filter((device) => device.id !== deviceId));
      showToast('Сессии устройства завершены');
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось завершить сессию');
    }
  }

  async function revokeAllSessions() {
    if (!user || !token) return;
    setIsRevoking(true);
    try {
      await apiFetch(`/security/users/${user.id}/revoke-all-sessions`, { method: 'POST' }, token);
      showToast('Все сессии завершены');
      logout();
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось выйти везде');
    } finally {
      setIsRevoking(false);
    }
  }

  async function submitDialog() {
    if (!user || !token || !dialogMode) return;
    setIsDialogSaving(true);
    try {
      if (dialogMode === 'pin') {
        await apiFetch(`/security/users/${user.id}/pin/setup`, { method: 'POST', body: JSON.stringify({ pin: dialogValue.trim() }) }, token);
        showToast('PIN-код установлен');
      } else if (dialogMode === 'password') {
        await apiFetch(`/profile/users/${user.id}/password`, { method: 'POST', body: JSON.stringify({ password: dialogValue }) }, token);
        showToast('Пароль установлен');
      } else if (dialogMode === 'backupEmail') {
        await apiFetch(`/profile/users/${user.id}/contacts`, { method: 'PATCH', body: JSON.stringify({ backupEmail: dialogValue.trim() }) }, token);
        showToast('Резервная почта добавлена');
      } else if (dialogMode === 'backupPhone') {
        await apiFetch(`/profile/users/${user.id}/contacts`, { method: 'PATCH', body: JSON.stringify({ backupPhone: dialogValue.trim() }) }, token);
        showToast('Резервный телефон добавлен');
      }
      setDialogMode(null);
      setDialogValue('');
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось сохранить');
    } finally {
      setIsDialogSaving(false);
    }
  }

  function openDialog(mode: Exclude<DialogMode, null>) {
    setDialogValue('');
    setDialogMode(mode);
  }

  return (
    <IdShell active="/security">
      <p className="text-sm text-[#667085]">Безопасность</p>
      <h1 className="text-4xl font-medium tracking-tight">Устройства</h1>
      <p className="mt-2 max-w-[460px] text-base">На них вы вошли в ID и получаете уведомления безопасности от сервисов</p>

      <div className="mt-8 space-y-2">
        {isSecurityLoading ? (
          <div className="rounded-[20px] bg-[#f4f5f8] px-4 py-5 text-[#667085]">Загружаем устройства...</div>
        ) : devices.length ? (
          devices.map((device) => {
            const Icon = deviceIcons[device.type] ?? Laptop;
            return (
              <div key={device.id} className="flex items-center gap-4 rounded-[20px] bg-[#f4f5f8] px-4 py-3">
                <div className="flex h-11 w-11 items-center justify-center rounded-2xl bg-white">
                  <Icon className="h-5 w-5" />
                </div>
                <div className="min-w-0 flex-1">
                  <span className="block truncate font-medium">{device.name}</span>
                  <span className="text-xs text-[#667085]">{device.lastIp ?? 'IP не сохранён'} · {formatDate(device.lastSeenAt)}</span>
                </div>
                <Button variant="ghost" size="sm" className="shrink-0 text-[#d14343] hover:bg-[#fbeaea]" onClick={() => revokeDevice(device.id)}>
                  Выйти
                </Button>
              </div>
            );
          })
        ) : (
          <div className="rounded-[20px] bg-[#f4f5f8] px-4 py-5 text-[#667085]">Активных устройств пока нет</div>
        )}
      </div>

      <div className="mt-6 space-y-1">
        <button type="button" onClick={revokeAllSessions} disabled={isRevoking || !user} className="flex w-full items-center gap-4 border-t border-[#eceef4] py-4 text-left disabled:opacity-60">
          <LogOut className="h-6 w-6" />
          <span>{isRevoking ? 'Выходим...' : 'Выйти везде'}</span>
        </button>
      </div>

      <section className="mt-10">
        <h2 className="text-2xl font-medium">Способ входа в профиль</h2>
        <div className="mt-4 space-y-2">
          <button type="button" onClick={() => openDialog('pin')} className="flex w-full items-center gap-4 rounded-[18px] bg-[#f8f9fb] p-4 text-left hover:bg-[#f1f2f6]">
            <Fingerprint className="h-5 w-5" />
            <div className="flex-1">
              <p className="font-medium">PIN-код</p>
              <p className="text-sm text-[#667085]">Установить или изменить PIN для входа</p>
            </div>
            <ChevronRight className="h-5 w-5 text-[#a8adbc]" />
          </button>
          <button type="button" onClick={() => openDialog('password')} className="flex w-full items-center gap-4 rounded-[18px] bg-[#f8f9fb] p-4 text-left hover:bg-[#f1f2f6]">
            <KeyRound className="h-5 w-5" />
            <div className="flex-1">
              <p className="font-medium">Пароль</p>
              <p className="text-sm text-[#667085]">{user?.email || user?.phone ? 'Добавить пароль как способ входа' : 'Установить пароль'}</p>
            </div>
            <ChevronRight className="h-5 w-5 text-[#a8adbc]" />
          </button>
        </div>
      </section>

      <section className="mt-10">
        <h2 className="text-2xl font-medium">Способы восстановления</h2>
        <div className="mt-4 space-y-2">
          <button type="button" onClick={() => openDialog('backupEmail')} className="flex w-full items-center gap-4 rounded-[18px] bg-[#f8f9fb] p-4 text-left hover:bg-[#f1f2f6]">
            <Mail className="h-5 w-5" />
            <div className="flex-1">
              <p className="font-medium">Резервная почта</p>
              <p className="text-sm text-[#667085]">{user?.backupEmail || 'Не добавлена'}</p>
            </div>
            <ChevronRight className="h-5 w-5 text-[#a8adbc]" />
          </button>
          <button type="button" onClick={() => openDialog('backupPhone')} className="flex w-full items-center gap-4 rounded-[18px] bg-[#f8f9fb] p-4 text-left hover:bg-[#f1f2f6]">
            <Phone className="h-5 w-5" />
            <div className="flex-1">
              <p className="font-medium">Резервный телефон</p>
              <p className="text-sm text-[#667085]">{user?.backupPhone || 'Не добавлен'}</p>
            </div>
            <ChevronRight className="h-5 w-5 text-[#a8adbc]" />
          </button>
        </div>
      </section>

      <section className="mt-10">
        <h2 className="text-2xl font-medium">Активность</h2>
        <div className="mt-4 space-y-3">
          {isSecurityLoading ? (
            <div className="text-[#667085]">Загружаем историю входов...</div>
          ) : history.length ? (
            history.map((item) => (
              <div key={item.id} className="flex items-center gap-4 border-b border-[#eceef4] pb-3">
                <Clock3 className="h-5 w-5" />
                <span className="flex-1">{item.success ? 'Успешный вход' : item.reason ?? 'Неудачная попытка входа'}</span>
                <span className="text-sm text-[#667085]">{formatDate(item.createdAt)}</span>
              </div>
            ))
          ) : (
            <div className="text-[#667085]">История входов пока пуста</div>
          )}
        </div>
      </section>

      <Dialog open={dialogMode !== null} onOpenChange={(open) => (open ? null : setDialogMode(null))}>
        <DialogContent>
          {dialogMode ? (
            <>
              <DialogHeader>
                <DialogTitle>{dialogConfig[dialogMode].title}</DialogTitle>
              </DialogHeader>
              <div className="flex items-center gap-3 rounded-2xl bg-[#f4f5f8] px-4">
                <ShieldCheck className="h-5 w-5 text-[#667085]" />
                <Input
                  className="border-0 bg-transparent focus:ring-0"
                  type={dialogConfig[dialogMode].type}
                  placeholder={dialogConfig[dialogMode].placeholder}
                  value={dialogValue}
                  onChange={(event) => setDialogValue(event.target.value)}
                />
              </div>
              <Button className="mt-5 w-full" onClick={submitDialog} disabled={isDialogSaving || !dialogValue.trim()}>
                {isDialogSaving ? 'Сохраняем...' : 'Сохранить'}
              </Button>
            </>
          ) : null}
        </DialogContent>
      </Dialog>
    </IdShell>
  );
}
