import { readFileSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { renderToStaticMarkup } from 'react-dom/server'
import { FormProvider, useForm } from 'react-hook-form'
import { describe, expect, it } from 'vitest'
import { DataTable } from '../src/data-display/data-table'
import { Table, Tbody, Td, Th, Thead, Tr } from '../src/data-display/table'
import { FormField } from '../src/forms/form-field'
import { cn } from '../src/lib/cn'
import { panelHeightMap, panelWidthMap, sideMap } from '../src/overlays/sheet'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

function RequiredField({ childRequired }: { childRequired?: boolean }) {
  const form = useForm()
  const childProps = childRequired === undefined ? {} : { required: childRequired }

  return (
    <FormProvider {...form}>
      <FormField name="name" required>
        <input {...childProps} />
      </FormField>
    </FormProvider>
  )
}

describe('foundation design system', () => {
  it('keeps semantic text colors alongside custom typography utilities', () => {
    expect(cn('text-ink-on-accent text-body-1')).toBe('text-ink-on-accent text-body-1')
    expect(cn('text-ink-soft text-meta')).toBe('text-ink-soft text-meta')
  })

  it('applies sheet side and size defaults from the root contract', () => {
    expect(sideMap['left']).toContain('start-0')
    expect(panelWidthMap['lg']).toContain('max-w-screen-lg')
  })

  it('lets sheet content override the root defaults', () => {
    expect(sideMap['bottom']).toContain('bottom-0')
    expect(panelHeightMap['xl']).toContain('max-h-[88vh]')
  })

  it('keeps the shared tailwind preset off the banned system-ui fallback', () => {
    const presetSource = readFileSync(
      path.resolve(__dirname, '../../config/tailwind.preset.ts'),
      'utf8',
    )

    expect(presetSource).toContain("'IBM Plex Sans', Arial, sans-serif")
    expect(presetSource).not.toContain('system-ui')
  })

  it('propagates FormField required state without overriding an explicit child value', () => {
    expect(renderToStaticMarkup(<RequiredField />)).toContain('required=""')
    expect(renderToStaticMarkup(<RequiredField childRequired={false} />)).not.toContain(
      'required=""',
    )
  })

  it('renders the complete table accessibility role tree', () => {
    const markup = renderToStaticMarkup(
      <DataTable
        columns={[{ accessorKey: 'name', header: 'Name' }]}
        data={[{ name: 'Ada' }]}
      />,
    )

    expect(markup).toMatch(
      /<div(?=[^>]*role="table")[^>]*>.*<div(?=[^>]*role="rowgroup")[^>]*>.*<div(?=[^>]*role="row")[^>]*>.*<div(?=[^>]*role="columnheader")[^>]*>.*Name.*<\/div>/,
    )
    expect(markup).toMatch(
      /<div(?=[^>]*role="rowgroup")[^>]*>.*<div(?=[^>]*role="row")[^>]*>.*<div(?=[^>]*role="cell")[^>]*>Ada<\/div>/,
    )
    expect(markup.match(/role="rowgroup"/g)).toHaveLength(2)
    expect(markup.match(/role="row"/g)).toHaveLength(2)
    expect(markup).toContain('tabindex="0"')
  })

  it('makes data tables sortable and searchable by default', () => {
    const markup = renderToStaticMarkup(
      <DataTable
        columns={[{ accessorKey: 'name', header: 'Name' }]}
        data={[{ name: 'Ada' }]}
      />,
    )

    expect(markup).toContain('aria-label="Filter table"')
    expect(markup).toContain('<button type="button"')
  })

  it('wraps long table content without overlapping adjacent cells', () => {
    const markup = renderToStaticMarkup(
      <Table>
        <Thead><Tr><Th>Name</Th><Th>Details</Th></Tr></Thead>
        <Tbody><Tr><Td>unbroken-content-that-must-wrap</Td><Td>Adjacent</Td></Tr></Tbody>
      </Table>,
    )

    expect(markup).toContain('min-w-0')
    expect(markup).toContain('[overflow-wrap:anywhere]')
    expect(markup).toContain('min-h-8')
    expect(markup).not.toContain('class="h-8 px-2')
  })

  it('preserves custom text color and typography utilities together', () => {
    expect(cn('text-ink-on-accent', 'text-body-1')).toContain('text-ink-on-accent')
    expect(cn('text-ink-on-accent', 'text-body-1')).toContain('text-body-1')
  })

  it('localizes parameterized settings category action names', () => {
    const en = JSON.parse(
      readFileSync(path.resolve(__dirname, '../src/i18n/en.json'), 'utf8'),
    ) as Record<string, string>
    const he = JSON.parse(
      readFileSync(path.resolve(__dirname, '../src/i18n/he.json'), 'utf8'),
    ) as Record<string, string>

    expect(en['settings.hub.configureCategory']).toBe('Configure {{category}}')
    expect(he['settings.hub.configureCategory']).toContain('{{category}}')
    expect(he['settings.hub.configureCategory']).not.toBe(
      en['settings.hub.configureCategory'],
    )
  })
})
