<template>
  <div class="h-full min-h-0 flex flex-col" data-testid="entry-form">
    <div class="flex-1 min-h-0 overflow-y-auto p-4 space-y-4">
      <div class="flex items-start justify-between gap-3">
        <div>
          <p class="evidence-level evidence-level--2 mb-1">
            <span class="evidence-level-mark" aria-hidden="true">2</span>
            Structured draft
          </p>
          <h2 class="text-base font-semibold text-ink-strong">Data Entry</h2>
          <p
            class="mt-1 text-xs tabular-nums"
            :class="{
              'text-ink-secondary': saveState === 'saved' || saveState === 'idle',
              'text-ink-secondary animate-pulse': saveState === 'saving',
              'text-clinical-danger font-medium': saveState === 'failed',
            }"
            data-testid="entry-save-status"
          >
            {{ saveStatusLabel }}
          </p>
        </div>
        <StatusBadge :status="batch?.status" />
      </div>

      <div v-if="ocrConfidence" class="ocr-banner">
        Pre-filled by OCR ({{ ocrConfidence.provider }}) — review against the scan.
        OCR is assistive, not authoritative.
      </div>

      <!-- Patient section -->
      <fieldset class="workstation-form-section">
        <legend class="workstation-form-legend">Patient Demographics</legend>
        <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
          <div>
            <label class="workstation-field-label">
              Full Name
              <OcrConfidenceBadge :label="fieldConfidenceLabel('patient.fullName')" :level="fieldConfidenceLevel('patient.fullName')" />
            </label>
            <input
              v-model="patient.fullName"
              type="text"
              :class="['form-input', 'text-sm', 'py-1.5', fieldConfidenceClass('patient.fullName')]"
              @blur="savePatient"
            />
          </div>
          <div>
            <label class="workstation-field-label">
              Date of Birth
              <OcrConfidenceBadge :label="fieldConfidenceLabel('patient.dateOfBirth')" :level="fieldConfidenceLevel('patient.dateOfBirth')" />
            </label>
            <input
              v-model="patient.dateOfBirth"
              type="date"
              :class="['form-input', 'text-sm', 'py-1.5', fieldConfidenceClass('patient.dateOfBirth')]"
              @blur="savePatient"
            />
          </div>
          <div>
            <label class="workstation-field-label">
              Sex
              <OcrConfidenceBadge :label="fieldConfidenceLabel('patient.sex')" :level="fieldConfidenceLevel('patient.sex')" />
            </label>
            <select
              v-model="patient.sex"
              :class="['form-input', 'text-sm', 'py-1.5', fieldConfidenceClass('patient.sex')]"
              @change="savePatient"
            >
              <option value="">Select...</option>
              <option value="male">Male</option>
              <option value="female">Female</option>
              <option value="other">Other</option>
            </select>
          </div>
          <div>
            <label class="workstation-field-label">Blood Type</label>
            <select v-model="patient.bloodType" class="form-input text-sm py-1.5" @change="savePatient">
              <option value="">Unknown</option>
              <option v-for="bt in bloodTypes" :key="bt" :value="bt">{{ bt }}</option>
            </select>
          </div>
          <div class="md:col-span-2">
            <label class="workstation-field-label">Emergency Contact</label>
            <input
              v-model="patient.emergencyContact"
              type="text"
              class="form-input text-sm py-1.5"
              @blur="savePatient"
            />
          </div>
        </div>
      </fieldset>

      <!-- Allergies section (ALLERGY_UPDATE or MIXED) -->
      <fieldset v-if="showAllergies" class="workstation-form-section">
        <legend class="workstation-form-legend">Allergies</legend>
        <label class="flex items-center gap-2 mb-2 cursor-pointer">
          <input
            v-model="patient.noKnownAllergies"
            type="checkbox"
            class="w-4 h-4 text-clinical-safe rounded"
            @change="onNoKnownAllergiesChange"
          />
          <span class="text-sm">No known allergies (NKA)</span>
        </label>
        <div v-if="!patient.noKnownAllergies" class="space-y-2">
          <div
            v-for="(_allergy, idx) in allergies"
            :key="idx"
            class="flex items-center gap-2"
          >
            <input
              v-model="allergies[idx]"
              type="text"
              class="form-input text-sm py-1.5 flex-1"
              placeholder="Allergy (e.g. Penicillin)"
              @blur="saveAllergies"
            />
            <button
              type="button"
              class="text-clinical-danger hover:text-clinical-critical text-sm"
              @click="removeAllergy(idx)"
            >
              Remove
            </button>
          </div>
          <button type="button" class="text-sm text-primary-600 hover:text-primary-800" @click="addAllergy">
            + Add Allergy
          </button>
        </div>
      </fieldset>

      <!-- Medications section (MEDICATION_LIST or MIXED) -->
      <fieldset v-if="showMedications" class="workstation-form-section">
        <legend class="workstation-form-legend">Medications</legend>
        <label class="flex items-center gap-2 mb-2 cursor-pointer">
          <input
            v-model="patient.noActiveMedications"
            type="checkbox"
            class="w-4 h-4 text-clinical-safe rounded"
            @change="onNoActiveMedicationsChange"
          />
          <span class="text-sm">No active medications</span>
        </label>
        <div v-if="!patient.noActiveMedications" class="space-y-2">
          <div
            v-for="(_med, idx) in medications"
            :key="idx"
            class="flex items-center gap-2"
          >
            <input
              v-model="medications[idx]"
              type="text"
              class="form-input text-sm py-1.5 flex-1"
              placeholder="Medication (e.g. Metoprolol 50mg BID)"
              @blur="saveMedications"
            />
            <button
              type="button"
              class="text-clinical-danger hover:text-clinical-critical text-sm"
              @click="removeMedication(idx)"
            >
              Remove
            </button>
          </div>
          <button type="button" class="text-sm text-primary-600 hover:text-primary-800" @click="addMedication">
            + Add Medication
          </button>
        </div>
      </fieldset>

      <!-- Encounter section -->
      <fieldset class="workstation-form-section">
        <legend class="workstation-form-legend">Encounter Context</legend>
        <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
          <div>
            <label class="workstation-field-label">
              Admission Date
              <OcrConfidenceBadge :label="fieldConfidenceLabel('encounter.admissionDate')" :level="fieldConfidenceLevel('encounter.admissionDate')" />
            </label>
            <input
              v-model="encounter.admissionDate"
              type="datetime-local"
              :class="['form-input', 'text-sm', 'py-1.5', fieldConfidenceClass('encounter.admissionDate')]"
              @blur="saveEncounter"
            />
          </div>
          <div>
            <label class="workstation-field-label">
              Department
              <OcrConfidenceBadge :label="fieldConfidenceLabel('encounter.department')" :level="fieldConfidenceLevel('encounter.department')" />
            </label>
            <select
              v-model="encounter.department"
              :class="['form-input', 'text-sm', 'py-1.5', fieldConfidenceClass('encounter.department')]"
              @change="saveEncounter"
            >
              <option value="">—</option>
              <option v-for="dept in departments" :key="dept" :value="dept">{{ dept }}</option>
            </select>
          </div>
          <div>
            <label class="workstation-field-label">
              Room / Bed
              <OcrConfidenceBadge :label="fieldConfidenceLabel('encounter.roomBed')" :level="fieldConfidenceLevel('encounter.roomBed')" />
            </label>
            <input
              v-model="encounter.roomBed"
              type="text"
              :class="['form-input', 'text-sm', 'py-1.5', fieldConfidenceClass('encounter.roomBed')]"
              @blur="saveEncounter"
            />
          </div>
          <div>
            <label class="workstation-field-label">
              Admission Reason
              <OcrConfidenceBadge :label="fieldConfidenceLabel('encounter.admissionReason')" :level="fieldConfidenceLevel('encounter.admissionReason')" />
            </label>
            <input
              v-model="encounter.admissionReason"
              type="text"
              :class="['form-input', 'text-sm', 'py-1.5', fieldConfidenceClass('encounter.admissionReason')]"
              @blur="saveEncounter"
            />
          </div>
          <div v-if="showEncounterSummary">
            <label class="workstation-field-label">Encounter Status</label>
            <select v-model="encounter.status" class="form-input text-sm py-1.5" @change="saveEncounter">
              <option value="">—</option>
              <option value="active">Active</option>
              <option value="discharged">Discharged</option>
            </select>
          </div>
          <div v-if="showEncounterSummary" class="md:col-span-2">
            <label class="workstation-field-label">Discharge Diagnosis</label>
            <textarea
              v-model="encounter.dischargeDiagnosis"
              class="form-input text-sm py-1.5"
              rows="2"
              placeholder="Discharge diagnosis..."
              @blur="saveEncounter"
            />
          </div>
        </div>
      </fieldset>

      <!-- Observations section -->
      <fieldset class="workstation-form-section">
        <legend class="workstation-form-legend">Observations</legend>
        <div class="space-y-2">
          <ObservationRow
            v-for="obs in observations"
            :key="obs.id"
            :observation="obs"
            :value-input-class="observationValueConfidenceClass(obs.observationCode)"
            :ocr-label="fieldConfidenceLabel(`observation.${obs.observationCode}.value`)"
            :ocr-level="fieldConfidenceLevel(`observation.${obs.observationCode}.value`)"
            @update="(field, value) => handleObsUpdate(obs.id, field, value)"
            @delete="handleObsDelete"
          />
          <button type="button" class="btn-secondary text-sm py-1.5" @click="addObservation">
            + Add Observation
          </button>
        </div>
      </fieldset>

      <div v-if="errorMessage" class="text-clinical-danger text-sm" role="alert">
        {{ errorMessage }}
      </div>
    </div>

    <WorkstationActionBar>
      <template #center>
        <button
          type="button"
          class="btn-secondary"
          :disabled="saveState === 'saving' || submitting"
          @click="saveDraft"
        >
          Save Draft
        </button>
      </template>
      <template #primary>
        <div class="flex flex-col items-end gap-1">
          <p class="evidence-level evidence-level--3 mb-0 hidden sm:flex">
            <span class="evidence-level-mark" aria-hidden="true">3</span>
            Submit decision
          </p>
          <button
            type="button"
            class="btn-primary"
            :disabled="submitting || saveState === 'saving'"
            @click="submitForVerification"
          >
            {{ submitting ? 'Submitting...' : 'Submit for Verification' }}
          </button>
        </div>
      </template>
      <template v-if="nextBatchId" #right>
        <button
          type="button"
          class="btn-secondary"
          :disabled="submitting"
          data-testid="entry-next-batch"
          @click="emit('open-next', nextBatchId)"
        >
          Next
        </button>
      </template>
    </WorkstationActionBar>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { useBatchStore } from '../stores/batches'
