import { render } from '@testing-library/vue'
import { createTestingPinia } from '@pinia/testing'
import PrimeVue from 'primevue/config'
import { describe, expect, it } from 'vitest'
import { nextTick } from 'vue'
import { createI18n } from 'vue-i18n'
import type { ComponentProps } from 'vue-component-type-helpers'

import enMessages from '@/locales/en/main.json' with { type: 'json' }

import GridSkeleton from './GridSkeleton.vue'

describe('GridSkeleton', () => {
  function renderComponent({
    props = {}
  }: {
    props?: Partial<ComponentProps<typeof GridSkeleton>>
  } = {}) {
    const i18n = createI18n({
      legacy: false,
      locale: 'en',
      messages: { en: enMessages }
    })

    return render(GridSkeleton, {
      props: {
        gridStyle: {
          display: 'grid',
          gridTemplateColumns: 'repeat(auto-fill, minmax(19rem, 1fr))',
          padding: '0.5rem',
          gap: '1.5rem'
        },
        ...props
      },
      global: {
        plugins: [PrimeVue, createTestingPinia({ stubActions: false }), i18n],
        stubs: {
          PackCardSkeleton: {
            template: '<div data-testid="pack-card-skeleton" />'
          }
        }
      }
    })
  }

  it('renders with default props', () => {
    const { container } = renderComponent()
    // eslint-disable-next-line testing-library/no-node-access
    expect(container.firstElementChild).toBeTruthy()
  })

  it('applies the provided grid style', () => {
    const customGridStyle = {
      display: 'grid',
      gridTemplateColumns: 'repeat(auto-fill, minmax(15rem, 1fr))',
      padding: '1rem',
      gap: '1rem'
    }

    const { container } = renderComponent({
      props: { gridStyle: customGridStyle }
    })

    // eslint-disable-next-line testing-library/no-node-access
    const gridElement = container.firstElementChild as HTMLElement
    expect(gridElement.style.display).toBe('grid')
    expect(gridElement.style.gridTemplateColumns).toBe(
      'repeat(auto-fill, minmax(15rem, 1fr))'
    )
    expect(gridElement.style.padding).toBe('1rem')
    expect(gridElement.style.gap).toBe('1rem')
  })

  it('renders the specified number of skeleton cards', async () => {
    const cardCount = 5
    const { container } = renderComponent({
      props: { skeletonCardCount: cardCount }
    })

    await nextTick()

    // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
    const skeletonCards = container.querySelectorAll(
      '[data-testid="pack-card-skeleton"]'
    )
    expect(skeletonCards).toHaveLength(5)
  })
})
