import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { ChatWidget } from "@/components/dashboard/ChatWidget";
import { describe, it, expect, vi, beforeEach } from "vitest";
import { useChatStore } from "@/hooks/useChatStore";
import { useChatWidgetStore } from "@/hooks/useChatWidgetStore";
import { usePresenceStore } from "@/hooks/usePresenceStore";
import { useAuthStore } from "@/hooks/useAuthStore";

// Mock stores
vi.mock("@/hooks/useChatStore", () => ({
  useChatStore: vi.fn(),
}));

vi.mock("@/hooks/useChatWidgetStore", () => ({
  useChatWidgetStore: vi.fn(),
}));

vi.mock("@/hooks/usePresenceStore", () => ({
  usePresenceStore: vi.fn(),
}));

vi.mock("@/hooks/useAuthStore", () => ({
  useAuthStore: vi.fn(),
}));

describe("ChatWidget", () => {
  const mockFetchMessages = vi.fn();
  const mockSendMessage = vi.fn();
  const mockCleanup = vi.fn();
  const mockSetupSSE = vi.fn().mockReturnValue(mockCleanup);

  const defaultChatStore = {
    messages: [],
    rooms: [{ id: '1', name: 'General', type: 'group', participants: [] }],
    activeRoomId: '1',
    isLoading: false,
    typingUsers: {},
    drafts: {},
    fetchMessages: mockFetchMessages,
    sendMessage: mockSendMessage,
    setupSSE: mockSetupSSE,
    fetchRooms: vi.fn(),
    setActiveRoom: vi.fn(),
    setDraft: vi.fn(),
    sendTypingStatus: vi.fn(),
  };

  const defaultWidgetStore = {
    isMinimized: false,
    isVisible: true,
    toggleMinimized: vi.fn(),
    setVisible: vi.fn(),
  };

  const defaultPresenceStore = {
    presenceData: { users: [] },
    fetchPresenceData: vi.fn(),
  };

  const defaultAuthStore = {
    user: { id: '1', name: 'Test User', email: 'test@example.com' },
    login: vi.fn(),
  };

  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(useChatStore).mockReturnValue(defaultChatStore as any);
    vi.mocked(useChatWidgetStore).mockReturnValue(defaultWidgetStore as any);
    // @ts-ignore
    vi.mocked(usePresenceStore).mockReturnValue(defaultPresenceStore as any);
    // @ts-ignore
    vi.mocked(useAuthStore).mockReturnValue(defaultAuthStore as any);
    
    // Mock global fetch for session
    global.fetch = vi.fn().mockResolvedValue({
      json: vi.fn().mockResolvedValue({ user: defaultAuthStore.user })
    } as any);
  });

  it("renders correctly when not minimized", () => {
    render(<ChatWidget />);
    // Check for "General" in the header/rooms list
    expect(screen.getAllByText(/General/i).length).toBeGreaterThan(0);
    expect(screen.getByTestId("chat-input-editor")).toBeInTheDocument();
  });

  it("renders messages correctly", () => {
    vi.mocked(useChatStore).mockReturnValue({
      ...defaultChatStore,
      messages: [
        { id: '1', message: 'Hello team!', sender_name: 'Alice', sender_id: 'alice', sender_email: 'alice@test.com', created_at: new Date().toISOString() },
        { id: '2', message: 'Hi Alice!', sender_name: 'Bob', sender_id: 'bob', sender_email: 'bob@test.com', created_at: new Date().toISOString() },
      ],
    } as any);

    render(<ChatWidget />);
    expect(screen.getByText("Hello team!")).toBeInTheDocument();
    expect(screen.getByText("Hi Alice!")).toBeInTheDocument();
  });

  it("calls sendMessage when input is submitted", async () => {
    render(<ChatWidget />);
    
    // ChatInput uses a div with contentEditable
    const input = screen.getByTestId("chat-input-editor");
    
    // Set textContent and trigger input
    input.textContent = "New message";
    fireEvent.input(input);
    
    // Trigger Enter key
    fireEvent.keyDown(input, { key: 'Enter', code: 'Enter', shiftKey: false });

    await waitFor(() => {
      expect(mockSendMessage).toHaveBeenCalledWith("New message");
    });
  });

  it("does not render content when minimized", () => {
    vi.mocked(useChatWidgetStore).mockReturnValue({
      ...defaultWidgetStore,
      isMinimized: true,
    } as any);

    const { container } = render(<ChatWidget />);
    expect(container.firstChild).toBeNull();
  });
});
