import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount } from '@vue/test-utils'
import { nextTick } from 'vue'
import ImagePicker from '../ImagePicker.vue'

vi.mock('@/common/imageCache', () => ({
  getCachedImageUrl: vi.fn(async (imageId: string) => `blob:mock-url-${imageId}`),
  revokeImageUrl: vi.fn(),
  revokeAllImageUrls: vi.fn(),
}))

global.fetch = vi.fn()

async function flushPromises() {
  for (let i = 0; i < 5; i++) {
    await nextTick()
  }
}

describe('ImagePicker disabled behavior', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    const mockFetch = vi.fn()
    global.fetch = mockFetch
    mockFetch.mockResolvedValue({
      ok: true,
      json: async () => ({ ids: ['img1'] }),
    })
  })

  it('renders selectable images and action buttons', async () => {
    const wrapper = mount(ImagePicker, {
      props: { modelValue: null, imageType: 1, disabled: false },
    })
    await flushPromises()

    expect(wrapper.findAll('.selectable-image').length).toBeGreaterThan(0)
    expect(wrapper.find('button[aria-label="Add from device"]').exists()).toBe(true)
    expect(wrapper.find('button[aria-label="Add from camera"]').exists()).toBe(true)
  })

  it('disables image selection and action buttons when disabled is true', async () => {
    const wrapper = mount(ImagePicker, {
      props: { modelValue: null, imageType: 1, disabled: true },
    })
    await flushPromises()

    const image = wrapper.find('.selectable-image')
    expect(image.classes()).toContain('disabled')

    const addFromDevice = wrapper.find('button[aria-label="Add from device"]')
    const addFromCamera = wrapper.find('button[aria-label="Add from camera"]')
    expect((addFromDevice.element as HTMLButtonElement).disabled).toBe(true)
    expect((addFromCamera.element as HTMLButtonElement).disabled).toBe(true)
  })

  it('does not emit update:modelValue when a disabled image is clicked', async () => {
    const wrapper = mount(ImagePicker, {
      props: { modelValue: null, imageType: 1, disabled: true },
    })
    await flushPromises()

    const image = wrapper.find('.selectable-image')
    await image.trigger('click')

    expect(wrapper.emitted('update:modelValue')).toBeUndefined()
  })

  it('does not open file input when Add from device is clicked while disabled', async () => {
    const wrapper = mount(ImagePicker, {
      props: { modelValue: null, imageType: 1, disabled: true },
    })
    await flushPromises()

    const fileInput = wrapper.find('input[type="file"]').element as HTMLInputElement
    const clickSpy = vi.spyOn(fileInput, 'click')

    await wrapper.find('button[aria-label="Add from device"]').trigger('click')

    expect(clickSpy).not.toHaveBeenCalled()
  })

  it('opens the file input when Add from device is clicked while enabled', async () => {
    const wrapper = mount(ImagePicker, {
      props: { modelValue: null, imageType: 1, disabled: false },
    })
    await flushPromises()

    const fileInput = wrapper.find('input[type="file"]').element as HTMLInputElement
    const clickSpy = vi.spyOn(fileInput, 'click')

    await wrapper.find('button[aria-label="Add from device"]').trigger('click')

    expect(clickSpy).toHaveBeenCalled()
  })
})
