import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import Checkbox from '../src/components/Checkbox/Checkbox.vue'

describe('Checkbox', () => {
  it('renders slot content', () => {
    const wrapper = mount(Checkbox, { slots: { default: 'Option 1' } })
    expect(wrapper.text()).toContain('Option 1')
  })

  it('shows checked state when modelValue is true', () => {
    const wrapper = mount(Checkbox, { props: { modelValue: true } })
    expect(wrapper.find('.cb-box--checked').exists()).toBe(true)
  })

  it('shows indeterminate state when indeterminate is true', () => {
    const wrapper = mount(Checkbox, { props: { indeterminate: true } })
    expect(wrapper.find('.cb-box--indeterminate').exists()).toBe(true)
  })

  it('does not emit toggle when disabled', async () => {
    const wrapper = mount(Checkbox, {
      props: { disabled: true, modelValue: false },
      slots: { default: 'Disabled' },
    })

    await wrapper.find('label').trigger('click')
    expect(wrapper.emitted('update:modelValue')).toBeFalsy()
    expect(wrapper.find('label').classes()).toContain('cb--disabled')
  })

  it('keeps the checked glyph when disabled', () => {
    const wrapper = mount(Checkbox, {
      props: { disabled: true, modelValue: true },
      slots: { default: 'Checked disabled' },
    })

    expect(wrapper.find('.cb-box--checked').exists()).toBe(true)
    expect(wrapper.find('.cb-icon--selected').exists()).toBe(true)
    expect(wrapper.find('.cb-icon--selected svg').exists()).toBe(true)
  })

  it('keeps the indeterminate glyph when disabled', () => {
    const wrapper = mount(Checkbox, {
      props: { disabled: true, indeterminate: true },
      slots: { default: 'Some disabled' },
    })

    expect(wrapper.find('.cb-box--indeterminate').exists()).toBe(true)
    expect(wrapper.find('.cb-icon--minus').exists()).toBe(true)
    expect(wrapper.find('.cb-icon--minus svg').exists()).toBe(true)
  })

  it('exposes checkbox role and reflects aria-checked state', () => {
    const off = mount(Checkbox, { props: { modelValue: false } })
    const label = off.find('label')
    expect(label.attributes('role')).toBe('checkbox')
    expect(label.attributes('tabindex')).toBe('0')
    expect(label.attributes('aria-checked')).toBe('false')

    const on = mount(Checkbox, { props: { modelValue: true } })
    expect(on.find('label').attributes('aria-checked')).toBe('true')

    const mixed = mount(Checkbox, { props: { indeterminate: true } })
    expect(mixed.find('label').attributes('aria-checked')).toBe('mixed')
  })

  it('toggles via keyboard Space and Enter', async () => {
    const wrapper = mount(Checkbox, { props: { modelValue: false } })
    await wrapper.find('label').trigger('keydown', { key: ' ' })
    expect(wrapper.emitted('update:modelValue')![0]).toEqual([true])
    await wrapper.find('label').trigger('keydown', { key: 'Enter' })
    expect(wrapper.emitted('update:modelValue')![1]).toEqual([true])
  })

  it('is not keyboard-focusable or toggleable when disabled', async () => {
    const wrapper = mount(Checkbox, { props: { disabled: true, modelValue: false } })
    expect(wrapper.find('label').attributes('tabindex')).toBe('-1')
    expect(wrapper.find('label').attributes('aria-disabled')).toBe('true')
    await wrapper.find('label').trigger('keydown', { key: ' ' })
    expect(wrapper.emitted('update:modelValue')).toBeFalsy()
  })

  // CANONICAL-012: display-only mode for embedding inside a host click target.
  it('readonly mode drops interaction + ARIA and is aria-hidden', async () => {
    const wrapper = mount(Checkbox, { props: { readonly: true, modelValue: true } })
    const label = wrapper.find('label')
    expect(label.attributes('role')).toBeUndefined()
    expect(label.attributes('tabindex')).toBeUndefined()
    expect(label.attributes('aria-checked')).toBeUndefined()
    expect(label.attributes('aria-hidden')).toBe('true')
    expect(label.classes()).toContain('cb--readonly')
    // still renders the checked glyph (purely presentational)
    expect(wrapper.find('.cb-box--checked').exists()).toBe(true)
  })

  it('readonly mode does not emit on click or keyboard', async () => {
    const wrapper = mount(Checkbox, { props: { readonly: true, modelValue: false } })
    await wrapper.find('label').trigger('click')
    await wrapper.find('label').trigger('keydown', { key: ' ' })
    await wrapper.find('label').trigger('keydown', { key: 'Enter' })
    expect(wrapper.emitted('update:modelValue')).toBeFalsy()
  })
})
