import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import { createMemoryHistory, createRouter } from 'vue-router'
import NotificationView from '../notification/NotificationView.vue'

// ── Hoisted mocks ────────────────────────────────────────────────────────────

let capturedChoreHandler: ((event: any) => void) | null = null
let capturedRewardHandler: ((event: any) => void) | null = null

vi.mock('@/common/eventBus', () => ({
  eventBus: {
    on: vi.fn((event: string, handler: (e: any) => void) => {
      if (event === 'child_chore_confirmation') capturedChoreHandler = handler
      if (event === 'child_reward_request') capturedRewardHandler = handler
    }),
    off: vi.fn(),
  },
}))

vi.mock('@/common/backendEvents', () => ({ useBackendEvents: vi.fn() }))

vi.mock('../shared/ItemList.vue', () => ({
  default: { template: '<div class="item-list-stub" />', props: ['fetchUrl', 'key'] },
}))

vi.mock('../shared/MessageBlock.vue', () => ({
  default: { template: '<div class="message-block-stub" />', props: ['message'] },
}))

// ── Router ───────────────────────────────────────────────────────────────────

const mockRouter = createRouter({
  history: createMemoryHistory(),
  routes: [
    { path: '/', name: 'Landing', component: { template: '<div />' } },
    { path: '/parent/:id', name: 'ParentView', component: { template: '<div />' } },
  ],
})

// ── Helpers ──────────────────────────────────────────────────────────────────

function mountView() {
  capturedChoreHandler = null
  capturedRewardHandler = null
  return mount(NotificationView, {
    global: { plugins: [mockRouter] },
  })
}

function fireChoreConfirmation(operation: string) {
  capturedChoreHandler?.({ payload: { operation, child_id: 'c1', task_id: 't1' } })
}

function fireRewardRequest(operation: string) {
  capturedRewardHandler?.({ payload: { operation, child_id: 'c1', reward_id: 'r1' } })
}

// ── Tests ────────────────────────────────────────────────────────────────────

describe('NotificationView – chore confirmation handler', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  const refreshingOperations = ['CONFIRMED', 'APPROVED', 'REJECTED', 'CANCELLED', 'RESET']

  refreshingOperations.forEach((op) => {
    it(`refreshes list on ${op} operation`, async () => {
      const wrapper = mountView()
      const before = (wrapper.vm as any).refreshKey
      fireChoreConfirmation(op)
      await flushPromises()
      expect((wrapper.vm as any).refreshKey).toBeGreaterThan(before)
    })
  })

  it('does not refresh on unknown operation', async () => {
    const wrapper = mountView()
    const before = (wrapper.vm as any).refreshKey
    fireChoreConfirmation('UNKNOWN_OP')
    await flushPromises()
    expect((wrapper.vm as any).refreshKey).toBe(before)
  })
})

describe('NotificationView – reward request handler', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  const refreshingOperations = ['CREATED', 'CANCELLED', 'GRANTED']

  refreshingOperations.forEach((op) => {
    it(`refreshes list on ${op} operation`, async () => {
      const wrapper = mountView()
      const before = (wrapper.vm as any).refreshKey
      fireRewardRequest(op)
      await flushPromises()
      expect((wrapper.vm as any).refreshKey).toBeGreaterThan(before)
    })
  })
})
