'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Car, ChevronRight, FileKey2, FileText, Loader2, Mail, Phone, Trash2, UserRound } from 'lucide-react';
import { AddressQuickSection } from '@/components/addresses/address-quick-section';
import { DocumentFormDialog } from '@/components/documents/document-form-dialog';
import { ActionTile } from '@/components/id/action-tile';
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 { AvatarDisplay, AvatarUpload } from '@/components/id/avatar-upload';
import { Input } from '@/components/ui/input';
import { DatePicker } from '@/components/ui/date-picker';
import { PhoneInput, parseE164Phone, phoneCountries, toE164 } from '@/components/ui/phone-input';
import { useRequireAuth } from '@/hooks/use-require-auth';
import {
  getDocumentType,
  indexDocumentsByType,
  type DocumentTypeCode
} from '@/lib/document-catalog';
import { apiFetch, getApiErrorMessage, cancelAccountDeletion, fetchAccountDeletionStatus, requestAccountDeletion, type AccountDeletionStatus, UserDocument, UserProfileResponse } from '@/lib/api';

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

function Row({
  icon: Icon,
  title,
  text,
  onClick,
  destructive
}: {
  icon: typeof Mail;
  title: string;
  text?: string;
  onClick?: () => void;
  destructive?: boolean;
}) {
  const content = (
    <>
      <div className={`flex h-11 w-11 items-center justify-center rounded-2xl ${destructive ? 'bg-red-50' : 'bg-[#f4f5f8]'}`}>
        <Icon className={`h-5 w-5 ${destructive ? 'text-red-500' : ''}`} />
      </div>
      <div className="min-w-0 flex-1">
        <div className={`font-medium ${destructive ? 'text-red-600' : ''}`}>{title}</div>
        {text ? <div className="truncate text-sm text-[#667085]">{text}</div> : null}
      </div>
      {onClick ? <ChevronRight className="h-5 w-5 text-[#a8adbc]" /> : null}
    </>
  );

  if (!onClick) {
    return <div className="flex items-center gap-4 border-b border-[#eceef4] py-4">{content}</div>;
  }

  return (
    <button
      type="button"
      onClick={onClick}
      className="flex w-full items-center gap-4 border-b border-[#eceef4] py-4 text-left transition hover:bg-[#fafbfd]"
    >
      {content}
    </button>
  );
}

