'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import {
  Activity,
  CheckCircle2,
  Loader2,
  MessageSquare,
  Search,
  ShieldAlert,
  Trash2,
  XCircle
} from 'lucide-react';
import { VerificationBadge } from '@/components/id/verification-badge';
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 { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  AdminChatMessage,
  AdminChatRoomSummary,
  AdminUser,
  AdminUserActivityItem,
  SignInEvent,
  apiFetch
} from '@/lib/api';
import { cn } from '@/lib/utils';

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

function useDebouncedValue<T>(value: T, delayMs = 350) {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => {
    const timer = window.setTimeout(() => setDebounced(value), delayMs);
    return () => window.clearTimeout(timer);
  }, [delayMs, value]);
  return debounced;
}

const roomTypeLabels: Record<string, string> = {
  GENERAL: 'Общий',
  DIRECT: 'Личный',
  GROUP: 'Группа'
};

export function UserInspectorDialog({
  user,
  token,
  canModerateChats,
  open,
  onOpenChange
}: {
  user: AdminUser | null;
  token: string | null;
  canModerateChats: boolean;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const { showToast } = useToast();
  const [tab, setTab] = useState('sign-in');

  const [signInSearch, setSignInSearch] = useState('');
  const [activitySearch, setActivitySearch] = useState('');
  const [chatSearch, setChatSearch] = useState('');
  const [messageSearch, setMessageSearch] = useState('');
  const [globalMessageSearch, setGlobalMessageSearch] = useState('');

  const debouncedSignInSearch = useDebouncedValue(signInSearch);
  const debouncedActivitySearch = useDebouncedValue(activitySearch);
  const debouncedChatSearch = useDebouncedValue(chatSearch);
  const debouncedMessageSearch = useDebouncedValue(messageSearch);
  const debouncedGlobalMessageSearch = useDebouncedValue(globalMessageSearch);

  const [signInEvents, setSignInEvents] = useState<SignInEvent[]>([]);
  const [signInTotal, setSignInTotal] = useState(0);
  const [activityItems, setActivityItems] = useState<AdminUserActivityItem[]>([]);
  const [activityTotal, setActivityTotal] = useState(0);
  const [rooms, setRooms] = useState<AdminChatRoomSummary[]>([]);
  const [roomsTotal, setRoomsTotal] = useState(0);
  const [selectedRoomId, setSelectedRoomId] = useState<string | null>(null);
  const [roomMessages, setRoomMessages] = useState<AdminChatMessage[]>([]);
  const [roomContext, setRoomContext] = useState<{ name: string; groupName: string; type: string } | null>(null);
  const [searchResults, setSearchResults] = useState<AdminChatMessage[]>([]);
  const [searchTotal, setSearchTotal] = useState(0);

  const [loadingSignIn, setLoadingSignIn] = useState(false);
  const [loadingActivity, setLoadingActivity] = useState(false);
  const [loadingRooms, setLoadingRooms] = useState(false);
  const [loadingMessages, setLoadingMessages] = useState(false);
  const [loadingSearch, setLoadingSearch] = useState(false);
  const [deletingMessageId, setDeletingMessageId] = useState<string | null>(null);

  const selectedRoom = useMemo(() => rooms.find((room) => room.id === selectedRoomId) ?? null, [rooms, selectedRoomId]);

  const loadSignIn = useCallback(async () => {
    if (!token || !user) return;
    setLoadingSignIn(true);
    try {
      const params = new URLSearchParams();
      if (debouncedSignInSearch.trim()) params.set('search', debouncedSignInSearch.trim());
      params.set('limit', '50');
      const response = await apiFetch<{ total: number; events: SignInEvent[] }>(
        `/admin/users/${user.id}/sign-in-history?${params.toString()}`,
        {},
        token
      );
      setSignInEvents(response.events ?? []);
      setSignInTotal(response.total ?? 0);
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось загрузить историю входов');
    } finally {
      setLoadingSignIn(false);
    }
  }, [debouncedSignInSearch, showToast, token, user]);

  const loadActivity = useCallback(async () => {
    if (!token || !user) return;
    setLoadingActivity(true);
    try {
      const params = new URLSearchParams();
      if (debouncedActivitySearch.trim()) params.set('search', debouncedActivitySearch.trim());
      params.set('limit', '50');
      const response = await apiFetch<{ total: number; items: AdminUserActivityItem[] }>(
        `/admin/users/${user.id}/activity?${params.toString()}`,
        {},
        token
      );
      setActivityItems(response.items ?? []);
      setActivityTotal(response.total ?? 0);
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось загрузить активность');
    } finally {
      setLoadingActivity(false);
    }
  }, [debouncedActivitySearch, showToast, token, user]);

  const loadRooms = useCallback(async () => {
    if (!token || !user || !canModerateChats) return;
    setLoadingRooms(true);
    try {
      const params = new URLSearchParams();
      if (debouncedChatSearch.trim()) params.set('search', debouncedChatSearch.trim());
      params.set('limit', '50');
      const response = await apiFetch<{ total: number; rooms: AdminChatRoomSummary[] }>(
        `/admin/users/${user.id}/chats?${params.toString()}`,
        {},
        token
      );
      setRooms(response.rooms ?? []);
      setRoomsTotal(response.total ?? 0);
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось загрузить чаты');
    } finally {
      setLoadingRooms(false);
    }
  }, [canModerateChats, debouncedChatSearch, showToast, token, user]);

  const loadRoomMessages = useCallback(async () => {
    if (!token || !user || !selectedRoomId) return;
    setLoadingMessages(true);
    try {
      const params = new URLSearchParams();
      if (debouncedMessageSearch.trim()) params.set('search', debouncedMessageSearch.trim());
      params.set('limit', '80');
      const response = await apiFetch<{
        room?: { id: string; name: string; type: string; groupName: string };
        messages: AdminChatMessage[];
      }>(`/admin/users/${user.id}/chats/${selectedRoomId}/messages?${params.toString()}`, {}, token);
      setRoomMessages(response.messages ?? []);
      setRoomContext(
        response.room
          ? { name: response.room.name, groupName: response.room.groupName, type: response.room.type }
          : null
      );
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось загрузить сообщения');
    } finally {
      setLoadingMessages(false);
    }
  }, [debouncedMessageSearch, selectedRoomId, showToast, token, user]);

  const loadGlobalSearch = useCallback(async () => {
    if (!token || !user || !canModerateChats || !debouncedGlobalMessageSearch.trim()) {
      setSearchResults([]);
      setSearchTotal(0);
      return;
    }
    setLoadingSearch(true);
    try {
      const params = new URLSearchParams();
      params.set('search', debouncedGlobalMessageSearch.trim());
      params.set('limit', '50');
      const response = await apiFetch<{ total: number; messages: AdminChatMessage[] }>(
        `/admin/users/${user.id}/chats/search?${params.toString()}`,
        {},
        token
      );
      setSearchResults(response.messages ?? []);
      setSearchTotal(response.total ?? 0);
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось выполнить поиск');
    } finally {
      setLoadingSearch(false);
    }
  }, [canModerateChats, debouncedGlobalMessageSearch, showToast, token, user]);

  useEffect(() => {
    if (!open || !user) return;
    if (tab === 'sign-in') void loadSignIn();
  }, [loadSignIn, open, tab, user]);

  useEffect(() => {
    if (!open || !user) return;
    if (tab === 'activity') void loadActivity();
  }, [loadActivity, open, tab, user]);

  useEffect(() => {
    if (!open || !user || !canModerateChats) return;
    if (tab === 'chats') void loadRooms();
  }, [canModerateChats, loadRooms, open, tab, user]);

  useEffect(() => {
    if (!open || !user || !selectedRoomId) return;
    void loadRoomMessages();
  }, [loadRoomMessages, open, selectedRoomId, user]);

  useEffect(() => {
    if (!open || !user || tab !== 'chats') return;
    void loadGlobalSearch();
  }, [loadGlobalSearch, open, tab, user]);

  useEffect(() => {
    if (!open) {
      setTab('sign-in');
      setSignInSearch('');
      setActivitySearch('');
      setChatSearch('');
      setMessageSearch('');
      setGlobalMessageSearch('');
      setSelectedRoomId(null);
      setRoomMessages([]);
      setSearchResults([]);
    }
  }, [open]);

  async function handleDeleteMessage(messageId: string) {
    if (!token || !user || !canModerateChats) return;
    const confirmed = window.confirm('Удалить это сообщение? Действие необратимо для пользователей чата.');
    if (!confirmed) return;
    setDeletingMessageId(messageId);
    try {
      await apiFetch(`/admin/users/${user.id}/chat-messages/${messageId}`, { method: 'DELETE' }, token);
      setRoomMessages((prev) => prev.filter((item) => item.id !== messageId));
      setSearchResults((prev) => prev.filter((item) => item.id !== messageId));
      showToast('Сообщение удалено');
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось удалить сообщение');
    } finally {
      setDeletingMessageId(null);
    }
  }

  if (!user) return null;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="flex max-h-[90vh] w-[min(960px,calc(100vw-2rem))] flex-col gap-0 overflow-hidden p-0">
        <DialogHeader className="border-b border-[#eceef4] px-6 py-5">
          <DialogTitle className="flex items-center gap-3 text-left text-xl font-semibold">
            <span>{user.displayName}</span>
            {user.isVerified ? <VerificationBadge verificationIcon={user.verificationIcon} size="sm" /> : null}
          </DialogTitle>
          <p className="text-left text-sm text-[#667085]">
            {[user.email, user.phone, user.username].filter(Boolean).join(' · ') || 'Контакты не указаны'}
          </p>
        </DialogHeader>

        <Tabs value={tab} onValueChange={setTab} className="flex min-h-0 flex-1 flex-col">
          <div className="border-b border-[#eceef4] px-6 pt-4">
            <TabsList className="grid w-full grid-cols-3">
              <TabsTrigger value="sign-in" className="gap-2">
                <ShieldAlert className="h-4 w-4" />
                Входы
              </TabsTrigger>
              <TabsTrigger value="activity" className="gap-2">
                <Activity className="h-4 w-4" />
                Активность
              </TabsTrigger>
              <TabsTrigger value="chats" className="gap-2" disabled={!canModerateChats}>
                <MessageSquare className="h-4 w-4" />
                Чаты
              </TabsTrigger>
            </TabsList>
          </div>

          <TabsContent value="sign-in" className="mt-0 flex min-h-0 flex-1 flex-col gap-4 overflow-hidden px-6 py-4">
            <div className="relative">
              <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#667085]" />
              <Input
                value={signInSearch}
                onChange={(event) => setSignInSearch(event.target.value)}
                placeholder="Поиск по IP, устройству, user-agent, причине..."
                className="pl-10"
              />
            </div>
            <p className="text-xs text-[#667085]">Найдено: {signInTotal}</p>
            <div className="min-h-0 flex-1 overflow-y-auto rounded-2xl border border-[#eceef4]">
              {loadingSignIn ? (
                <div className="flex items-center justify-center gap-2 py-16 text-[#667085]">
                  <Loader2 className="h-5 w-5 animate-spin" />
                  Загрузка...
                </div>
              ) : signInEvents.length ? (
                <div className="divide-y divide-[#eceef4]">
                  {signInEvents.map((event) => (
                    <div key={event.id} className="flex gap-3 px-4 py-3">
                      {event.success ? (
                        <CheckCircle2 className="mt-0.5 h-5 w-5 shrink-0 text-emerald-600" />
                      ) : (
                        <XCircle className="mt-0.5 h-5 w-5 shrink-0 text-red-500" />
                      )}
                      <div className="min-w-0 flex-1">
                        <div className="flex flex-wrap items-center gap-2">
                          <span className="font-medium">{event.success ? 'Успешный вход' : 'Неудачная попытка'}</span>
                          <span className="text-xs text-[#667085]">{formatDateTime(event.createdAt)}</span>
                        </div>
                        <p className="mt-1 text-sm text-[#667085]">
                          {[event.deviceName, event.ipAddress].filter(Boolean).join(' · ') || 'Устройство не определено'}
                        </p>
                        {event.reason ? <p className="mt-1 text-sm text-red-600">{event.reason}</p> : null}
                        {event.userAgent ? (
                          <p className="mt-1 truncate text-xs text-[#98a2b3]" title={event.userAgent}>
                            {event.userAgent}
                          </p>
                        ) : null}
                      </div>
                    </div>
                  ))}
                </div>
              ) : (
                <p className="py-16 text-center text-sm text-[#667085]">События входа не найдены</p>
              )}
            </div>
          </TabsContent>

          <TabsContent value="activity" className="mt-0 flex min-h-0 flex-1 flex-col gap-4 overflow-hidden px-6 py-4">
            <div className="relative">
              <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#667085]" />
              <Input
                value={activitySearch}
                onChange={(event) => setActivitySearch(event.target.value)}
                placeholder="Поиск по действиям, документам, чатам, OAuth..."
                className="pl-10"
              />
            </div>
            <p className="text-xs text-[#667085]">Найдено: {activityTotal}</p>
            <div className="min-h-0 flex-1 overflow-y-auto rounded-2xl border border-[#eceef4]">
              {loadingActivity ? (
                <div className="flex items-center justify-center gap-2 py-16 text-[#667085]">
                  <Loader2 className="h-5 w-5 animate-spin" />
                  Загрузка...
                </div>
              ) : activityItems.length ? (
                <div className="divide-y divide-[#eceef4]">
                  {activityItems.map((item) => (
                    <div key={item.id} className="px-4 py-3">
                      <div className="flex flex-wrap items-center gap-2">
                        <span className="font-medium">{item.title}</span>
                        <span className="rounded-full bg-[#f4f5f8] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-[#667085]">
                          {item.action}
                        </span>
                        <span className="text-xs text-[#667085]">{formatDateTime(item.createdAt)}</span>
                      </div>
                      {item.detail ? <p className="mt-1 text-sm text-[#667085]">{item.detail}</p> : null}
                    </div>
                  ))}
                </div>
              ) : (
                <p className="py-16 text-center text-sm text-[#667085]">Активность не найдена</p>
              )}
            </div>
          </TabsContent>

          <TabsContent value="chats" className="mt-0 flex min-h-0 flex-1 flex-col gap-4 overflow-hidden px-6 py-4">
            {!canModerateChats ? (
              <p className="py-8 text-center text-sm text-[#667085]">Недостаточно прав для модерации чатов</p>
            ) : (
              <>
                <div className="relative">
                  <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#667085]" />
                  <Input
                    value={globalMessageSearch}
                    onChange={(event) => setGlobalMessageSearch(event.target.value)}
                    placeholder="Глобальный поиск по сообщениям пользователя..."
                    className="pl-10"
                  />
                </div>
                {debouncedGlobalMessageSearch.trim() ? (
                  <div className="rounded-2xl border border-[#eceef4] bg-[#fafbff] p-3">
                    <p className="mb-2 text-xs font-medium text-[#667085]">
                      Результаты поиска по сообщениям: {searchTotal}
                    </p>
                    {loadingSearch ? (
                      <div className="flex items-center gap-2 py-4 text-sm text-[#667085]">
                        <Loader2 className="h-4 w-4 animate-spin" />
                        Поиск...
                      </div>
                    ) : searchResults.length ? (
                      <div className="max-h-40 space-y-2 overflow-y-auto">
                        {searchResults.map((message) => (
                          <button
                            key={message.id}
                            type="button"
                            className="flex w-full items-start gap-3 rounded-xl bg-white px-3 py-2 text-left hover:bg-[#f4f5f8]"
                            onClick={() => {
                              if (message.roomId) setSelectedRoomId(message.roomId);
                            }}
                          >
                            <div className="min-w-0 flex-1">
                              <p className="text-xs text-[#667085]">
                                {message.roomName} · {message.groupName} · {formatDateTime(message.createdAt)}
                              </p>
                              <p className="text-sm">
                                <span className="font-medium">{message.senderName}: </span>
                                {message.preview}
                              </p>
                            </div>
                          </button>
                        ))}
                      </div>
                    ) : (
                      <p className="py-2 text-sm text-[#667085]">Сообщения не найдены</p>
                    )}
                  </div>
                ) : null}

                <div className="grid min-h-0 flex-1 gap-4 lg:grid-cols-[280px_minmax(0,1fr)]">
                  <div className="flex min-h-0 flex-col gap-3">
                    <div className="relative">
                      <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#667085]" />
                      <Input
                        value={chatSearch}
                        onChange={(event) => setChatSearch(event.target.value)}
                        placeholder="Поиск чатов..."
                        className="pl-10"
                      />
                    </div>
                    <p className="text-xs text-[#667085]">Чатов: {roomsTotal}. E2E и боты скрыты.</p>
                    <div className="min-h-0 flex-1 overflow-y-auto rounded-2xl border border-[#eceef4]">
                      {loadingRooms ? (
                        <div className="flex items-center justify-center gap-2 py-10 text-[#667085]">
                          <Loader2 className="h-4 w-4 animate-spin" />
                        </div>
                      ) : rooms.length ? (
                        <div className="divide-y divide-[#eceef4]">
                          {rooms.map((room) => (
                            <button
                              key={room.id}
                              type="button"
                              onClick={() => setSelectedRoomId(room.id)}
                              className={cn(
                                'w-full px-3 py-3 text-left transition hover:bg-[#f8f9fb]',
                                selectedRoomId === room.id && 'bg-[#eef4ff]'
                              )}
                            >
                              <div className="flex items-center justify-between gap-2">
                                <span className="truncate font-medium">{room.name}</span>
                                <span className="shrink-0 rounded-full bg-[#f4f5f8] px-2 py-0.5 text-[10px] font-semibold text-[#667085]">
                                  {roomTypeLabels[room.type] ?? room.type}
                                </span>
                              </div>
                              <p className="mt-1 truncate text-xs text-[#667085]">{room.groupName}</p>
                              {room.lastMessage ? (
                                <p className="mt-1 truncate text-xs text-[#98a2b3]">{room.lastMessage.preview}</p>
                              ) : null}
                            </button>
                          ))}
                        </div>
                      ) : (
                        <p className="px-3 py-10 text-center text-sm text-[#667085]">Чаты не найдены</p>
                      )}
                    </div>
                  </div>

                  <div className="flex min-h-0 flex-col gap-3">
                    <div className="rounded-2xl border border-[#eceef4] bg-[#fafbff] px-4 py-3">
                      <p className="font-medium">{selectedRoom?.name ?? 'Выберите чат'}</p>
                      <p className="text-xs text-[#667085]">
                        {roomContext
                          ? `${roomContext.groupName} · ${roomTypeLabels[roomContext.type] ?? roomContext.type}`
                          : selectedRoom
                            ? `${selectedRoom.groupName} · ${selectedRoom.memberCount} участников`
                            : 'Обычные чаты доступны для модерации'}
                      </p>
                    </div>
                    <div className="relative">
                      <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#667085]" />
                      <Input
                        value={messageSearch}
                        onChange={(event) => setMessageSearch(event.target.value)}
                        placeholder="Поиск в выбранном чате..."
                        className="pl-10"
                        disabled={!selectedRoomId}
                      />
                    </div>
                    <div className="min-h-0 flex-1 overflow-y-auto rounded-2xl border border-[#eceef4] bg-white">
                      {!selectedRoomId ? (
                        <p className="py-16 text-center text-sm text-[#667085]">Выберите чат слева</p>
                      ) : loadingMessages ? (
                        <div className="flex items-center justify-center gap-2 py-16 text-[#667085]">
                          <Loader2 className="h-5 w-5 animate-spin" />
                          Загрузка сообщений...
                        </div>
                      ) : roomMessages.length ? (
                        <div className="space-y-2 p-3">
                          {roomMessages.map((message) => (
                            <div
                              key={message.id}
                              className={cn(
                                'rounded-2xl border px-3 py-2',
                                message.isDeleted ? 'border-red-100 bg-red-50' : 'border-[#eceef4] bg-[#fafbff]'
                              )}
                            >
                              <div className="flex items-start justify-between gap-3">
                                <div className="min-w-0">
                                  <div className="flex flex-wrap items-center gap-2">
                                    <span className="text-sm font-medium">{message.senderName}</span>
                                    <span className="text-xs text-[#667085]">{formatDateTime(message.createdAt)}</span>
                                    {message.isDeleted ? (
                                      <span className="text-xs font-medium text-red-600">Удалено</span>
                                    ) : null}
                                  </div>
                                  <p className="mt-1 whitespace-pre-wrap break-words text-sm text-[#344054]">
                                    {message.isEncrypted ? '[E2E недоступно для модерации]' : message.preview}
                                  </p>
                                </div>
                                {!message.isDeleted && !message.isEncrypted ? (
                                  <Button
                                    type="button"
                                    variant="ghost"
                                    size="icon"
                                    className="shrink-0 text-red-600 hover:bg-red-50 hover:text-red-700"
                                    disabled={deletingMessageId === message.id}
                                    aria-label="Удалить сообщение"
                                    onClick={() => void handleDeleteMessage(message.id)}
                                  >
                                    {deletingMessageId === message.id ? (
                                      <Loader2 className="h-4 w-4 animate-spin" />
                                    ) : (
                                      <Trash2 className="h-4 w-4" />
                                    )}
                                  </Button>
                                ) : null}
                              </div>
                            </div>
                          ))}
                        </div>
                      ) : (
                        <p className="py-16 text-center text-sm text-[#667085]">Сообщения не найдены</p>
                      )}
                    </div>
                  </div>
                </div>
              </>
            )}
          </TabsContent>
        </Tabs>
      </DialogContent>
    </Dialog>
  );
}
