import { describe, expect, test } from 'vitest'
import { button } from '../styled-system/recipes/button'
import { buttonWithCompoundVariants } from '../styled-system/recipes/button-with-compound-variants'

describe('recipe', () => {
  test('base styles', () => {
    const result = button()

    expect(result).toMatchInlineSnapshot('"button"')
  })

  test('split variant props', () => {
    const result = button.splitVariantProps({ visual: 'solid', bg: 'red.500' })
    expect(result).toMatchInlineSnapshot(`
      [
        {
          "visual": "solid",
        },
        {
          "bg": "red.500",
        },
      ]
    `)
  })

  test('solid variant styles', () => {
    const result = button({ visual: 'solid' })

    expect(result).toMatchInlineSnapshot('"button button--visual_solid"')
  })

  test('outline variant styles', () => {
    const result = button({ visual: 'outline' })

    expect(result).toMatchInlineSnapshot('"button button--visual_outline"')
  })

  test('using conditions', () => {
    const result = button({ visual: { base: 'solid', _hover: 'outline' } })
    expect(result).toMatchInlineSnapshot('"button button--visual_solid hover:button--visual_outline"')
  })

  test('compoundVariants', () => {
    const result = buttonWithCompoundVariants({ visual: 'solid' })

    expect(result).toMatchInlineSnapshot(`"button button--visual_solid"`)

    const result2 = buttonWithCompoundVariants({ visual: 'outline', size: 'md' })
    expect(result2).toMatchInlineSnapshot(`"button button--visual_outline button--size_md"`)

    const result3 = buttonWithCompoundVariants({ visual: 'outline', size: 'sm' })
    expect(result3).toMatchInlineSnapshot(`"button button--visual_outline button--size_sm"`)

    const result4 = buttonWithCompoundVariants({ visual: 'outline', size: 'lg' })
    expect(result4).toMatchInlineSnapshot(`"button button--visual_outline button--size_lg"`)
  })

  test('throws an error when using conditions with compound variants', () => {
    // @ts-expect-error
    expect(() => buttonWithCompoundVariants({ visual: { base: 'solid', _hover: 'outline' } })).toThrow(
      '[recipe:button:visual] Conditions are not supported when using compound variants.',
    )
  })

  test('split variant props', () => {
    const result = buttonWithCompoundVariants.splitVariantProps({ visual: 'solid', bg: 'red.500' })

    expect(result).toMatchInlineSnapshot(`
      [
        {
          "visual": "solid",
        },
        {
          "bg": "red.500",
        },
      ]
    `)
  })

  test('get variant props', () => {
    const result = buttonWithCompoundVariants.getVariantProps({ visual: 'outline' })

    expect(result).toMatchInlineSnapshot(`
      {
        "button": "__ignore__",
        "visual": "outline",
      }
    `)
  })

  /**
   * The boundary of the scalar fast path.
   *
   * A scalar selection names its classes by lookup; anything object-typed falls back to
   * `createCss`. `null` is object-typed and `compact` keeps it, so it takes the slow path — and
   * has to come out the same either way, which is what this pins.
   */
  test('a null variant selects nothing, as it did before', () => {
    expect(button({ visual: null as never })).toMatchInlineSnapshot('"button"')
  })

  /** An undeclared value names no class, since the build emitted no rule for one. */
  test('an undeclared variant value selects nothing', () => {
    expect(button({ visual: 'nope' as never })).toMatchInlineSnapshot('"button"')
  })
})
