import React from 'react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { cleanup, render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import AuthorBioPopover from './AuthorBioPopover'

describe('AuthorBioPopover', () => {
  beforeEach(() => {
    vi.stubGlobal('fetch', vi.fn())
  })

  afterEach(() => {
    cleanup()
    vi.unstubAllGlobals()
    vi.clearAllMocks()
  })

  it('loads and shows the public biography when opened', async () => {
    const user = userEvent.setup()
    const fetchMock = vi.mocked(fetch)

    fetchMock.mockResolvedValue({
      ok: true,
      json: async () => ({
        data: {
          text: 'Gregor has spent decades building a public portfolio across wallpapers and digital art.',
        },
      }),
    })

    render(
      <AuthorBioPopover author={{ name: 'Gregor', username: 'gregor', profile_url: '/@gregor' }} />,
    )

    await user.click(screen.getByRole('button', { name: /more about gregor/i }))

    await waitFor(() => {
      expect(fetchMock).toHaveBeenCalledTimes(1)
    })

    expect(fetchMock).toHaveBeenCalledWith(
      '/api/profile/gregor/ai-biography',
      expect.objectContaining({ credentials: 'same-origin' }),
    )

    expect(await screen.findByText(/spent decades building a public portfolio/i)).not.toBeNull()
    expect(screen.getByRole('link', { name: /view profile/i }).getAttribute('href')).toBe('/@gregor')
    expect(screen.getByRole('link', { name: /open gallery/i }).getAttribute('href')).toBe('/@gregor/gallery')
  })

  it('shows a fallback message when no public biography exists', async () => {
    const user = userEvent.setup()
    const fetchMock = vi.mocked(fetch)

    fetchMock.mockResolvedValue({
      ok: true,
      json: async () => ({ data: null }),
    })

    render(
      <AuthorBioPopover author={{ name: 'Gregor', username: 'gregor', profile_url: '/@gregor' }} />,
    )

    await user.click(screen.getByRole('button', { name: /more about gregor/i }))

    expect(await screen.findByText(/no public biography available yet/i)).not.toBeNull()
  })
})