import { fireEvent, screen, waitFor } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'

import PostListPage from '@/pages/posts/PostListPage'
import { buildPost, buildTag, buildWikiPage } from '@/test/factories'
import { renderWithProviders } from '@/test/render'

const postsApi = vi.hoisted (() => ({
  fetchPosts: vi.fn (),
}))

const wikiApi = vi.hoisted (() => ({
  fetchWikiPageByTitle: vi.fn (),
  fetchWikiPages:       vi.fn (),
}))

vi.mock ('@/lib/posts', () => postsApi)
vi.mock ('@/lib/wiki', () => wikiApi)

describe ('PostListPage', () => {
  it ('loads posts from the current query and renders the plaza tab', async () => {
    const tag = buildTag ({ name: '虹夏' })
    postsApi.fetchPosts.mockResolvedValueOnce ({
      posts: [buildPost ({ id: 5, title: '投稿5', tags: [tag] })],
      count: 1,
    })
    wikiApi.fetchWikiPageByTitle.mockResolvedValueOnce (buildWikiPage ({ title: '虹夏' }))
    wikiApi.fetchWikiPages.mockResolvedValueOnce ([buildWikiPage ({ title: '虹夏' })])

    renderWithProviders (<PostListPage/>, { route: '/posts?tags=%E8%99%B9%E5%A4%8F&page=2' })

    await waitFor (() => {
      expect (postsApi.fetchPosts).toHaveBeenCalledWith (
          expect.objectContaining ({
            tags:  '虹夏',
            match: 'all',
            page:  2,
            limit: 20,
          }),
      )
    })
    expect (await screen.findByRole ('link', { name: '投稿5' })).toHaveAttribute (
        'href',
        '/posts/5',
    )
    expect (screen.getByText ('広場')).toBeInTheDocument ()
  })

  it ('shows the empty state when loading finishes without posts', async () => {
    postsApi.fetchPosts.mockResolvedValueOnce ({ posts: [], count: 0 })

    renderWithProviders (<PostListPage/>, { route: '/posts' })

    expect (await screen.findByText ('広場には何もありませんよ．')).toBeInTheDocument ()
  })

  it ('renders the wiki tab for single-tag pages', async () => {
    postsApi.fetchPosts.mockResolvedValueOnce ({ posts: [], count: 0 })
    wikiApi.fetchWikiPageByTitle.mockResolvedValueOnce (
        buildWikiPage ({ title: '虹夏', body: 'Wiki body' }),
    )
    wikiApi.fetchWikiPages.mockResolvedValueOnce ([buildWikiPage ({ title: '虹夏' })])

    renderWithProviders (<PostListPage/>, { route: '/posts?tags=%E8%99%B9%E5%A4%8F' })

    fireEvent.click (await screen.findByText ('Wiki'))

    expect (await screen.findByText ('Wiki body')).toBeInTheDocument ()
    expect (screen.getByRole ('link', { name: 'Wiki を見る' })).toHaveAttribute (
        'href',
        '/wiki/%E8%99%B9%E5%A4%8F',
    )
  })
})
