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

import * as analyticsLib from '@/lib/analytics';

import CookieConsentBanner from './CookieConsentBanner';

vi.mock('@/lib/analytics', async (importOriginal) => {
  const actual = await importOriginal<typeof import('@/lib/analytics')>();
  return { ...actual, loadAnalytics: vi.fn() };
});

describe('CookieConsentBanner', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    // Clear cookies before each test so the banner is visible
    document.cookie = 'cookie_consent=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
    document.cookie = 'cookie_consent_categories=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
  });

  it('renders the consent banner when no consent cookie exists', () => {
    render(<CookieConsentBanner />);

    expect(screen.getByRole('dialog', { name: /cookie consent/i })).toBeInTheDocument();
    expect(screen.getByText(/we use cookies/i)).toBeInTheDocument();
  });

  it('does not render the banner when consent cookie already exists', () => {
    document.cookie = 'cookie_consent=accepted; path=/;';

    render(<CookieConsentBanner />);

    expect(screen.queryByRole('dialog', { name: /cookie consent/i })).not.toBeInTheDocument();
  });

  it('shows customize panel with necessary, analytics, and marketing sections', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /customize/i }));

    expect(screen.getByLabelText(/necessary cookies/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/analytics cookies/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/marketing cookies/i)).toBeInTheDocument();
  });

  it('has the necessary cookies toggle always checked and disabled', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /customize/i }));

    const necessarySwitch = screen.getByLabelText(/necessary cookies/i);
    expect(necessarySwitch).toBeChecked();
    expect(necessarySwitch).toBeDisabled();
  });

  it('allows toggling the analytics switch', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /customize/i }));

    const analyticsSwitch = screen.getByLabelText(/analytics cookies/i);
    expect(analyticsSwitch).not.toBeChecked();

    await user.click(analyticsSwitch);
    expect(analyticsSwitch).toBeChecked();
  });

  it('hides the banner after clicking Accept all', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /accept all/i }));

    expect(screen.queryByRole('dialog', { name: /cookie consent/i })).not.toBeInTheDocument();
  });

  it('hides the banner after clicking Decline', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /decline/i }));

    expect(screen.queryByRole('dialog', { name: /cookie consent/i })).not.toBeInTheDocument();
  });

  it('shows marketing toggle description indicating no current marketing cookies', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /customize/i }));

    expect(screen.getByText(/not currently in use/i)).toBeInTheDocument();
  });

  it('calls loadAnalytics when Accept all is clicked', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /accept all/i }));

    expect(analyticsLib.loadAnalytics).toHaveBeenCalledOnce();
  });

  it('calls loadAnalytics when analytics is enabled via Save preferences', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /customize/i }));
    await user.click(screen.getByLabelText(/analytics cookies/i));
    await user.click(screen.getByRole('button', { name: /save preferences/i }));

    expect(analyticsLib.loadAnalytics).toHaveBeenCalledOnce();
  });

  it('does not call loadAnalytics when Decline is clicked', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /decline/i }));

    expect(analyticsLib.loadAnalytics).not.toHaveBeenCalled();
  });

  it('does not call loadAnalytics when analytics is disabled via Save preferences', async () => {
    const user = userEvent.setup();
    render(<CookieConsentBanner />);

    await user.click(screen.getByRole('button', { name: /customize/i }));
    // analytics switch defaults to off — save without enabling it
    await user.click(screen.getByRole('button', { name: /save preferences/i }));

    expect(analyticsLib.loadAnalytics).not.toHaveBeenCalled();
  });
});
