"use client";

import { useEffect, useRef, useState } from "react";

import { ChatComposer } from "@/components/chat/chat-composer";
import { ChatEmptyState } from "@/components/chat/chat-empty-state";
import { ChatHeader } from "@/components/chat/chat-header";
import { ChatMessageList } from "@/components/chat/chat-message-list";
import { ChatSidebar } from "@/components/chat/chat-sidebar";
import { useChat } from "@/hooks/use-chat";
import { useModels } from "@/hooks/use-models";
import type { AuthIdentity } from "@/lib/auth/types";

type ChatAppProps = {
  user: AuthIdentity;
  onLogout: () => void;
};

export function ChatApp({ user, onLogout }: ChatAppProps) {
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const mobileDrawerRef = useRef<HTMLElement>(null);
  const previousFocusRef = useRef<HTMLElement | null>(null);
  const catalog = useModels(user.id, user.lastModelId, onLogout);
  const chat = useChat(user.id, onLogout, user.lastModelId);
  const { activeModelId, setModel } = chat;
  const sidebarProps = {
    activeConversationId: chat.activeConversation?.id ?? null,
    conversations: chat.conversations,
    onDeleteConversation: chat.deleteConversation,
    onLogout,
    onNewConversation: chat.newConversation,
    onSelectConversation: chat.selectConversation,
    user,
  };

  useEffect(() => {
    if (
      catalog.status !== "loading" &&
      !catalog.models.some((model) => model.id === activeModelId)
    ) {
      setModel(catalog.effectiveModelId);
    }
  }, [activeModelId, catalog.effectiveModelId, catalog.models, catalog.status, setModel]);

  useEffect(() => {
    if (!mobileMenuOpen) return;
    const drawer = mobileDrawerRef.current;
    const focusable = drawer?.querySelectorAll<HTMLElement>(
      'button:not([disabled]), input:not([disabled]), textarea:not([disabled]), [href], [tabindex]:not([tabindex="-1"])',
    );
    focusable?.[0]?.focus();

    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === "Escape") {
        event.preventDefault();
        setMobileMenuOpen(false);
        return;
      }
      if (event.key !== "Tab" || !focusable?.length) return;

      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      if (event.shiftKey && document.activeElement === first) {
        event.preventDefault();
        last.focus();
      } else if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault();
        first.focus();
      }
    }

    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.removeEventListener("keydown", handleKeyDown);
      previousFocusRef.current?.focus();
    };
  }, [mobileMenuOpen]);

  useEffect(() => {
    if (typeof window.matchMedia !== "function") return;
    const desktopQuery = window.matchMedia("(min-width: 768px)");

    function closeMobileDrawer(event: MediaQueryListEvent) {
      if (!event.matches) return;
      previousFocusRef.current = null;
      setMobileMenuOpen(false);
    }

    desktopQuery.addEventListener("change", closeMobileDrawer);
    return () => desktopQuery.removeEventListener("change", closeMobileDrawer);
  }, []);

  return (
    <main className="flex h-screen min-h-0 overflow-hidden bg-background">
      <aside
        className="hidden w-[272px] shrink-0 border-r border-sidebar-border md:block"
        inert={mobileMenuOpen ? true : undefined}
      >
        <ChatSidebar {...sidebarProps} />
      </aside>

      {mobileMenuOpen ? (
        <div className="fixed inset-0 z-40 md:hidden">
          <button
            aria-label="Закрыть меню"
            className="chat-overlay absolute inset-0 bg-foreground/25"
            onClick={() => setMobileMenuOpen(false)}
            type="button"
          />
          <aside
            aria-label="История чатов"
            aria-modal="true"
            className="relative h-full w-[272px] max-w-[85vw] border-r border-sidebar-border shadow-xl"
            ref={mobileDrawerRef}
            role="dialog"
          >
            <ChatSidebar
              {...sidebarProps}
              onClose={() => setMobileMenuOpen(false)}
            />
          </aside>
        </div>
      ) : null}

      <div
        className="flex min-w-0 flex-1 flex-col"
        inert={mobileMenuOpen ? true : undefined}
      >
        <ChatHeader
          models={catalog.models}
          modelId={chat.activeModelId}
          onModelChange={chat.setModel}
          onOpenMenu={() => {
            previousFocusRef.current = document.activeElement as HTMLElement;
            setMobileMenuOpen(true);
          }}
          quota={chat.quota}
        />
        <div className="min-h-0 flex-1 overflow-y-auto">
          {chat.activeConversation ? (
            <ChatMessageList
              canRetryLast={chat.canRetryLast}
              conversation={chat.activeConversation}
              isGenerating={chat.isGenerating}
              onRetry={chat.retryLast}
            />
          ) : (
            <ChatEmptyState firstName={user.firstName} onSuggestion={chat.sendMessage} />
          )}
        </div>
        <ChatComposer
          isGenerating={chat.isGenerating}
          onSend={chat.sendMessage}
          onStop={chat.stopGenerating}
          quotaExhausted={
            chat.quota.status === "ready" && chat.quota.snapshot.exhausted
          }
        />
      </div>
    </main>
  );
}
