import { createContext } from '@bamboocss/fixture'
import type { Dict } from '@bamboocss/types'
import { describe, expect, test } from 'vitest'
import { serializeStyles } from '../src/serialize'

const css = (style: Dict) => {
  return serializeStyles(createContext(), style)
}

describe('serialize', () => {
  test('should serialize', () => {
    const result = css({
      html: {
        color: 'red',
        border: '2px solid token(colors.red.200)',
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "border": "2px solid var(--colors-red-200)",
          "color": "red",
        },
      }
    `)
  })

  test('skip non-existent', () => {
    const result = css({
      html: {
        border: '2px solid token(colors.red.xxx)',
        bg: 'token(colors.xxx)',
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "background": "colors\\.xxx",
          "border": "2px solid colors\\.red\\.xxx",
        },
      }
    `)
  })

  test('in media query', () => {
    const result = css({
      html: {
        '@container (min-width: token(sizes.4xl))': {
          color: 'green',
        },
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "@container (min-width: 56rem)": {
            "color": "green",
          },
        },
      }
    `)
  })

  test('expand multiple references', () => {
    const result = css({
      html: {
        padding: 'token(spacing.3) token(spacing.5)',
        _hover: {
          padding: 'token(spacing.7)',
        },
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "&:is(:hover, [data-hover])": {
            "padding": "var(--spacing-7)",
          },
          "padding": "var(--spacing-3) var(--spacing-5)",
        },
      }
    `)
  })
})

describe('serialize - with token()', () => {
  test('should serialize', () => {
    const result = css({
      html: {
        color: 'red',
        border: '2px solid token(colors.red.200)',
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "border": "2px solid var(--colors-red-200)",
          "color": "red",
        },
      }
    `)
  })

  test('in media query', () => {
    const result = css({
      html: {
        '@container (min-width: token(sizes.4xl))': {
          color: 'green',
        },
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "@container (min-width: 56rem)": {
            "color": "green",
          },
        },
      }
    `)
  })

  test('skip non-existent', () => {
    const result = css({
      html: {
        border: '2px solid token(colors.red.xxx)',
        bg: 'token(colors.xxx)',
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "background": "colors\\.xxx",
          "border": "2px solid colors\\.red\\.xxx",
        },
      }
    `)
  })

  test('expand multiple references', () => {
    const result = css({
      html: {
        padding: 'token(spacing.3) token(spacing.5)',
        _hover: {
          padding: 'token(spacing.7)',
        },
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "&:is(:hover, [data-hover])": {
            "padding": "var(--spacing-7)",
          },
          "padding": "var(--spacing-3) var(--spacing-5)",
        },
      }
    `)
  })

  test('serialize divide utility', () => {
    const result = css({
      html: {
        divideY: '1px',
        divideColor: 'red',
      },
    })

    expect(result).toMatchInlineSnapshot(`
      {
        "html": {
          "& > :not([hidden]) ~ :not([hidden])": {
            "borderBottomWidth": "0px",
            "borderColor": "red",
            "borderTopWidth": "1px",
          },
        },
      }
    `)
  })
})