export default function DataPage() {
  const router = useRouter();
  const { user, token, refreshProfile } = useAuth();
  const { isReady, isPinLocked } = useRequireAuth();
  const { showToast } = useToast();
  const [displayName, setDisplayName] = useState('');
  const [email, setEmail] = useState('');
  const [backupEmail, setBackupEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [backupPhone, setBackupPhone] = useState('');
  const [birthDate, setBirthDate] = useState<string | undefined>();
  const [phoneCountry, setPhoneCountry] = useState(phoneCountries[0]);
  const [phoneDigits, setPhoneDigits] = useState('');
  const [backupPhoneCountry, setBackupPhoneCountry] = useState(phoneCountries[0]);
  const [backupPhoneDigits, setBackupPhoneDigits] = useState('');
  const [documents, setDocuments] = useState<UserDocument[]>([]);
  const [isSaving, setIsSaving] = useState(false);
  const [activeDocumentType, setActiveDocumentType] = useState<DocumentTypeCode | null>(null);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [isDeleting, setIsDeleting] = useState(false);
  const [deletionStatus, setDeletionStatus] = useState<AccountDeletionStatus | null>(null);
  const [cancellingDeletion, setCancellingDeletion] = useState(false);

  const loadDocuments = useCallback(async () => {
    if (!user || !token || isPinLocked) return;
    try {
      const response = await apiFetch<{ documents?: UserDocument[] }>(`/documents/users/${user.id}`, {}, token);
      setDocuments(response.documents ?? []);
    } catch (error) {
      const message = getApiErrorMessage(error, 'Не удалось загрузить документы');
      if (message) showToast(message);
    }
  }, [isPinLocked, showToast, token, user]);

  useEffect(() => {
    if (!user) return;
    setDisplayName(user.displayName);
    setEmail(user.email ?? '');
    setBackupEmail(user.backupEmail ?? '');
    const parsedPhone = parseE164Phone(user.phone ?? '');
    setPhoneCountry(parsedPhone.country);
    setPhoneDigits(parsedPhone.digits);
    setPhone(parsedPhone.digits ? toE164(parsedPhone.country, parsedPhone.digits) : '');
    const parsedBackupPhone = parseE164Phone(user.backupPhone ?? '');
    setBackupPhoneCountry(parsedBackupPhone.country);
    setBackupPhoneDigits(parsedBackupPhone.digits);
    setBackupPhone(parsedBackupPhone.digits ? toE164(parsedBackupPhone.country, parsedBackupPhone.digits) : '');
  }, [user]);

  useEffect(() => {
    if (!user || !token || isPinLocked) return;
    void apiFetch<UserProfileResponse>(`/profile/users/${user.id}`, {}, token)
      .then((profile) => {
        if (profile.birthDate) setBirthDate(profile.birthDate);
      })
      .catch(() => undefined);
  }, [isPinLocked, token, user]);

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

  const loadDeletionStatus = useCallback(async () => {
    if (!user || !token || isPinLocked) return;
    try {
      const status = await fetchAccountDeletionStatus(user.id, token);
      setDeletionStatus(status);
    } catch {
      setDeletionStatus(null);
    }
  }, [isPinLocked, token, user]);

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

  const documentsByType = useMemo(() => indexDocumentsByType(documents), [documents]);

  function openDocument(type: DocumentTypeCode) {
    setActiveDocumentType(type);
  }

  async function updateProfile() {
    if (!user || !token) return;
    setIsSaving(true);
    const trimmedName = displayName.trim();
    const [firstName, ...rest] = trimmedName.split(' ');
    try {
      await apiFetch(`/profile/users/${user.id}`, {
        method: 'PATCH',
        body: JSON.stringify({
          firstName: firstName || undefined,
          lastName: rest.join(' ') || undefined,
          birthDate: birthDate || undefined
        })
      }, token);

      const contacts: Record<string, string> = {};
      const nextPhone = phoneDigits ? toE164(phoneCountry, phoneDigits) : '';
      const nextBackupPhone = backupPhoneDigits ? toE164(backupPhoneCountry, backupPhoneDigits) : '';
      if (email.trim() && email.trim() !== (user.email ?? '')) contacts.email = email.trim();
      if (nextPhone && nextPhone !== (user.phone ?? '')) contacts.phone = nextPhone;
      if (backupEmail.trim() && backupEmail.trim() !== (user.backupEmail ?? '')) contacts.backupEmail = backupEmail.trim();
      if (nextBackupPhone && nextBackupPhone !== (user.backupPhone ?? '')) contacts.backupPhone = nextBackupPhone;

      if (Object.keys(contacts).length > 0) {
        await apiFetch(`/profile/users/${user.id}/contacts`, {
          method: 'PATCH',
          body: JSON.stringify(contacts)
        }, token);
      }

      await refreshProfile();
      showToast('Профиль обновлён');
    } catch (error) {
      const message = getApiErrorMessage(error, 'Не удалось обновить профиль');
      if (message) showToast(message);
    } finally {
      setIsSaving(false);
    }
  }

  async function confirmDeleteProfile() {
    if (!user || !token) return;
    setIsDeleting(true);
    try {
      const response = await requestAccountDeletion(user.id, token);
      setDeletionStatus(response);
      setDeleteDialogOpen(false);
      showToast(
        response.effectiveAt
          ? `Удаление запланировано на ${formatDeletionDate(response.effectiveAt)}`
          : 'Удаление аккаунта запланировано'
      );
    } catch (error) {
      const message = getApiErrorMessage(error, 'Не удалось запланировать удаление профиля');
      if (message) showToast(message);
    } finally {
      setIsDeleting(false);
    }
  }

  async function handleCancelDeletion() {
    if (!user || !token) return;
    setCancellingDeletion(true);
    try {
      await cancelAccountDeletion(user.id, token);
      setDeletionStatus({ pending: false, graceDays: deletionStatus?.graceDays ?? 30 });
      showToast('Удаление аккаунта отменено');
    } catch (error) {
      const message = getApiErrorMessage(error, 'Не удалось отменить удаление');
      if (message) showToast(message);
    } finally {
      setCancellingDeletion(false);
    }
  }

  return (
    <IdShell active="/data">
      <div className="mb-8 flex items-center gap-4 rounded-[24px] border border-[#20212b] p-4">
        {user ? (
          <AvatarUpload
            userId={user.id}
            displayName={user.displayName}
            hasAvatar={user.hasAvatar}
            token={token}
            isVerified={user.isVerified}
            verificationIcon={user.verificationIcon}
            className="h-14 w-14"
            badgeSize="sm"
            onUpdated={refreshProfile}
          />
        ) : (
          <AvatarDisplay userId="" displayName="" hasAvatar={false} token={null} className="h-14 w-14" />
        )}
        <div className="flex-1">
          <h1 className="text-lg font-semibold">{user?.displayName ?? 'Профиль'}</h1>
          <p className="text-sm text-[#667085]">Логин: {user?.username ?? user?.email ?? user?.phone ?? 'не указан'}</p>
        </div>
      </div>

      <section>
        <h2 className="text-2xl font-medium">Личные данные</h2>
        <p className="mt-1 text-sm text-[#667085]">Эти данные помогают быстрее входить в сервисы и восстанавливать доступ.</p>
        <div className="mt-5 grid gap-3 sm:grid-cols-2">
          <Input placeholder="ФИО" value={displayName} onChange={(event) => setDisplayName(event.target.value)} />
          <DatePicker value={birthDate} onChange={setBirthDate} />
          <Input placeholder="Основная почта" value={email} onChange={(event) => setEmail(event.target.value)} />
          <Input placeholder="Резервная почта" value={backupEmail} onChange={(event) => setBackupEmail(event.target.value)} />
          <PhoneInput
            variant="light"
            country={phoneCountry}
            value={phoneDigits}
            onCountryChange={setPhoneCountry}
            onValueChange={(digits) => {
              setPhoneDigits(digits);
              setPhone(digits ? toE164(phoneCountry, digits) : '');
            }}
            required={false}
          />
          <PhoneInput
            variant="light"
            country={backupPhoneCountry}
            value={backupPhoneDigits}
            onCountryChange={setBackupPhoneCountry}
            onValueChange={(digits) => {
              setBackupPhoneDigits(digits);
              setBackupPhone(digits ? toE164(backupPhoneCountry, digits) : '');
            }}
            required={false}
          />
        </div>
        <Button className="mt-4" onClick={updateProfile} disabled={isSaving}>
          {isSaving ? 'Сохраняем...' : 'Обновить профиль'}
        </Button>
      </section>

      <section className="mt-10">
        <div className="flex items-center justify-between">
          <div>
            <h2 className="text-2xl font-medium">Документы</h2>
            <p className="mt-1 text-sm text-[#667085]">ID бережно хранит документы и подставляет их там, где вы разрешили.</p>
          </div>
          <Button variant="secondary" onClick={() => router.push('/documents')}>Все документы</Button>
        </div>
        <div className="mt-5 grid grid-cols-4 gap-3">
          <ActionTile icon={FileText} label="Паспорт РФ" onClick={() => openDocument('PASSPORT_RF')} />
          <ActionTile icon={FileText} label="Загран" onClick={() => openDocument('FOREIGN_PASSPORT')} />
          <ActionTile icon={Car} label="ВУ" onClick={() => openDocument('DRIVER_LICENSE')} />
          <ActionTile icon={FileText} label="ОМС" onClick={() => openDocument('OMS')} />
        </div>
        <div className="mt-4 overflow-hidden rounded-[24px] bg-[#f4f5f8]">
          {documents.length === 0 ? (
            <p className="px-4 py-6 text-center text-sm text-[#667085]">Документы пока не добавлены</p>
          ) : (
            documents.map((document) => {
              const config = getDocumentType(document.type);
              return (
                <Row
                  key={document.id}
                  icon={FileText}
                  title={config?.label ?? document.type}
                  text={document.number}
                  onClick={() => openDocument(document.type as DocumentTypeCode)}
                />
              );
            })
          )}
        </div>
      </section>

      <AddressQuickSection layout="data" isPinLocked={isPinLocked} isReady={isReady} />

      <section className="mt-10">
        <h2 className="text-2xl font-medium">Контакты</h2>
        <Row icon={Mail} title="Email в ID" text={email || 'Не указан'} />
        <Row icon={Phone} title="Основной телефон" text={phone || 'Не указан'} />
        <Row icon={Mail} title="Запасная почта" text={backupEmail || 'Не указана'} />
        <Row icon={UserRound} title="Добавить внешние аккаунты" text="Помогут быстрее входить и заполнить данные" />
      </section>

      <section className="mt-10">
        <h2 className="text-2xl font-medium">Управление данными</h2>
        <div className="mt-2 overflow-hidden rounded-[24px] bg-[#f4f5f8]">
          <Row
            icon={FileKey2}
            title="Доступы к данным"
            text="Приложения, которым вы разрешили доступ к аккаунту"
            onClick={() => router.push('/data/consents')}
          />
        </div>
        {deletionStatus?.pending && deletionStatus.effectiveAt ? (
          <div className="mt-4 rounded-[24px] border border-amber-200 bg-amber-50/80 p-5">
            <p className="font-medium text-amber-900">Удаление аккаунта запланировано</p>
            <p className="mt-2 text-sm leading-relaxed text-amber-800">
              Профиль будет окончательно удалён {formatDeletionDate(deletionStatus.effectiveAt)}. До этой даты вы
              можете пользоваться сервисом или отменить удаление.
            </p>
            <Button
              className="mt-4"
              variant="secondary"
              disabled={cancellingDeletion}
              onClick={() => void handleCancelDeletion()}
            >
              {cancellingDeletion ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Отменяем...
                </>
              ) : (
                'Отменить удаление'
              )}
            </Button>
          </div>
        ) : (
          <div className="mt-2 overflow-hidden rounded-[24px] border border-red-100 bg-red-50/40">
            <Row
              icon={Trash2}
              title="Удалить профиль"
              text="Аккаунт будет удалён после периода ожидания (настраивается администратором)"
              onClick={() => setDeleteDialogOpen(true)}
              destructive
            />
          </div>
        )}
      </section>

      {activeDocumentType && user ? (
        <DocumentFormDialog
          open={Boolean(activeDocumentType)}
          onOpenChange={(open) => {
            if (!open) setActiveDocumentType(null);
          }}
          documentType={activeDocumentType}
          userId={user.id}
          token={token}
          existing={documentsByType.get(activeDocumentType) ?? null}
          onSaved={loadDocuments}
        />
      ) : null}

      <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
        <DialogContent className="rounded-[28px] sm:max-w-[440px]">
          <DialogHeader>
            <DialogTitle>Удалить профиль?</DialogTitle>
          </DialogHeader>
          <p className="text-sm leading-relaxed text-[#667085]">
            Аккаунт не удалится сразу. После подтверждения начнётся период ожидания (по умолчанию 30 дней — срок
            задаётся в настройках администратора). По истечении срока профиль будет окончательно удалён: контакты и
            логин освободятся, семьи и чаты будут удалены или покинууты, сессии завершены. До этого момента удаление
            можно отменить на этой странице.
          </p>
          <div className="mt-6 flex gap-3">
            <Button variant="secondary" className="flex-1" onClick={() => setDeleteDialogOpen(false)} disabled={isDeleting}>
              Отмена
            </Button>
            <Button className="flex-1 bg-red-600 hover:bg-red-700" onClick={() => void confirmDeleteProfile()} disabled={isDeleting}>
              {isDeleting ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Удаляем...
                </>
              ) : (
                'Запланировать удаление'
              )}
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </IdShell>
  );
}