import { useToast } from '../composables/useToast'
import { useOcrFieldConfidence } from '../composables/useOcrFieldConfidence'
import ObservationRow from '../components/ObservationRow.vue'
import StatusBadge from '../components/StatusBadge.vue'
import OcrConfidenceBadge from '../components/OcrConfidenceBadge.vue'
import WorkstationActionBar from '../components/WorkstationActionBar.vue'
import type { BatchDetailResponse, DraftObservation } from '../types'

const props = defineProps<{
  batch: BatchDetailResponse | null
  batchId: string
  /** Next batch in the current queue list, if any */
  nextBatchId?: string
}>()

const emit = defineEmits<{
  (e: 'open-next', id: string): void
}>()

const batchStore = useBatchStore()
const toast = useToast()
const submitting = ref(false)
const errorMessage = ref('')
const saveState = ref<'idle' | 'saving' | 'saved' | 'failed'>('idle')
const lastSavedAt = ref<Date | null>(null)

const saveStatusLabel = computed(() => {
  if (saveState.value === 'saving') return 'Saving…'
  if (saveState.value === 'failed') return 'Save failed'
  if (saveState.value === 'saved' && lastSavedAt.value) {
    return `Saved ${lastSavedAt.value.toLocaleTimeString()}`
  }
  return ''
})

