import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import SeedUpload from './SeedUpload'

const mocks = vi.hoisted(() => ({
  uploadSeed: vi.fn(),
}))

vi.mock('../api/client', async (importOriginal) => ({
  ...(await importOriginal<typeof import('../api/client')>()),
  uploadSeed: mocks.uploadSeed,
}))

beforeEach(() => {
  mocks.uploadSeed.mockReset()
})

function selectFile() {
  const file = new File(['dummy'], 'seed.xlsx', {
    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  })
  const input = document.querySelector('input[type="file"]') as HTMLInputElement
  fireEvent.change(input, { target: { files: [file] } })
}

describe('SeedUpload', () => {
  /**
   * Finding I3 회귀 테스트: 업로드가 진행 중일 때 버튼을 다시 누르면 두 번째 업로드
   * 요청이 겹쳐서 나갈 수 있다. 업로드 promise가 아직 풀리지 않은 동안 버튼이
   * 비활성화되는지 검증한다.
   */
  it('업로드가 진행 중이면 버튼이 비활성화된다', async () => {
    let resolvePromise: (value: { created: number; updated: number; total: number }) => void =
      () => {}
    mocks.uploadSeed.mockReturnValue(
      new Promise((resolve) => {
        resolvePromise = resolve
      }),
    )

    render(<SeedUpload onUploaded={() => {}} />)

    selectFile()

    await waitFor(() => {
      expect(screen.getByRole('button', { name: '신청목록 시트 올리기' })).toBeDisabled()
    })

    resolvePromise({ created: 1, updated: 0, total: 1 })

    await waitFor(() => {
      expect(screen.getByRole('button', { name: '신청목록 시트 올리기' })).toBeEnabled()
    })
  })
})
