import { render, screen, waitFor } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { http, HttpResponse } from 'msw';
import { server } from '../mocks/server.js';
import CreateMetaDescription from './CreateMetaDescription.js';
import { useState } from 'react';

vi.mock('../../assets/lightbulb.svg?react', () => ({
  default: () => <div data-testid="lightbulb-icon">Lightbulb</div>,
}));

// Helpers to mock the meta description generation endpoint per test
function useMetaDescriptionGenerationResponses(first: string[], second?: string[]) {
  let callCount = 0;
  server.use(
    http.post('/conductor/proxy/v3/meta-description/content-generation', async () => {
      callCount++;
      if (second && callCount > 1) {
        return HttpResponse.json({ descriptions: second });
      }
      return HttpResponse.json({ descriptions: first });
    }),
  );
}

describe('CreateMetaDescription component', () => {
  test('renders the meta description label', () => {
    render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );
    expect(screen.getByText('Meta description')).toBeInTheDocument();
  });

  test('displays Topic and Length validation sections', () => {
    render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );
    expect(screen.getByText('Topic')).toBeInTheDocument();
    expect(screen.getByText('Length')).toBeInTheDocument();
  });

  test('renders the textarea field', () => {
    render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );
    const textarea = screen.getByTestId('meta-description-textarea');
    expect(textarea).toBeInTheDocument();
  });

  test('updates textarea value when typing', async () => {
    const user = userEvent.setup();
    const CreateMetaDescriptionWrapper = () => {
      const [text, setText] = useState<string>('');
      return (
        <CreateMetaDescription
          accountId="12345"
          draftId="bead88f1-bd37-48a7-9861-46f04058141d"
          text={text}
          setText={setText}
        />
      );
    };
    render(<CreateMetaDescriptionWrapper />);

    const textarea = screen.getByTestId('meta-description-textarea');
    await user.type(textarea, 'My Test Meta Description');

    expect(textarea).toHaveValue('My Test Meta Description');
  });

  test('opens the dropdown menu when open button is clicked', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses(['First option']);
    const { container } = render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );

    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);

    await waitFor(() => {
      expect(screen.getByRole('listbox')).toBeInTheDocument();
    });
  });

  test('displays generated meta description options in the menu', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses([
      'Philadelphia Eagles 2025 fan guide: from the roar at Lincoln Financial Field to legendary moments, must‑know traditions, and where to celebrate across Philly.',
      'Explore the Philadelphia Eagles’ rich history, iconic players, and Super Bowl memories, plus tips for tailgating, merch, and planning the perfect Philly weekend.',
      'Plan your ultimate Eagles day in Philadelphia: stadium tour, murals and statues to visit, best cheesesteaks near the Linc, and family‑friendly stops for fans.',
    ]);
    const { container } = render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );

    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);

    await waitFor(() => {
      expect(screen.getAllByRole('option').length).toBeGreaterThan(0);
    });

    expect(
      screen.getByText(
        'Philadelphia Eagles 2025 fan guide: from the roar at Lincoln Financial Field to legendary moments, must‑know traditions, and where to celebrate across Philly.',
      ),
    ).toBeInTheDocument();
  });

  test('selects a meta description option when clicked', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses([
      'Philadelphia Eagles fan experience: from game-day traditions at Lincoln Financial Field to post-win celebrations across Philly, tips for tailgates, and must-see landmarks for diehard fans.',
    ]);
    const CreateMetaDescriptionWrapper = () => {
      const [text, setText] = useState<string>('');
      return (
        <CreateMetaDescription
          accountId="12345"
          draftId="bead88f1-bd37-48a7-9861-46f04058141d"
          text={text}
          setText={setText}
        />
      );
    };
    const { container } = render(<CreateMetaDescriptionWrapper />);

    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);

    await waitFor(() => {
      expect(screen.getAllByRole('option').length).toBeGreaterThan(0);
    });

    await user.click(
      screen.getByText(
        'Philadelphia Eagles fan experience: from game-day traditions at Lincoln Financial Field to post-win celebrations across Philly, tips for tailgates, and must-see landmarks for diehard fans.',
      ),
    );

    await waitFor(() => {
      const textarea = screen.getByTestId('meta-description-textarea');
      expect(textarea).toHaveValue(
        'Philadelphia Eagles fan experience: from game-day traditions at Lincoln Financial Field to post-win celebrations across Philly, tips for tailgates, and must-see landmarks for diehard fans.',
      );
    });
  });

  test('shows reload button in menu footer', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses(['Any description']);
    const { container } = render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );

    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);

    const reloadButton = screen.getByTestId('reload-meta-descriptions');
    expect(reloadButton).toBeInTheDocument();
  });

  test('calls mutate when reload button is clicked', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses(
      ['First description from server'],
      ['Second description after reload'],
    );
    const { container } = render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );

    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);
    await waitFor(() => {
      expect(screen.getAllByRole('option').length).toBeGreaterThan(0);
    });

    let firstOption = screen.getAllByRole('option')[0];
    expect(firstOption).toHaveTextContent('First description from server');

    const reloadButton = screen.getByTestId('reload-meta-descriptions');
    await user.click(reloadButton);
    await waitFor(() => {
      expect(screen.getAllByRole('option').length).toBeGreaterThan(0);
    });

    firstOption = screen.getAllByRole('option')[0];
    expect(firstOption).toHaveTextContent('Second description after reload');
  });

  test('closes select when Close button is clicked', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses(['Any description']);
    const { container } = render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );

    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);
    await waitFor(() => {
      expect(screen.getAllByRole('option').length).toBeGreaterThan(0);
    });

    const closeButton = screen.getByRole('button', { name: 'Close' });
    await user.click(closeButton);

    const listbox = screen.queryByRole('listbox');
    expect(listbox).not.toBeInTheDocument();
  });

  test('hides textarea when menu is open', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses(['Any description']);
    const { container } = render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );

    let textarea = screen.queryByTestId('meta-description-textarea');
    expect(textarea).toBeInTheDocument();
    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);
    textarea = screen.queryByTestId('meta-description-textarea');
    expect(textarea).not.toBeInTheDocument();
  });

  test('validates meta description length correctly', async () => {
    const user = userEvent.setup();
    const CreateMetaDescriptionWrapper = () => {
      const [text, setText] = useState<string>('');
      return (
        <CreateMetaDescription
          accountId="12345"
          draftId="bead88f1-bd37-48a7-9861-46f04058141d"
          text={text}
          setText={setText}
        />
      );
    };
    render(<CreateMetaDescriptionWrapper />);

    const textarea = screen.getByTestId('meta-description-textarea');

    // Type a valid length within 120-159 characters
    await user.type(textarea, 'A'.repeat(130));
    let indicators = screen.getAllByTestId('form-indicator');
    let lengthIndicator = indicators[1]; // Second indicator is for length
    expect(lengthIndicator).toHaveAttribute('data-valid', 'true');

    // Type an invalid length lower than 120
    await user.clear(textarea);
    await user.type(textarea, 'A'.repeat(119));
    indicators = screen.getAllByTestId('form-indicator');
    lengthIndicator = indicators[1]; // Second indicator is for length
    expect(lengthIndicator).toHaveAttribute('data-valid', 'false');

    // Type an invalid length higher than 159
    await user.clear(textarea);
    await user.type(textarea, 'A'.repeat(160));
    indicators = screen.getAllByTestId('form-indicator');
    lengthIndicator = indicators[1]; // Second indicator is for length
    expect(lengthIndicator).toHaveAttribute('data-valid', 'false');

    // Test again a valid length within 120-159 characters
    await user.clear(textarea);
    await user.type(textarea, 'A'.repeat(130));
    indicators = screen.getAllByTestId('form-indicator');
    lengthIndicator = indicators[1]; // Second indicator is for length
    expect(lengthIndicator).toHaveAttribute('data-valid', 'true');
  });

  test('applies open class to form when menu is open', async () => {
    const user = userEvent.setup();
    useMetaDescriptionGenerationResponses(['Any description']);
    const { container } = render(
      <CreateMetaDescription accountId="12345" draftId="bead88f1-bd37-48a7-9861-46f04058141d" />,
    );

    const form = container.querySelector('.create-meta-description__form');
    expect(form).not.toHaveClass('create-meta-description__form--is-open');

    const openButton = container.querySelector(
      '.create-meta-description__select__dropdown-indicator',
    ) as Element;
    await user.click(openButton);

    expect(form).toHaveClass('create-meta-description__form--is-open');
  });
});
