'use client';

import { useMemo, useState } from 'react';
import { CalendarDays, ImageIcon, Loader2, Search } from 'lucide-react';
import { Calendar } from '@/components/ui/calendar';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import type { ChatMessage } from '@/lib/api';
import { getChatDateKey } from '@/lib/chat-date-utils';
import { getMessagePreviewText } from '@/lib/chat-message-utils';
import { cn } from '@/lib/utils';

export type ChatToolsTab = 'search' | 'calendar' | 'media';

interface ChatToolsDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  messages: ChatMessage[];
  defaultTab?: ChatToolsTab;
  getMessagePreview: (message: ChatMessage) => string;
  getMediaUrl?: (message: ChatMessage) => string | null;
  onJumpToMessage: (messageId: string) => void;
}

export function ChatToolsDialog({
  open,
  onOpenChange,
  messages,
  defaultTab = 'search',
  getMessagePreview,
  getMediaUrl,
  onJumpToMessage
}: ChatToolsDialogProps) {
  const [tab, setTab] = useState<ChatToolsTab>(defaultTab);
  const [query, setQuery] = useState('');
  const [selectedDate, setSelectedDate] = useState<Date | undefined>();

  const messageDates = useMemo(() => {
    const keys = new Set<string>();
    for (const message of messages) {
      keys.add(getChatDateKey(message.createdAt));
    }
    return keys;
  }, [messages]);

  const searchResults = useMemo(() => {
    const normalized = query.trim().toLowerCase();
    if (!normalized) return [];
    return messages.filter((message) => getMessagePreview(message).toLowerCase().includes(normalized));
  }, [getMessagePreview, messages, query]);

  const mediaMessages = useMemo(
    () => messages.filter((message) => message.type === 'IMAGE' && message.storageKey),
    [messages]
  );

  const calendarModifiers = useMemo(
    () => ({
      hasMessages: (date: Date) => messageDates.has(getChatDateKey(date))
    }),
    [messageDates]
  );

  function jumpToDate(date: Date) {
    const key = getChatDateKey(date);
    const target = messages.find((message) => getChatDateKey(message.createdAt) === key);
    if (!target) return;
    onJumpToMessage(target.id);
    onOpenChange(false);
  }

  function handleOpenChange(next: boolean) {
    onOpenChange(next);
    if (next) setTab(defaultTab);
  }

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent className="max-h-[85vh] overflow-hidden rounded-[28px] sm:max-w-[520px]">
        <DialogHeader>
          <DialogTitle>Чат</DialogTitle>
        </DialogHeader>

        <div className="flex gap-1 rounded-xl bg-[#f4f5f8] p-1">
          {(
            [
              { id: 'search' as const, label: 'Поиск', icon: Search },
              { id: 'calendar' as const, label: 'Дата', icon: CalendarDays },
              { id: 'media' as const, label: 'Медиа', icon: ImageIcon }
            ] as const
          ).map((item) => (
            <button
              key={item.id}
              type="button"
              onClick={() => setTab(item.id)}
              className={cn(
                'flex flex-1 items-center justify-center gap-1.5 rounded-lg px-2 py-2 text-xs font-medium transition',
                tab === item.id ? 'bg-white text-[#1f2430] shadow-sm' : 'text-[#667085] hover:text-[#1f2430]'
              )}
            >
              <item.icon className="h-3.5 w-3.5" />
              {item.label}
            </button>
          ))}
        </div>

        <div className="max-h-[min(52vh,420px)] overflow-y-auto pt-1">
          {tab === 'search' ? (
            <div className="space-y-3">
              <div className="relative">
                <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#a8adbc]" />
                <Input
                  value={query}
                  onChange={(event) => setQuery(event.target.value)}
                  placeholder="Поиск по сообщениям"
                  className="rounded-xl pl-9"
                />
              </div>
              {!query.trim() ? (
                <p className="py-6 text-center text-sm text-[#667085]">Введите текст для поиска</p>
              ) : searchResults.length ? (
                <div className="space-y-1">
                  {searchResults.map((message) => (
                    <button
                      key={message.id}
                      type="button"
                      className="flex w-full flex-col rounded-xl px-3 py-2 text-left transition hover:bg-[#f4f5f8]"
                      onClick={() => {
                        onJumpToMessage(message.id);
                        onOpenChange(false);
                      }}
                    >
                      <span className="text-xs font-medium text-[#3390ec]">{message.senderName}</span>
                      <span className="truncate text-sm text-[#1f2430]">{getMessagePreview(message)}</span>
                      <span className="text-[11px] text-[#a8adbc]">
                        {new Intl.DateTimeFormat('ru-RU', {
                          day: '2-digit',
                          month: '2-digit',
                          year: 'numeric',
                          hour: '2-digit',
                          minute: '2-digit'
                        }).format(new Date(message.createdAt))}
                      </span>
                    </button>
                  ))}
                </div>
              ) : (
                <p className="py-6 text-center text-sm text-[#667085]">Ничего не найдено</p>
              )}
            </div>
          ) : null}

          {tab === 'calendar' ? (
            <div className="space-y-3">
              <Calendar
                mode="single"
                selected={selectedDate}
                onSelect={(date) => {
                  setSelectedDate(date);
                  if (date) jumpToDate(date);
                }}
                modifiers={calendarModifiers}
                modifiersClassNames={{
                  hasMessages: 'relative after:absolute after:bottom-1 after:left-1/2 after:h-1 after:w-1 after:-translate-x-1/2 after:rounded-full after:bg-[#3390ec]'
                }}
              />
              <div className="space-y-1">
                <label className="text-xs font-medium text-[#667085]">Перейти к дате</label>
                <Input
                  type="date"
                  onChange={(event) => {
                    if (!event.target.value) return;
                    jumpToDate(new Date(`${event.target.value}T12:00:00`));
                  }}
                />
              </div>
              <p className="text-xs text-[#667085]">Точки под датами означают наличие сообщений в этот день</p>
            </div>
          ) : null}

          {tab === 'media' ? (
            mediaMessages.length ? (
              <div className="grid grid-cols-3 gap-2">
                {mediaMessages.map((message) => {
                  const url = getMediaUrl?.(message);
                  return (
                    <button
                      key={message.id}
                      type="button"
                      className="relative aspect-square overflow-hidden rounded-xl bg-[#eef1f6]"
                      onClick={() => {
                        onJumpToMessage(message.id);
                        onOpenChange(false);
                      }}
                    >
                      {url ? (
                        // eslint-disable-next-line @next/next/no-img-element
                        <img src={url} alt="" className="h-full w-full object-cover" />
                      ) : (
                        <div className="flex h-full items-center justify-center">
                          <Loader2 className="h-5 w-5 animate-spin text-[#667085]" />
                        </div>
                      )}
                    </button>
                  );
                })}
              </div>
            ) : (
              <p className="py-8 text-center text-sm text-[#667085]">Медиафайлов пока нет</p>
            )
          ) : null}
        </div>
      </DialogContent>
    </Dialog>
  );
}

export function buildMessagePreview(message: ChatMessage, visibleText?: string) {
  return getMessagePreviewText(message, visibleText);
}
