import { cleanup, fireEvent, render, screen, within } from '@testing-library/react'
import { ThemeModeProvider } from '@my-resume/ui/theme'
import { beforeEach, describe, expect, it, vi } from 'vitest'

let activeLocale: 'zh' | 'en' = 'zh'
let pathnameState = '/zh/ai-talk'
const pushMock = vi.fn()
const prefetchMock = vi.fn()

vi.mock('@i18n/navigation', () => ({
  Link: ({ children, href, prefetch: _prefetch, ...props }: any) => (
    <a
      href={
        typeof href === 'string'
          ? href === '/'
            ? `/${activeLocale}`
            : href.startsWith('/')
              ? `/${activeLocale}${href}`
              : href
          : `/${activeLocale}`
      }
      {...props}>
      {children}
    </a>
  ),
  usePathname: () => pathnameState,
  useRouter: () => ({
    push: pushMock,
    prefetch: prefetchMock,
    replace: vi.fn(),
  }),
}))

vi.mock('next-intl', async () => {
  const zhAiTalk = (await import('@i18n/locales/zh/aiTalk.json')).default
  const zhPublishedResume = (await import('@i18n/locales/zh/publishedResume.json')).default
  const zhSite = (await import('@i18n/locales/zh/site.json')).default
  const enAiTalk = (await import('@i18n/locales/en/aiTalk.json')).default
  const enPublishedResume = (await import('@i18n/locales/en/publishedResume.json')).default
  const enSite = (await import('@i18n/locales/en/site.json')).default

  const bundlesByLocale: Record<'zh' | 'en', Record<string, Record<string, unknown>>> = {
    zh: {
      aiTalk: zhAiTalk as Record<string, unknown>,
      publishedResume: zhPublishedResume as Record<string, unknown>,
      site: zhSite as Record<string, unknown>,
    },
    en: {
      aiTalk: enAiTalk as Record<string, unknown>,
      publishedResume: enPublishedResume as Record<string, unknown>,
      site: enSite as Record<string, unknown>,
    },
  }

  const getMessage = (namespace: string, key: string): string => {
    const value = key
      .split('.')
      .reduce<unknown>((currentValue, segment) => {
        if (!currentValue || typeof currentValue !== 'object') {
          return undefined
        }

        return (currentValue as Record<string, unknown>)[segment]
      }, bundlesByLocale[activeLocale][namespace])

    return typeof value === 'string' ? value : key
  }

  const interpolate = (message: string, values?: Record<string, unknown>) =>
    Object.entries(values ?? {}).reduce(
      (currentMessage, [name, value]) =>
        currentMessage.replaceAll(`{${name}}`, String(value)),
      message,
    )

  return {
    useTranslations:
      (namespace: string) =>
      (key: string, values?: Record<string, unknown>): string =>
        interpolate(getMessage(namespace, key), values),
  }
})

vi.mock('@shared/ai-chat/ai-chat-presentation-sync', () => ({
  AiChatPresentationSync: () => null,
}))

import { AiTalkEntryShell } from '../entry-shell'
import { publishedResumeFixture } from '@shared/published-resume/__tests__/fixture'

describe('AiTalkEntryShell', () => {
  beforeEach(() => {
    activeLocale = 'zh'
    pathnameState = '/zh/ai-talk'
    pushMock.mockReset()
    prefetchMock.mockReset()
    cleanup()
  })

  it('should render the hero row and three feature cards', () => {
    render(
      <ThemeModeProvider>
        <AiTalkEntryShell
          apiBaseUrl="http://localhost:5577"
          locale="zh"
          publishedResume={publishedResumeFixture}
        />
      </ThemeModeProvider>,
    )

    expect(screen.getByRole('heading', { name: 'AI Talk 页面入口' })).toBeInTheDocument()
    expect(screen.getByTestId('ai-talk-hub-row')).toBeInTheDocument()
    expect(screen.getByTestId('ai-talk-hub-primary')).toBeInTheDocument()
    expect(screen.getByTestId('ai-talk-hub-profile')).toBeInTheDocument()

    const ragCard = screen.getByTestId('ai-talk-card-rag')
    const resumeAdvisorCard = screen.getByTestId('ai-talk-card-resumeAdvisor')
    const avatarCard = screen.getByTestId('ai-talk-card-avatar')

    expect(within(ragCard).getAllByText('RAG 知识库 / 分身问答')).not.toHaveLength(0)
    const ragButton = within(ragCard).getByRole('button', { name: '暂未开放' })
    expect(ragButton.className).toContain('button--primary')
    fireEvent.click(ragButton)
    expect(pushMock).toHaveBeenCalledWith('/ai-talk/chat')

    expect(within(resumeAdvisorCard).getAllByText('简历优化与建议')).not.toHaveLength(0)
    fireEvent.click(within(resumeAdvisorCard).getByRole('button', { name: '查看优化说明' }))
    expect(pushMock).toHaveBeenCalledWith('/ai-talk/resume-advisor')

    expect(within(avatarCard).getAllByText('数字人 / 自我介绍')).not.toHaveLength(0)
    expect(within(avatarCard).getAllByText(/coming soon/i)).not.toHaveLength(0)
    fireEvent.click(within(avatarCard).getByRole('button', { name: '查看数字人入口' }))
    expect(pushMock).toHaveBeenCalledWith('/ai-talk/avatar')
    expect(prefetchMock).toHaveBeenCalledWith('/ai-talk/chat')
    expect(prefetchMock).toHaveBeenCalledWith('/ai-talk/resume-advisor')
    expect(prefetchMock).toHaveBeenCalledWith('/ai-talk/avatar')
    expect(screen.getByRole('link', { name: 'AI Talk' })).toHaveAttribute('aria-current', 'page')
  })

  it('should render english copy and keep ai-talk nav active on en locale', () => {
    activeLocale = 'en'
    pathnameState = '/en/ai-talk'

    render(
      <ThemeModeProvider>
        <AiTalkEntryShell
          apiBaseUrl="http://localhost:5577"
          locale="en"
          publishedResume={publishedResumeFixture}
        />
      </ThemeModeProvider>,
    )

    expect(screen.getByRole('heading', { name: 'AI Talk Entry Hub' })).toBeInTheDocument()
    expect(screen.getByRole('link', { name: 'Resume' })).toHaveAttribute('href', '/en')
    expect(screen.getByRole('link', { name: 'Profile' })).toHaveAttribute('href', '/en/profile')
    expect(screen.getByRole('link', { name: 'AI Talk' })).toHaveAttribute('aria-current', 'page')
    const ragButton = screen.getByRole('button', { name: 'Not open yet' })
    expect(ragButton).toBeInTheDocument()
    fireEvent.click(ragButton)
    expect(pushMock).toHaveBeenCalledWith('/ai-talk/chat')
  })

  it('should keep ai-talk frame visible when published resume is temporarily unavailable', () => {
    render(
      <ThemeModeProvider>
        <AiTalkEntryShell
          apiBaseUrl="http://localhost:5577"
          enableClientSync
          initialLoadError="fetch failed"
          locale="zh"
          publishedResume={null}
        />
      </ThemeModeProvider>,
    )

    expect(screen.getByRole('link', { name: 'AI Talk' })).toHaveAttribute('aria-current', 'page')
    expect(screen.getByText('公开简历服务暂时不可用')).toBeInTheDocument()
    expect(screen.getByTestId('published-resume-unavailable-message')).toHaveTextContent(
      'fetch failed',
    )
  })
})
