import { cleanup, render, screen, within } from '@testing-library/react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

import { CmsRouteProvider, type CmsRouteData } from '@/spa/cmsRoute'
import About from '@/spa/pages/About'

const viewport = vi.hoisted(() => ({ mobile: false, relevanceStacked: false }))

vi.mock('@/spa/hooks/useIsMobile', () => ({
  useIsMobile: (breakpoint = 768) =>
    breakpoint === 1024 ? viewport.relevanceStacked : viewport.mobile,
}))

vi.mock('next/navigation', () => ({
  usePathname: () => '/der-bmp',
  useRouter: () => ({ push: vi.fn(), replace: vi.fn() }),
}))

vi.mock('@/spa/components/AwardsGridSection', () => ({
  default: () => <section data-testid="awards-stub" />,
}))

vi.mock('@/spa/components/HomeWinnersSection', () => ({
  default: () => <section data-testid="winners-stub" />,
}))

vi.mock('@/spa/components/TestimonialsSection', () => ({
  default: () => <section data-testid="testimonials-stub" />,
}))

vi.mock('@/spa/components/ui/munich-skyline-bg', () => ({
  default: () => null,
}))

const aboutRoute: CmsRouteData = {
  collection: 'pages',
  doc: {
    id: 'about-page',
    slug: 'der-bmp',
    spaPath: '/der-bmp',
    about: {
      mittelstand: {
        image: {
          url: '/api/media/file/cms-relevance.jpg',
          alt: 'CMS relevance event',
          focalX: 38,
          focalY: 42,
        },
        imageAlt: 'Page-owned fallback alt',
        eyebrow: 'CMS relevance eyebrow',
        heading: 'CMS RELEVANCE\nHEADING',
        body: [
          { text: 'First CMS relevance paragraph.' },
          { text: 'Second CMS relevance paragraph.' },
        ],
      },
    },
  },
}

const renderAbout = () =>
  render(
    <CmsRouteProvider value={aboutRoute}>
      <About />
    </CmsRouteProvider>,
  )

describe('/der-bmp relevance section', () => {
  beforeEach(() => {
    viewport.mobile = false
    viewport.relevanceStacked = false
  })

  afterEach(() => cleanup())

  it('gives the image the larger desktop share and centers a readable copy measure', () => {
    renderAbout()

    const layout = screen.getByTestId('relevance-layout')
    const copyPanel = screen.getByTestId('relevance-copy-panel')
    const copy = screen.getByTestId('relevance-copy')

    expect(layout.getAttribute('data-layout')).toBe('split')
    expect(layout.style.gridTemplateColumns).toBe('55% 45%')
    expect(copyPanel.style.padding).toBe('88px 64px')
    expect(copy.style.width).toBe('100%')
    expect(copy.style.maxWidth).toBe('520px')
    expect(copy.style.margin).toBe('0px auto')
  })

  it('preserves CMS-owned copy and media while honoring the media focal point', () => {
    renderAbout()

    const section = screen.getByTestId('relevance-section')
    const image = within(section).getByRole('img', { name: 'CMS relevance event' })

    expect(image.getAttribute('src')).toBe('/api/media/file/cms-relevance.jpg')
    expect(image.style.objectPosition).toBe('38% 42%')
    expect(within(section).getByText('CMS relevance eyebrow')).toBeTruthy()
    expect(within(section).getByRole('heading', { level: 2 }).textContent).toBe(
      'CMS RELEVANCEHEADING',
    )
    expect(within(section).getByText('First CMS relevance paragraph.')).toBeTruthy()
    expect(within(section).getByText('Second CMS relevance paragraph.')).toBeTruthy()
    expect(
      within(section).queryByText(
        'Der Bayerische Mittelstandspreis ist weit mehr als eine Trophäe.',
      ),
    ).toBeNull()
  })

  it('keeps the image first with readable padding in the stacked mobile layout', () => {
    viewport.mobile = true
    viewport.relevanceStacked = true
    renderAbout()

    const layout = screen.getByTestId('relevance-layout')
    const imagePanel = screen.getByTestId('relevance-image-panel')
    const copyPanel = screen.getByTestId('relevance-copy-panel')

    expect(layout.getAttribute('data-layout')).toBe('stacked')
    expect(layout.style.gridTemplateColumns).toBe('1fr')
    expect(imagePanel.style.minHeight).toBe('280px')
    expect(copyPanel.style.padding).toBe('32px 24px 40px')
    expect(
      imagePanel.compareDocumentPosition(copyPanel) & Node.DOCUMENT_POSITION_FOLLOWING,
    ).toBeTruthy()
  })
})
