import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

// Mock the hook so we can control its return values
const mockPromptInstall = vi.fn();
const mockDismiss = vi.fn();

vi.mock("../hooks/useInstallPrompt", () => ({
  useInstallPrompt: vi.fn(() => ({
    canInstall: false,
    isStandalone: false,
    isIOS: false,
    isDismissed: false,
    promptInstall: mockPromptInstall,
    dismiss: mockDismiss,
  })),
}));

import { useInstallPrompt } from "../hooks/useInstallPrompt";
import { InstallBanner } from "./InstallBanner";

const mockUseInstallPrompt = vi.mocked(useInstallPrompt);

describe("InstallBanner", () => {
  beforeEach(() => {
    mockPromptInstall.mockClear();
    mockDismiss.mockClear();
  });

  afterEach(() => {
    vi.restoreAllMocks();
  });

  it("renders nothing when canInstall is false and not iOS", () => {
    mockUseInstallPrompt.mockReturnValue({
      canInstall: false,
      isStandalone: false,
      isIOS: false,
      isDismissed: false,
      promptInstall: mockPromptInstall,
      dismiss: mockDismiss,
    });
    const { container } = render(<InstallBanner />);
    expect(container.firstChild).toBeNull();
  });

  it("renders nothing when already in standalone mode", () => {
    mockUseInstallPrompt.mockReturnValue({
      canInstall: true,
      isStandalone: true,
      isIOS: false,
      isDismissed: false,
      promptInstall: mockPromptInstall,
      dismiss: mockDismiss,
    });
    const { container } = render(<InstallBanner />);
    expect(container.firstChild).toBeNull();
  });

  it("renders nothing when dismissed", () => {
    mockUseInstallPrompt.mockReturnValue({
      canInstall: true,
      isStandalone: false,
      isIOS: false,
      isDismissed: true,
      promptInstall: mockPromptInstall,
      dismiss: mockDismiss,
    });
    const { container } = render(<InstallBanner />);
    expect(container.firstChild).toBeNull();
  });

  it("renders install banner when canInstall is true", () => {
    mockUseInstallPrompt.mockReturnValue({
      canInstall: true,
      isStandalone: false,
      isIOS: false,
      isDismissed: false,
      promptInstall: mockPromptInstall,
      dismiss: mockDismiss,
    });
    render(<InstallBanner />);
    expect(screen.getByText(/install/i)).toBeInTheDocument();
  });

  it("calls promptInstall when install button is clicked", async () => {
    mockUseInstallPrompt.mockReturnValue({
      canInstall: true,
      isStandalone: false,
      isIOS: false,
      isDismissed: false,
      promptInstall: mockPromptInstall,
      dismiss: mockDismiss,
    });
    render(<InstallBanner />);
    await userEvent.click(screen.getByRole("button", { name: /install/i }));
    expect(mockPromptInstall).toHaveBeenCalledOnce();
  });

  it("calls dismiss when close button is clicked", async () => {
    mockUseInstallPrompt.mockReturnValue({
      canInstall: true,
      isStandalone: false,
      isIOS: false,
      isDismissed: false,
      promptInstall: mockPromptInstall,
      dismiss: mockDismiss,
    });
    render(<InstallBanner />);
    await userEvent.click(screen.getByRole("button", { name: /dismiss|close/i }));
    expect(mockDismiss).toHaveBeenCalledOnce();
  });

  it("renders iOS instructions when isIOS is true and not dismissed", () => {
    mockUseInstallPrompt.mockReturnValue({
      canInstall: false,
      isStandalone: false,
      isIOS: true,
      isDismissed: false,
      promptInstall: mockPromptInstall,
      dismiss: mockDismiss,
    });
    render(<InstallBanner />);
    expect(screen.getByText(/share/i)).toBeInTheDocument();
    expect(screen.getByText(/add to home screen/i)).toBeInTheDocument();
  });
});
