import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import IntakeView from '@/views/IntakeView.vue'

vi.mock('@/api/client', () => ({
  get: vi.fn(),
}))

vi.mock('@/composables/useToast', () => ({
  useToast: () => ({
    success: vi.fn(),
    error: vi.fn(),
  }),
}))

vi.mock('@/components/AppHeader.vue', () => ({
  default: { template: '<div />' },
}))

vi.mock('@/components/PatientSearch.vue', () => ({
  default: {
    props: ['modelValue'],
    emits: ['update:modelValue'],
    template: '<input data-testid="patient-search" />',
  },
}))

vi.mock('@/components/BatchList.vue', () => ({
  default: {
    props: ['batches', 'loading', 'showAssign'],
    emits: ['assign', 'select'],
    template: '<div data-testid="batch-list" />',
  },
}))

vi.mock('@/components/AssignClerkDialog.vue', () => ({
  default: {
    props: ['show', 'batchId'],
    emits: ['close', 'assigned'],
    template: '<div />',
  },
}))

const uploadBatchMock = vi.fn()

vi.mock('@/stores/batches', () => ({
  useBatchStore: () => ({
    batches: [],
    loading: false,
    listBatches: vi.fn(),
    uploadBatch: uploadBatchMock,
    assignBatch: vi.fn(),
  }),
}))

vi.mock('vue-router', () => ({
  useRoute: () => ({ query: {} }),
}))

import { get } from '@/api/client'

const mockedGet = vi.mocked(get)

const coverSheet = {
  id: 'cs-1',
  code: 'VCR-CS-A3F7B2D1',
  batchType: 'VITALS_SHEET',
  track: 'BACKFILL',
  patientId: 'patient-1',
  patientName: 'Maria Garcia',
  patientMrn: 'MRN-001',
  assignToUserId: null,
  assignToUserName: null,
  isUsed: false,
  batchId: null,
  createdAt: '2026-06-27T12:00:00Z',
  usedAt: null,
}

beforeEach(() => {
  setActivePinia(createPinia())
  vi.clearAllMocks()
  uploadBatchMock.mockResolvedValue({ id: 'batch-1', status: 'UPLOADED' })
})

describe('IntakeView cover sheet upload', () => {
  it('renders barcode input with autofocus and lookup button', () => {
    const wrapper = mount(IntakeView)
    const input = wrapper.find('input[placeholder="VCR-CS-XXXXXXXX"]')

    expect(wrapper.text()).toContain('Quick Upload with Cover Sheet')
    expect(input.exists()).toBe(true)
    expect(input.attributes('autofocus')).toBeDefined()
    expect(wrapper.find('button.btn-secondary').text()).toBe('Lookup')
  })

  it('looks up cover sheet on Enter and auto-fills form fields', async () => {
    mockedGet.mockResolvedValueOnce({
      success: true,
      statusCode: 200,
      data: coverSheet,
      error: null,
    })

    const wrapper = mount(IntakeView)
    const input = wrapper.find('input[placeholder="VCR-CS-XXXXXXXX"]')

    await input.setValue('VCR-CS-A3F7B2D1')
    await input.trigger('keydown.enter')
    await flushPromises()

    expect(mockedGet).toHaveBeenCalledWith('cover-sheets/lookup/VCR-CS-A3F7B2D1')
    expect(wrapper.text()).toContain('Cover Sheet Found')
    expect(wrapper.text()).toContain('Maria Garcia')
    expect((wrapper.findAll('select')[0].element as HTMLSelectElement).value).toBe('VITALS_SHEET')
    expect((wrapper.findAll('select')[1].element as HTMLSelectElement).value).toBe('BACKFILL')
  })

  it('uploads with coverSheetCode when cover sheet is resolved', async () => {
    mockedGet.mockResolvedValueOnce({
      success: true,
      statusCode: 200,
      data: coverSheet,
      error: null,
    })

    const wrapper = mount(IntakeView)

    await wrapper.find('input[placeholder="VCR-CS-XXXXXXXX"]').setValue('VCR-CS-A3F7B2D1')
    await wrapper.find('input[placeholder="VCR-CS-XXXXXXXX"]').trigger('keydown.enter')
    await flushPromises()

    const file = new File(['pdf'], 'scan.pdf', { type: 'application/pdf' })
    const fileInput = wrapper.find('input[type="file"]')
    Object.defineProperty(fileInput.element, 'files', { value: [file] })
    await fileInput.trigger('change')

    await wrapper.find('form').trigger('submit.prevent')
    await flushPromises()

    expect(uploadBatchMock).toHaveBeenCalledWith(
      file,
      'VITALS_SHEET',
      'BACKFILL',
      'patient-1',
      undefined,
      'VCR-CS-A3F7B2D1',
    )
    expect(wrapper.text()).toContain('Upload with Cover Sheet')
  })

  it('keeps manual upload available without a cover sheet', async () => {
    const wrapper = mount(IntakeView)

    expect(wrapper.text()).toContain('New Batch')
    expect(wrapper.text()).toContain('Upload and Create Batch')

    const file = new File(['pdf'], 'scan.pdf', { type: 'application/pdf' })
    const fileInput = wrapper.find('input[type="file"]')
    Object.defineProperty(fileInput.element, 'files', { value: [file] })
    await fileInput.trigger('change')
    await wrapper.findAll('select')[0].setValue('LAB_RESULTS')

    await wrapper.find('form').trigger('submit.prevent')
    await flushPromises()

    expect(uploadBatchMock).toHaveBeenCalledWith(
      file,
      'LAB_RESULTS',
      'BACKFILL',
      undefined,
      undefined,
      undefined,
    )
  })

  it('shows lookup error for unknown cover sheet', async () => {
    mockedGet.mockResolvedValueOnce({
      success: false,
      statusCode: 404,
      data: null,
      error: { message: 'Cover sheet not found.', code: 'COVER_SHEET_NOT_FOUND' },
    })

    const wrapper = mount(IntakeView)
    await wrapper.find('input[placeholder="VCR-CS-XXXXXXXX"]').setValue('VCR-CS-DEADBEEF')
    await wrapper.find('button.btn-secondary').trigger('click')
    await flushPromises()

    expect(wrapper.text()).toContain('Cover sheet not found.')
  })
})
