import { describe, it, expect } from 'vitest'
import { defineComponent, h, nextTick, ref } from 'vue'
import { mount } from '@vue/test-utils'
import { defaultLocale, provideTvuLocale, useLocale, TVU_LOCALE_KEY } from '../src/locale'

// Mount a child that captures useLocale(); optional parent provides a locale.
function harness(provided?: unknown) {
  let captured: ReturnType<typeof useLocale> | undefined
  const Child = defineComponent({
    setup() {
      captured = useLocale()
      return () => h('div')
    },
  })
  const Parent = defineComponent({
    setup() {
      if (provided !== undefined) provideTvuLocale(provided as never)
      return () => h(Child)
    },
  })
  const wrapper = mount(Parent)
  return { get: () => captured!, wrapper }
}

describe('useLocale', () => {
  it('returns the English defaults with no provider', () => {
    const { get } = harness()
    expect(get().value).toEqual(defaultLocale)
    expect(get().value.close).toBe('Close')
  })

  it('merges an injected partial over the defaults', () => {
    const { get } = harness({ close: '关闭', previous: '上一页' })
    expect(get().value.close).toBe('关闭')
    expect(get().value.previous).toBe('上一页')
    // untouched keys keep English defaults
    expect(get().value.next).toBe('Next')
    expect(get().value.pageUnit).toBe('Page')
  })

  it('is reactive to a provided ref', async () => {
    const loc = ref({ close: 'A' })
    const { get } = harness(loc)
    expect(get().value.close).toBe('A')
    loc.value = { close: 'B' }
    await nextTick()
    expect(get().value.close).toBe('B')
  })

  it('defaultLocale is frozen (cannot be mutated by a consumer)', () => {
    expect(Object.isFrozen(defaultLocale)).toBe(true)
  })

  it('exposes the injection key for direct app.provide use', () => {
    expect(typeof TVU_LOCALE_KEY).toBe('symbol')
  })
})
