import { render, waitFor, screen } from '@testing-library/react';
import ContentOutline from './ContentOutline.js';
import { AppStateProvider, type Draft, useDraft, useDrupal } from '../Context.js';
import { expect, vi } from 'vitest';
import { userEvent } from '@testing-library/user-event';

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

const initialState = {
  accountId: '12345',
  drupal: {
    entity: {
      id: 1,
      type: 'canvas_page',
    },
    draftLinked: false,
  },
  keywords: ['gritty', 'phanatic', 'swoop'],
  competitorUrls: [
    'https://www.instagram.com/grittynhl/',
    'https://en.wikipedia.org/wiki/Gritty',
    'https://www.nhl.com/flyers/fans/gritty',
    'https://www.tiktok.com/@grittynhl?lang=en',
    'https://grittys.com',
    'https://www.merriam-webster.com/dictionary/gritty',
    'https://www.instagram.com/reel/DLC8pxqRxqf/?hl=en',
    'https://975thefanatic.com/listicle/top-6-gritty-moments/',
    'https://www.tiktok.com/@grittynhl/video/7517302191233797407',
    'https://www.reddit.com/r/Gritty/',
  ],
};

describe('Content Outline', () => {
  test('No fields shown when no keywords or < 10 competitor URLs provided', async () => {
    render(
      <AppStateProvider
        initialState={{
          ...initialState,
          keywords: [],
          competitorUrls: ['https://www.instagram.com/grittynhl/'],
        }}
      >
        <ContentOutline />
      </AppStateProvider>,
    );

    await waitFor(() => {
      expect(
        screen.getByText(/Keywords and at least 10 competitor URLs are required/i),
      ).toBeInTheDocument();
    });
  });

  test('Draft is created and linked', async () => {
    let draft: Draft = {
      title: 'Untitled Canvas draft',
    };
    let drupal = { draftLinked: false };
    const ContextCapture = () => {
      draft = useDraft();
      drupal = useDrupal();
      return null;
    };
    render(
      <AppStateProvider initialState={initialState}>
        <ContentOutline />
        <ContextCapture />
      </AppStateProvider>,
    );

    await waitFor(() => {
      expect(draft.id).toBe('bead88f1-bd37-48a7-9861-46f04058141d');
    });
    await waitFor(() => {
      expect(drupal.draftLinked).toBe(true);
    });
  });

  test('error is displayed when draft could not be updated', async () => {
    const user = userEvent.setup();
    render(
      <AppStateProvider initialState={initialState}>
        <ContentOutline />
      </AppStateProvider>,
    );

    const input = screen.getByTestId('title-tag-input');
    await user.clear(input);
    await user.type(input, 'Bad title');

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

    expect(screen.getByText(/Changes to your draft are currently unsaved/i)).toBeInTheDocument();
  });

  test('error is removed when draft can be updated', async () => {
    const user = userEvent.setup();
    render(
      <AppStateProvider initialState={initialState}>
        <ContentOutline />
      </AppStateProvider>,
    );

    const input = screen.getByTestId('title-tag-input');
    await user.clear(input);
    await user.type(input, 'Bad title');

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

    expect(screen.getByText(/Changes to your draft are currently unsaved/i)).toBeInTheDocument();

    await user.clear(input);
    await user.type(input, 'Good title');
    await waitFor(
      () => {
        expect(screen.queryByRole('alert')).not.toBeInTheDocument();
      },
      { timeout: 3000 },
    );
  });
});
