<template>
  <div class="h-full min-h-0 flex flex-col">
    <AppHeader title="Live Capture" />

    <div class="flex-1 p-4 sm:p-6 lg:p-8 max-w-5xl mx-auto w-full">
      <!-- Mode selector tabs -->
      <div class="flex border-b mb-6">
        <button
          @click="mode = 'new'"
          class="px-6 py-3 text-sm font-medium border-b-2 transition-colors"
          :class="mode === 'new'
            ? 'border-primary-600 text-primary-600'
            : 'border-transparent text-gray-500 hover:text-gray-700'"
        >
          New Encounter
        </button>
        <button
          @click="mode = 'existing'"
          class="px-6 py-3 text-sm font-medium border-b-2 transition-colors"
          :class="mode === 'existing'
            ? 'border-primary-600 text-primary-600'
            : 'border-transparent text-gray-500 hover:text-gray-700'"
        >
          Existing Encounter
        </button>
      </div>

      <!-- New encounter mode -->
      <div v-if="mode === 'new'" class="space-y-6">
        <fieldset class="card">
          <legend class="text-sm font-medium text-gray-700 px-2">Patient</legend>
          <PatientSearch v-model="patientId" />
        </fieldset>

        <fieldset class="card">
          <legend class="text-sm font-medium text-gray-700 px-2">Encounter Details</legend>
          <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
            <div>
              <label class="block text-xs text-gray-500 mb-1">Department</label>
              <select v-model="department" class="form-input">
                <option value="">Select department...</option>
                <option v-for="dept in departments" :key="dept.value" :value="dept.value">
                  {{ dept.label }}
                </option>
              </select>
            </div>
            <div>
              <label class="block text-xs text-gray-500 mb-1">Room / Bed</label>
              <input v-model="roomBed" type="text" class="form-input" placeholder="e.g. 4B-12" />
            </div>
            <div class="sm:col-span-2">
              <label class="block text-xs text-gray-500 mb-1">Admission Reason</label>
              <input v-model="admissionReason" type="text" class="form-input" placeholder="Chief complaint or reason" />
            </div>
          </div>
        </fieldset>
      </div>

      <!-- Existing encounter mode -->
      <div v-if="mode === 'existing'" class="space-y-6">
        <fieldset class="card">
          <legend class="text-sm font-medium text-gray-700 px-2">Encounter</legend>
          <div>
            <label class="block text-xs text-gray-500 mb-1">Encounter ID</label>
            <input
              v-model="encounterId"
              type="text"
              class="form-input"
              placeholder="Enter existing encounter UUID"
            />
          </div>
        </fieldset>
      </div>

      <!-- Vitals entry -->
      <fieldset class="card mt-6">
        <legend class="text-sm font-medium text-gray-700 px-2">
          Vitals ({{ observations.length }})
        </legend>

        <div class="space-y-3">
          <div
            v-for="(obs, idx) in observations"
            :key="idx"
            class="p-4 bg-gray-50 rounded-md"
          >
            <div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3">
              <div class="col-span-2 sm:col-span-1">
                <label class="block text-xs text-gray-500 mb-1">Code</label>
                <select v-model="obs.observationCode" class="form-input text-sm" @change="autoFillUnit(obs)">
                  <option value="">Select...</option>
                  <option v-for="code in vitalCodes" :key="code.value" :value="code.value">
                    {{ code.label }}
                  </option>
                </select>
              </div>
              <div>
                <label class="block text-xs text-gray-500 mb-1">Value</label>
                <input
                  v-model.number="obs.value"
                  type="number"
                  step="0.01"
                  class="form-input text-sm"
                  inputmode="decimal"
                />
              </div>
              <div>
                <label class="block text-xs text-gray-500 mb-1">Unit</label>
                <input v-model="obs.unit" type="text" class="form-input text-sm" />
              </div>
              <div>
                <label class="block text-xs text-gray-500 mb-1">Recorded At</label>
                <input
                  v-model="obs.recordedAt"
                  type="datetime-local"
                  class="form-input text-sm"
                />
              </div>
              <div class="flex items-end gap-2">
                <div class="flex-1">
                  <label class="block text-xs text-gray-500 mb-1">Note</label>
                  <input v-model="obs.note" type="text" class="form-input text-sm" placeholder="Optional" />
                </div>
                <button
                  @click="removeObservation(idx)"
                  class="mb-0.5 text-clinical-danger hover:text-red-800 text-sm px-2 py-2"
                  :disabled="observations.length <= 1"
                >
                  Remove
                </button>
              </div>
            </div>
          </div>
        </div>

        <button
          @click="addObservation"
          class="mt-4 text-sm text-primary-600 hover:text-primary-800"
          :disabled="observations.length >= 10"
        >
          + Add Observation
        </button>
        <p v-if="observations.length >= 10" class="text-xs text-gray-400 mt-1">
          Maximum 10 observations per submission.
        </p>
      </fieldset>

      <!-- Attestation & password -->
      <fieldset class="card mt-6">
        <legend class="text-sm font-medium text-gray-700 px-2">Clinician Attestation</legend>
        <div class="space-y-4">
          <label class="flex items-start gap-3 cursor-pointer">
            <input
              v-model="clinicianAttestation"
              type="checkbox"
              class="w-5 h-5 mt-0.5 text-clinical-safe rounded"
            />
            <span class="text-sm">
              I attest that I have directly observed or performed these measurements and they are accurate to the best of my clinical judgment.
            </span>
          </label>
          <div>
            <label class="block text-xs text-gray-500 mb-1">Password Confirmation</label>
            <input
              v-model="passwordConfirm"
              type="password"
              class="form-input max-w-sm"
              placeholder="Re-enter your password to confirm"
              autocomplete="current-password"
            />
          </div>
        </div>
      </fieldset>

      <!-- Submit -->
      <div class="mt-6 flex flex-col sm:flex-row gap-4">
        <button
          @click="submit"
          class="btn-primary text-base px-8 py-3"
          :disabled="!canSubmit || store.loading"
        >
          {{ store.loading ? 'Submitting...' : 'Record Vitals' }}
        </button>
        <button
          v-if="lastResult"
          @click="resetForm"
          class="px-4 py-3 text-gray-600 hover:text-gray-800 text-sm"
        >
          Record More Vitals
        </button>
      </div>

      <!-- Error -->
      <div v-if="errorMessage" class="mt-4 bg-red-50 border border-red-200 rounded-md p-4 text-sm text-clinical-danger">
        {{ errorMessage }}
      </div>

      <!-- Success result -->
      <div v-if="lastResult" class="mt-6 space-y-4">
        <div class="bg-green-50 border border-green-200 rounded-md p-4">
          <p class="font-medium text-green-800">Vitals recorded and promoted successfully</p>
          <div class="text-sm text-green-700 mt-2 space-y-1">
            <p>Batch: {{ lastResult.batchId.substring(0, 8) }}...</p>
            <p>Encounter: {{ lastResult.encounterId.substring(0, 8) }}...</p>
            <p>Observations promoted: {{ lastResult.observations.length }}</p>
            <p>Promoted at: {{ new Date(lastResult.promotedAt).toLocaleString() }}</p>
          </div>
        </div>

        <!-- Critical alerts -->
        <div
          v-if="lastResult.criticalAlertCount > 0"
          class="bg-red-50 border-2 border-red-400 rounded-md p-4"
        >
          <div class="flex items-center gap-2 mb-3">
            <span class="text-red-700 font-bold text-lg">CRITICAL ALERTS ({{ lastResult.criticalAlertCount }})</span>
          </div>
          <div
            v-for="obs in lastResult.observations.filter(o => o.criticalAlert)"
            :key="obs.liveObservationId"
            class="bg-white border border-red-300 rounded p-3 mb-2 last:mb-0"
          >
            <p class="font-medium text-red-800">
              {{ formatCode(obs.observationCode) }}: {{ obs.value }} {{ obs.unit }}
            </p>
            <p class="text-sm text-red-700 mt-1">{{ obs.criticalAlert!.message }}</p>
            <div class="text-xs text-red-600 mt-1">
              <span>Severity: {{ obs.criticalAlert!.severity }}</span>
              <span class="ml-4">
                Threshold ({{ obs.criticalAlert!.thresholdBound.replace('_', ' ') }}):
                {{ obs.criticalAlert!.thresholdValue }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { useLiveCaptureStore } from '../stores/liveCapture'
import { useToast } from '../composables/useToast'
import AppHeader from '../components/AppHeader.vue'
import PatientSearch from '../components/PatientSearch.vue'
import type { LiveCaptureObservationInput } from '../types'

const store = useLiveCaptureStore()
const toast = useToast()

const mode = ref<'new' | 'existing'>('new')
const patientId = ref<string | undefined>()
const department = ref('')
const roomBed = ref('')
const admissionReason = ref('')
const encounterId = ref('')
const clinicianAttestation = ref(false)
const passwordConfirm = ref('')
const errorMessage = ref('')

const lastResult = computed(() => store.lastResult)

const departments = [
  { value: 'Emergency Department', label: 'Emergency Department' },
  { value: 'Internal Medicine', label: 'Internal Medicine' },
  { value: 'General Medicine', label: 'General Medicine' },
  { value: 'Surgery', label: 'Surgery' },
  { value: 'ICU', label: 'ICU' },
  { value: 'NICU', label: 'NICU' },
  { value: 'Medical-Surgical', label: 'Medical-Surgical' },
  { value: 'Outpatient Clinic', label: 'Outpatient Clinic' },
  { value: 'Pediatrics', label: 'Pediatrics' },
  { value: 'Obstetrics & Gynecology', label: 'Obstetrics & Gynecology' },
  { value: 'Labor & Delivery', label: 'Labor & Delivery' },
  { value: 'Cardiology', label: 'Cardiology' },
  { value: 'Orthopedics', label: 'Orthopedics' },
  { value: 'Neurology', label: 'Neurology' },
  { value: 'Oncology', label: 'Oncology' },
  { value: 'Radiology', label: 'Radiology' },
  { value: 'Laboratory', label: 'Laboratory' },
  { value: 'Psychiatry', label: 'Psychiatry' },
  { value: 'Physical Therapy', label: 'Physical Therapy' },
  { value: 'Anesthesiology', label: 'Anesthesiology' },
]

const vitalCodes = [
  { value: 'HEART_RATE', label: 'Heart Rate', unit: 'bpm' },
  { value: 'TEMP_C', label: 'Temperature', unit: '°C' },
  { value: 'BP_SYSTOLIC', label: 'BP Systolic', unit: 'mmHg' },
  { value: 'BP_DIASTOLIC', label: 'BP Diastolic', unit: 'mmHg' },
  { value: 'RESP_RATE', label: 'Respiratory Rate', unit: 'breaths/min' },
  { value: 'SPO2', label: 'SpO2', unit: '%' },
  { value: 'POTASSIUM_MEQ_L', label: 'Potassium', unit: 'mEq/L' },
  { value: 'GLUCOSE_MG_DL', label: 'Glucose', unit: 'mg/dL' },
  { value: 'WBC_K_UL', label: 'WBC', unit: '×10³/µL' },
  { value: 'LACTATE_MMOL_L', label: 'Lactate', unit: 'mmol/L' },
]

function nowLocal(): string {
  const d = new Date()
  d.setMinutes(d.getMinutes() - d.getTimezoneOffset())
  return d.toISOString().slice(0, 16)
}

function makeObservation(): LiveCaptureObservationInput {
  return { observationCode: '', value: null, unit: '', recordedAt: nowLocal(), note: '' }
}

const observations = ref<LiveCaptureObservationInput[]>([makeObservation()])

function addObservation() {
  if (observations.value.length < 10) {
    observations.value.push(makeObservation())
  }
}

function removeObservation(idx: number) {
  if (observations.value.length > 1) {
    observations.value.splice(idx, 1)
  }
}

function autoFillUnit(obs: LiveCaptureObservationInput) {
  const match = vitalCodes.find(c => c.value === obs.observationCode)
  if (match) obs.unit = match.unit
}

function formatCode(code: string): string {
  const match = vitalCodes.find(c => c.value === code)
  return match?.label ?? code
}

const canSubmit = computed(() => {
  const hasValidObs = observations.value.every(
    o => o.observationCode && o.value !== null && o.unit && o.recordedAt,
  )
  if (!hasValidObs || !clinicianAttestation.value || !passwordConfirm.value) return false

  if (mode.value === 'new') {
    return !!patientId.value && !!department.value && !!admissionReason.value
  }
  return !!encounterId.value.trim()
})

async function submit() {
  errorMessage.value = ''
  store.reset()

  const obs = observations.value.map(o => ({
    ...o,
    recordedAt: new Date(o.recordedAt).toISOString(),
  }))

  try {
    if (mode.value === 'new') {
      await store.openEncounterWithVitals(
        patientId.value!,
        department.value,
        roomBed.value,
        admissionReason.value,
        obs,
        clinicianAttestation.value,
        passwordConfirm.value,
      )
    } else {
      await store.recordObservations(
        encounterId.value.trim(),
        obs,
        clinicianAttestation.value,
        passwordConfirm.value,
      )
    }
    passwordConfirm.value = ''
    const result = store.lastResult
    if (result && result.criticalAlertCount > 0) {
      toast.warning(`Vitals recorded — ${result.criticalAlertCount} CRITICAL alert(s) generated`)
    } else {
      toast.success('Vitals recorded and promoted successfully')
    }
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Submission failed'
    errorMessage.value = msg
    toast.error(msg)
  }
}

function resetForm() {
  store.reset()
  errorMessage.value = ''
  observations.value = [makeObservation()]
  clinicianAttestation.value = false
  passwordConfirm.value = ''
  if (mode.value === 'existing') {
    encounterId.value = ''
  }
}
</script>
