import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent, waitFor } from "@solidjs/testing-library";
import { AiChatWidget } from "~/components/AiChatWidget";

global.fetch = vi.fn();

function createFetchMock(response: unknown, ok = true) {
  return vi.mocked(fetch).mockResolvedValueOnce({
    ok,
    json: () => Promise.resolve(response),
  } as Response);
}

describe("AiChatWidget", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("renders the floating button", () => {
    render(() => <AiChatWidget />);
    const button = screen.getByTitle("AI Assistant");
    expect(button).toBeTruthy();
  });

  it("opens chat window on button click", async () => {
    render(() => <AiChatWidget />);
    const button = screen.getByTitle("AI Assistant");

    fireEvent.click(button);

    await waitFor(() => {
      const header = screen.getByText("AI Assistant");
      expect(header).toBeTruthy();
    });
  });

  it("shows initial greeting message", () => {
    render(() => <AiChatWidget />);
    const button = screen.getByTitle("AI Assistant");
    fireEvent.click(button);

    const greeting = screen.getByText(/I'm your AI assistant/i);
    expect(greeting).toBeTruthy();
  });

  it("shows error message when API fails", async () => {
    vi.mocked(fetch).mockRejectedValueOnce(new Error("Network error"));

    render(() => <AiChatWidget />);
    const button = screen.getByTitle("AI Assistant");
    fireEvent.click(button);

    await waitFor(() => {
      const input = screen.getByPlaceholderText(/Ask/i);
      fireEvent.change(input, { target: { value: "Test" } });
      fireEvent.keyDown(input, { key: "Enter" });
    });

    await waitFor(
      () => {
        expect(screen.getByText(/contact support/i)).toBeTruthy();
      },
      { timeout: 5000 }
    );
  });

  it("displays user message after sending", async () => {
    createFetchMock({
      message: "Hello from AI",
      conversation_id: "conv-123",
      intent: "general",
      confidence: 0.9,
    });

    render(() => <AiChatWidget />);
    const button = screen.getByTitle("AI Assistant");
    fireEvent.click(button);

    await waitFor(() => {
      const input = screen.getByPlaceholderText(/Ask/i);
      fireEvent.change(input, { target: { value: "Hello" } });
      fireEvent.keyDown(input, { key: "Enter" });
    });

    await waitFor(() => {
      expect(screen.getByText("Hello")).toBeTruthy();
    });
  });
});