const bloodTypes = ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-']
const departments = [
  'Emergency Department',
  'Internal Medicine',
  'General Medicine',
  'Surgery',
  'ICU',
  'NICU',
  'Medical-Surgical',
  'Outpatient Clinic',
  'Pediatrics',
  'Obstetrics & Gynecology',
  'Labor & Delivery',
  'Cardiology',
  'Orthopedics',
  'Neurology',
  'Oncology',
  'Radiology',
  'Laboratory',
  'Psychiatry',
  'Physical Therapy',
  'Anesthesiology',
]

const fieldReqs = computed(() => batchStore.currentDraft?.fieldRequirements)
const ocrConfidence = computed(() => batchStore.currentDraft?.ocrConfidence ?? null)
const {
  fieldConfidenceClass,
  fieldConfidenceLabel,
  fieldConfidenceLevel,
} = useOcrFieldConfidence(ocrConfidence)

function observationValueConfidenceClass(observationCode: string): string {
  if (!observationCode) return ''
  return fieldConfidenceClass(`observation.${observationCode}.value`)
}

const showAllergies = computed(() => fieldReqs.value?.showAllergies ?? false)
const showMedications = computed(() => fieldReqs.value?.showMedications ?? false)
const showEncounterSummary = computed(() => fieldReqs.value?.showEncounterSummaryFields ?? false)

const patient = reactive({
  fullName: '',
  dateOfBirth: '',
  sex: '',
  bloodType: '',
  emergencyContact: '',
  noKnownAllergies: false,
  noActiveMedications: false,
})

const allergies = ref<string[]>([])
const medications = ref<string[]>([])

const encounter = reactive({
  admissionDate: '',
  department: '',
  roomBed: '',
  admissionReason: '',
  dischargeDiagnosis: '',
  status: '',
})

const observations = ref<DraftObservation[]>([])

