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

vi.mock('@/api/fhirClient', () => ({
  fhirGet: vi.fn(),
  openFhirJsonInNewTab: 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" @input="$emit(\'update:modelValue\', \'patient-1\')" />',
  },
}))

import { fhirGet, openFhirJsonInNewTab } from '@/api/fhirClient'

const mockedFhirGet = vi.mocked(fhirGet)
const mockedOpenTab = vi.mocked(openFhirJsonInNewTab)

const patientBundle = {
  resourceType: 'Bundle',
  type: 'searchset',
  total: 1,
  entry: [
    {
      resource: {
        resourceType: 'Patient',
        id: 'patient-1',
        name: [{ text: 'MARIA SANTOS' }],
        identifier: [{ value: 'VCR-000001' }],
        birthDate: '1978-03-15',
        gender: 'female',
      },
    },
  ],
}

const everythingBundle = {
  resourceType: 'Bundle',
  type: 'searchset',
  total: 3,
  entry: [
    { resource: { resourceType: 'Patient', id: 'patient-1', name: [{ text: 'MARIA SANTOS' }] } },
    { resource: { resourceType: 'Encounter', id: 'enc-1', status: 'in-progress', period: { start: '2026-06-22' } } },
    {
      resource: {
        resourceType: 'Observation',
        id: 'obs-1',
        code: { coding: [{ code: '8867-4', display: 'Heart rate' }] },
        valueQuantity: { value: 88, unit: 'bpm' },
        effectiveDateTime: '2026-06-22T10:00:00Z',
      },
    },
  ],
}

beforeEach(() => {
  setActivePinia(createPinia())
  vi.clearAllMocks()
  mockedFhirGet.mockResolvedValue(patientBundle)
})

describe('FhirExplorerView', () => {
  it('renders resource browser and patient search fields by default', () => {
    const wrapper = mount(FhirExplorerView)

    expect(wrapper.text()).toContain('Resource Browser')
    expect(wrapper.text()).toContain('Patient $everything')
    expect(wrapper.find('select').element).toBeTruthy()
    expect(wrapper.text()).toContain('MRN (identifier)')
  })

  it('searches FHIR Patient resources and shows results table', async () => {
    const wrapper = mount(FhirExplorerView)

    await wrapper.find('input[placeholder="e.g. Santos"]').setValue('Santos')
    await wrapper.find('button.btn-primary').trigger('click')
    await flushPromises()

    expect(mockedFhirGet).toHaveBeenCalledWith('/Patient', {
      name: 'Santos',
      birthdate: undefined,
      identifier: undefined,
      _count: 20,
    })
    expect(wrapper.text()).toContain('MARIA SANTOS')
    expect(wrapper.text()).toContain('VCR-000001')
  })

  it('shows formatted JSON when a result row is clicked', async () => {
    const wrapper = mount(FhirExplorerView)

    await wrapper.find('button.btn-primary').trigger('click')
    await flushPromises()

    await wrapper.find('tbody tr').trigger('click')
    await flushPromises()

    expect(wrapper.text()).toContain('"resourceType": "Patient"')
    expect(wrapper.text()).toContain('"id": "patient-1"')
  })

  it('loads Patient $everything bundle grouped by resource type', async () => {
    mockedFhirGet.mockResolvedValue(everythingBundle)

    const wrapper = mount(FhirExplorerView)

    await wrapper.find('[data-testid="patient-search"]').trigger('input')
    await flushPromises()

    const loadButton = wrapper.findAll('button.btn-primary').find((b) =>
      b.text().includes('Load All Data')
    )
    expect(loadButton).toBeDefined()
    await loadButton!.trigger('click')
    await flushPromises()

    expect(mockedFhirGet).toHaveBeenCalledWith('/Patient/patient-1/$everything')
    expect(wrapper.text()).toContain('Encounters (1)')
    expect(wrapper.text()).toContain('Observations (1)')
    expect(wrapper.text()).toContain('Heart rate')
  })

  it('opens metadata CapabilityStatement in a new tab', async () => {
    mockedFhirGet.mockResolvedValueOnce({ resourceType: 'CapabilityStatement' })

    const wrapper = mount(FhirExplorerView)
    await wrapper.find('button.btn-secondary').trigger('click')
    await flushPromises()

    expect(mockedFhirGet).toHaveBeenCalledWith('/metadata')
    expect(mockedOpenTab).toHaveBeenCalled()
  })
})
