import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createI18n } from 'vue-i18n'

import ReservationOperaPanel from '@/components/reservation/ReservationOperaPanel.vue'
import zhCN from '@/i18n/locales/zh-CN'
import type { ReservationOperaOperationResult } from '@/types/reservation'

vi.mock('@/services/reservationService', async (importOriginal) => {
  const actual = await importOriginal<typeof import('@/services/reservationService')>()
  return {
    ...actual,
    executeReservationOperaOperation: vi.fn(),
    retryReservationOperaOperation: vi.fn(),
  }
})

const service = await import('@/services/reservationService')

function createOperation(): ReservationOperaOperationResult {
  return {
    operation_id: 'op-1',
    task_id: '10001',
    operation_sequence: 1,
    operation_code: 'CREATE_RESERVATION',
    operation_name: 'Create reservation',
    operation_status: 'PENDING',
    attempt_count: 0,
    last_error_message: null,
    attempts: [],
  }
}

function mountPanel() {
  const i18n = createI18n({
    legacy: false,
    locale: 'zh-CN',
    messages: {
      'zh-CN': zhCN,
    },
  })
  return mount(ReservationOperaPanel, {
    props: {
      taskId: '10001',
      operations: [createOperation()],
      executable: true,
    },
    global: {
      plugins: [i18n],
    },
  })
}

describe('ReservationOperaPanel', () => {
  beforeEach(() => {
    vi.mocked(service.executeReservationOperaOperation).mockReset()
    vi.mocked(service.retryReservationOperaOperation).mockReset()
  })

  it('shows operation errors when execute fails', async () => {
    vi.mocked(service.executeReservationOperaOperation).mockRejectedValue(new Error('OPERA is unavailable'))

    const wrapper = mountPanel()
    await wrapper.find('button[title="执行"]').trigger('click')
    await flushPromises()

    expect(wrapper.text()).toContain('OPERA is unavailable')
    expect(wrapper.find('button[title="执行"]').attributes('disabled')).toBeUndefined()
  })
})
