import { describe, it, expect, vi, beforeEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useLiveCaptureStore } from '@/stores/liveCapture'

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

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

const mockedPost = vi.mocked(post)

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

describe('useLiveCaptureStore', () => {
  describe('initial state', () => {
    it('has expected defaults', () => {
      const store = useLiveCaptureStore()
      expect(store.loading).toBe(false)
      expect(store.error).toBeNull()
      expect(store.lastResult).toBeNull()
    })
  })

  describe('recordObservations', () => {
    const observations = [
      { observationCode: 'HEART_RATE', value: 72, unit: 'bpm', recordedAt: '2026-06-27T10:00:00Z', note: '' },
    ]

    it('returns result on success', async () => {
      const responseData = {
        batchId: 'b1',
        encounterId: 'enc-1',
        observations: [
          {
            draftObservationId: 'do1',
            liveObservationId: 'lo1',
            observationCode: 'HEART_RATE',
            value: 72,
            unit: 'bpm',
            recordedAt: '2026-06-27T10:00:00Z',
            criticalAlert: null,
          },
        ],
        criticalAlertCount: 0,
        promotedAt: '2026-06-27T10:00:01Z',
      }
      mockedPost.mockResolvedValueOnce({ success: true, statusCode: 200, data: responseData, error: null })

      const store = useLiveCaptureStore()
      const result = await store.recordObservations('enc-1', observations, true, 'password')

      expect(result).toEqual(responseData)
      expect(store.lastResult).toEqual(responseData)
      expect(store.loading).toBe(false)
      expect(store.error).toBeNull()
    })

    it('throws and sets error on failure response', async () => {
      mockedPost.mockResolvedValueOnce({
        success: false,
        statusCode: 400,
        data: null,
        error: { message: 'Attestation required', code: 'VALIDATION' },
      })

      const store = useLiveCaptureStore()
      await expect(
        store.recordObservations('enc-1', observations, false, 'password'),
      ).rejects.toThrow('Attestation required')

      expect(store.error).toBe('Attestation required')
      expect(store.lastResult).toBeNull()
    })

    it('throws on network error', async () => {
      mockedPost.mockRejectedValueOnce(new Error('Network error'))

      const store = useLiveCaptureStore()
      await expect(
        store.recordObservations('enc-1', observations, true, 'password'),
      ).rejects.toThrow('Network error')

      expect(store.error).toBe('Network error')
    })
  })

  describe('openEncounterWithVitals', () => {
    const observations = [
      { observationCode: 'TEMP_C', value: 37.2, unit: 'C', recordedAt: '2026-06-27T10:00:00Z', note: '' },
    ]

    it('returns result on success', async () => {
      const responseData = {
        batchId: 'b2',
        encounterId: 'enc-new',
        observations: [],
        criticalAlertCount: 0,
        promotedAt: '2026-06-27T10:00:01Z',
      }
      mockedPost.mockResolvedValueOnce({ success: true, statusCode: 201, data: responseData, error: null })

      const store = useLiveCaptureStore()
      const result = await store.openEncounterWithVitals(
        'patient-1', 'ICU', '3A-12', 'Chest pain', observations, true, 'password',
      )

      expect(result).toEqual(responseData)
      expect(mockedPost).toHaveBeenCalledWith('live-capture/encounters', {
        patientId: 'patient-1',
        department: 'ICU',
        roomBed: '3A-12',
        admissionReason: 'Chest pain',
        observations: [
          { observationCode: 'TEMP_C', value: 37.2, unit: 'C', recordedAt: '2026-06-27T10:00:00Z', note: null },
        ],
        clinicianAttestation: true,
        passwordConfirm: 'password',
      })
    })

    it('sends null for empty roomBed', async () => {
      mockedPost.mockResolvedValueOnce({
        success: true,
        statusCode: 201,
        data: { batchId: 'b', encounterId: 'e', observations: [], criticalAlertCount: 0, promotedAt: '' },
        error: null,
      })

      const store = useLiveCaptureStore()
      await store.openEncounterWithVitals(
        'p1', 'ED', '', 'Fall', observations, true, 'pass',
      )

      expect(mockedPost).toHaveBeenCalledWith(
        'live-capture/encounters',
        expect.objectContaining({ roomBed: null }),
      )
    })
  })

  describe('reset', () => {
    it('clears lastResult and error', () => {
      const store = useLiveCaptureStore()
      store.error = 'some error'
      store.lastResult = { batchId: 'b', encounterId: 'e', observations: [], criticalAlertCount: 0, promotedAt: '' }

      store.reset()

      expect(store.lastResult).toBeNull()
      expect(store.error).toBeNull()
    })
  })
})
