// Unit tests for routine components.

import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import RoutineEditView from '@/components/routine/RoutineEditView.vue'
import RoutineConfirmDialog from '@/components/child/RoutineConfirmDialog.vue'
import ModalDialog from '@/components/shared/ModalDialog.vue'

// Mock fetch globally
global.fetch = vi.fn()

describe('RoutineEditView.vue', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    ;(global.fetch as ReturnType<typeof vi.fn>).mockClear()
  })

  it('renders create form heading when no id prop provided', async () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    expect(wrapper.text()).toContain('Create Routine')
  })

  it('renders name and points inputs', () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    // EntityEditForm renders inputs with id matching field.name
    expect(wrapper.find('input[id="name"]').exists()).toBe(true)
    expect(wrapper.find('input[id="points"]').exists()).toBe(true)
  })

  it('shows Routine Tasks section', () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    expect(wrapper.text()).toContain('Routine Tasks')
  })

  it('shows empty state message when no tasks added', () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    expect(wrapper.text()).toContain('Add at least one task')
  })

  it('shows Add Task button by default', () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    expect(wrapper.text()).toContain('Add Task')
  })

  it('opens item form when Add Task button clicked', async () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    const addBtn = wrapper.find('.add-task-trigger')
    expect(addBtn.exists()).toBe(true)
    await addBtn.trigger('click')
    // Item form should appear with a task name input
    expect(wrapper.find('input[id="item-name"]').exists()).toBe(true)
  })

  it('allows typing a task name in the add form', async () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    await wrapper.find('.add-task-trigger').trigger('click')
    const itemInput = wrapper.find('input[id="item-name"]')
    await itemInput.setValue('Make Bed')
    expect((itemInput.element as HTMLInputElement).value).toBe('Make Bed')
  })

  it('adds item to list when Add button clicked with valid name', async () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    await wrapper.find('.add-task-trigger').trigger('click')
    await wrapper.find('input[id="item-name"]').setValue('Make Bed')
    await wrapper.find('.item-form-actions .btn-primary').trigger('click')
    await wrapper.vm.$nextTick()
    // The item name should now appear in the list
    expect(wrapper.text()).toContain('Make Bed')
  })

  it('renders Cancel and Create buttons', () => {
    const wrapper = mount(RoutineEditView, {
      props: { id: undefined },
    })
    const text = wrapper.text()
    expect(text).toContain('Cancel')
    expect(text).toContain('Create')
  })

  it('renders edit heading when id prop provided', async () => {
    ;(global.fetch as ReturnType<typeof vi.fn>)
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          id: 'r1',
          name: 'Morning Routine',
          points: 50,
          image_id: null,
          image_url: null,
        }),
      })
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({ items: [] }),
      })

    const wrapper = mount(RoutineEditView, {
      props: { id: 'r1' },
    })

    await wrapper.vm.$nextTick()
    await wrapper.vm.$nextTick()
    expect(wrapper.text()).toContain('Edit Routine')
  })
})

describe('RoutineConfirmDialog.vue', () => {
  const routine = {
    id: 'r1',
    name: 'Morning Routine',
    points: 20,
    custom_value: null,
    image_id: null,
    image_url: null,
    pending_status: null,
    pending_confirmation_id: null,
    schedule: null,
    items: [],
  }

  it('displays routine name', () => {
    const wrapper = mount(RoutineConfirmDialog, {
      props: { routine, childName: 'Timmy' },
      global: { components: { ModalDialog } },
    })

    expect(wrapper.text()).toContain('Morning Routine')
  })

  it('displays child name', () => {
    const wrapper = mount(RoutineConfirmDialog, {
      props: { routine, childName: 'Timmy' },
      global: { components: { ModalDialog } },
    })

    expect(wrapper.text()).toContain('Timmy')
  })

  it('emits confirm event when Yes button clicked', async () => {
    const wrapper = mount(RoutineConfirmDialog, {
      props: { routine, childName: 'Timmy' },
      global: { components: { ModalDialog } },
    })

    const buttons = wrapper.findAll('button')
    const confirmBtn = buttons.find((b) => b.text().toLowerCase().includes('yes'))
    if (confirmBtn) {
      await confirmBtn.trigger('click')
      expect(wrapper.emitted('confirm')).toBeTruthy()
    }
  })

  it('emits cancel event when Cancel button clicked', async () => {
    const wrapper = mount(RoutineConfirmDialog, {
      props: { routine, childName: 'Timmy' },
      global: { components: { ModalDialog } },
    })

    const buttons = wrapper.findAll('button')
    const cancelBtn = buttons.find((b) => b.text().toLowerCase().includes('cancel'))
    if (cancelBtn) {
      await cancelBtn.trigger('click')
      expect(wrapper.emitted('cancel')).toBeTruthy()
    }
  })
})