watch(
  () => batchStore.currentDraft,
  (draft) => {
    if (!draft) return
    if (draft.patient) {
      Object.assign(patient, {
        fullName: draft.patient.fullName ?? '',
        dateOfBirth: draft.patient.dateOfBirth ?? '',
        sex: draft.patient.sex ?? '',
        bloodType: draft.patient.bloodType ?? '',
        emergencyContact: draft.patient.emergencyContact ?? '',
        noKnownAllergies: draft.patient.noKnownAllergies ?? false,
        noActiveMedications: draft.patient.noActiveMedications ?? false,
      })
      allergies.value = draft.patient.allergies ?? []
      medications.value = draft.patient.medications ?? []
    }
    if (draft.encounter) {
      Object.assign(encounter, {
        admissionDate: draft.encounter.admissionDate?.substring(0, 16) ?? '',
        department: draft.encounter.department ?? '',
        roomBed: draft.encounter.roomBed ?? '',
        admissionReason: draft.encounter.admissionReason ?? '',
        dischargeDiagnosis: draft.encounter.dischargeDiagnosis ?? '',
        status: draft.encounter.status ?? '',
      })
    }
    observations.value = draft.observations ?? []
  },
  { immediate: true }
)

function addAllergy() {
  allergies.value.push('')
}

function removeAllergy(idx: number) {
  allergies.value.splice(idx, 1)
  saveAllergies()
}

async function withSaveFeedback(fn: () => Promise<void>) {
  saveState.value = 'saving'
  errorMessage.value = ''
  try {
    await fn()
    lastSavedAt.value = new Date()
    saveState.value = 'saved'
  } catch (e: unknown) {
    saveState.value = 'failed'
    const msg = e instanceof Error ? e.message : 'Failed to save'
    errorMessage.value = msg
    toast.error(msg)
    throw e
  }
}

async function saveAllergies() {
  await withSaveFeedback(async () => {
    await batchStore.saveDraftPatient(props.batchId, {
      ...patient,
      allergies: allergies.value.filter(a => a.trim()),
    })
  })
}

function onNoKnownAllergiesChange() {
  if (patient.noKnownAllergies) {
    allergies.value = []
  }
  savePatient()
}

function addMedication() {
  medications.value.push('')
}

function removeMedication(idx: number) {
  medications.value.splice(idx, 1)
  saveMedications()
}

async function saveMedications() {
  await withSaveFeedback(async () => {
    await batchStore.saveDraftPatient(props.batchId, {
      ...patient,
      medications: medications.value.filter(m => m.trim()),
    })
  })
}

function onNoActiveMedicationsChange() {
  if (patient.noActiveMedications) {
    medications.value = []
  }
  savePatient()
}

async function savePatient() {
  await withSaveFeedback(async () => {
    await batchStore.saveDraftPatient(props.batchId, {
      ...patient,
      allergies: patient.noKnownAllergies ? null : allergies.value.filter(a => a.trim()),
      medications: patient.noActiveMedications ? null : medications.value.filter(m => m.trim()),
    })
  })
}

async function saveEncounter() {
  await withSaveFeedback(async () => {
    await batchStore.saveDraftEncounter(props.batchId, encounter)
  })
}

async function saveDraft() {
  try {
    await withSaveFeedback(async () => {
      await batchStore.saveDraftPatient(props.batchId, {
        ...patient,
        allergies: patient.noKnownAllergies ? null : allergies.value.filter(a => a.trim()),
        medications: patient.noActiveMedications ? null : medications.value.filter(m => m.trim()),
      })
      await batchStore.saveDraftEncounter(props.batchId, encounter)
    })
  } catch {
    // Feedback already set
  }
}

async function addObservation() {
  await batchStore.addObservation(props.batchId, {
    observationCode: '',
    value: 0,
    unit: '',
    recordedAt: new Date().toISOString(),
    note: null,
  })
  observations.value = batchStore.currentDraft?.observations ?? []
}

async function handleObsUpdate(obsId: string, field: string, value: unknown) {
  const obs = observations.value.find((o) => o.id === obsId)
  if (!obs) return
  ;(obs as Record<string, unknown>)[field] = value
  await batchStore.updateObservation(props.batchId, obsId, obs)
}

async function handleObsDelete(obsId: string) {
  await batchStore.deleteObservation(props.batchId, obsId)
  observations.value = batchStore.currentDraft?.observations ?? []
}

async function submitForVerification() {
  submitting.value = true
  errorMessage.value = ''
  try {
    await batchStore.submitForVerification(props.batchId)
    toast.success('Batch submitted for verification')
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Submit failed'
    errorMessage.value = msg
    toast.error(msg)
  } finally {
    submitting.value = false
  }
}
</script>
