<template>
  <!-- Read-only: activity-list row — bold value, timestamp meta, optional OK -->
  <div
    v-if="readonly"
    class="observation-card observation-card--readonly"
    :class="{ 'observation-card--verified': showVerified && verified }"
    data-testid="observation-row"
  >
    <div class="observation-card__rail" aria-hidden="true">
      <span class="observation-card__dot" />
    </div>

    <div class="min-w-0 flex-1">
      <div class="flex items-start justify-between gap-2">
        <div class="min-w-0">
          <p class="text-xs font-semibold uppercase tracking-wide text-ink-secondary">
            {{ codeLabel }}
          </p>
          <p
            class="mt-0.5 flex flex-wrap items-baseline gap-x-1.5 gap-y-0.5 tabular-nums"
            :class="valueInputClass || 'text-ink-strong'"
          >
            <span class="text-xl font-bold leading-tight tracking-tight">
              {{ displayValue }}
            </span>
            <span
              v-if="observation.unit"
              class="text-sm font-medium text-ink-secondary"
            >
              {{ observation.unit }}
            </span>
          </p>
          <p
            v-if="recordedAtLabel"
            class="mt-1 text-[11px] leading-snug text-ink-secondary"
          >
            {{ recordedAtLabel }}
          </p>
          <p
            v-if="observation.note"
            class="mt-1 text-xs text-ink"
          >
            <span class="text-ink-secondary">Note:</span>
            {{ observation.note }}
          </p>
          <OcrConfidenceBadge
            v-if="ocrLabel"
            class="mt-1"
            :label="ocrLabel"
            :level="ocrLevel"
          />
        </div>

        <label
          v-if="showVerified"
          class="inline-flex shrink-0 items-center gap-1.5 rounded-input border px-2 py-1 text-xs font-semibold cursor-pointer transition-colors"
          :class="verified
            ? 'border-clinical-safe bg-clinical-safe-bg text-clinical-safe'
            : 'border-line bg-surface text-ink-secondary hover:border-primary-300'"
        >
          <input
            type="checkbox"
            class="w-3.5 h-3.5 text-clinical-safe rounded"
            :checked="verified"
            @change="$emit('verify', observation.id, ($event.target as HTMLInputElement).checked)"
          />
          OK
        </label>
      </div>
    </div>
  </div>

  <!-- Editable: card with hero value, then secondary fields (not a 5-col crunch) -->
  <div
    v-else
    class="observation-card"
    data-testid="observation-row"
  >
    <div class="flex items-start justify-between gap-2 mb-2.5">
      <div class="min-w-0 flex-1">
        <label class="workstation-field-label">Observation</label>
        <select
          :value="observation.observationCode"
          class="form-input text-sm font-semibold py-1.5"
          @change="onCodeChange(($event.target as HTMLSelectElement).value)"
        >
          <option value="">Select code…</option>
          <option
            v-for="opt in CODE_OPTIONS"
            :key="opt.value"
            :value="opt.value"
          >
            {{ opt.label }}
          </option>
        </select>
      </div>
      <button
        v-if="canDelete"
        type="button"
        class="shrink-0 mt-5 text-sm font-medium text-clinical-danger hover:text-clinical-critical"
        @click="$emit('delete', observation.id)"
      >
        Remove
      </button>
    </div>

    <div class="flex items-end gap-2 mb-2.5">
      <div class="min-w-0 flex-[1.4]">
        <label class="workstation-field-label">
          Value
          <OcrConfidenceBadge :label="ocrLabel" :level="ocrLevel" />
        </label>
        <input
          :value="observation.value"
          type="number"
          step="0.01"
          :class="[
            'form-input text-xl font-bold tabular-nums py-1.5 leading-none',
            valueInputClass,
          ]"
          @change="update('value', parseFloat(($event.target as HTMLInputElement).value))"
        />
      </div>
      <div class="w-[4.75rem] shrink-0">
        <label class="workstation-field-label">Unit</label>
        <input
          :value="observation.unit"
          type="text"
          class="form-input text-sm py-1.5"
          @change="update('unit', ($event.target as HTMLInputElement).value)"
        />
      </div>
    </div>

    <div class="grid grid-cols-1 gap-2">
      <div>
        <label class="workstation-field-label">Recorded at</label>
        <input
          :value="observation.recordedAt?.substring(0, 16)"
          type="datetime-local"
          class="form-input text-sm py-1.5"
          @change="update('recordedAt', ($event.target as HTMLInputElement).value)"
        />
      </div>
      <div>
        <label class="workstation-field-label">Note</label>
        <input
          :value="observation.note"
          type="text"
          class="form-input text-sm py-1.5"
          placeholder="Optional"
          @change="update('note', ($event.target as HTMLInputElement).value)"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import type { OcrConfidenceLevel } from '../composables/useOcrFieldConfidence'
import OcrConfidenceBadge from './OcrConfidenceBadge.vue'

/** Minimal observation shape for editable/readonly cards (DraftObservation satisfies this). */
export interface ObservationRowModel {
  id: string
  observationCode: string
  value: number | null
  unit: string | null
  recordedAt: string | null
  note: string | null
}

const CODE_OPTIONS = [
  { value: 'HEART_RATE', label: 'Heart Rate', unit: 'bpm' },
  { value: 'TEMP_C', label: 'Temperature (C)', 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' },
] as const

const props = withDefaults(
  defineProps<{
    observation: ObservationRowModel
    readonly?: boolean
    showVerified?: boolean
    verified?: boolean
    canDelete?: boolean
    valueInputClass?: string
    ocrLabel?: string | null
    ocrLevel?: OcrConfidenceLevel | null
  }>(),
  {
    canDelete: true,
  },
)

const emit = defineEmits<{
  (e: 'update', field: string, value: unknown): void
  (e: 'delete', obsId: string): void
  (e: 'verify', obsId: string, passed: boolean): void
}>()

const codeLabel = computed(() => {
  const code = props.observation.observationCode
  if (!code) return 'Unspecified observation'
  return CODE_OPTIONS.find((o) => o.value === code)?.label ?? code.replace(/_/g, ' ')
})

const displayValue = computed(() => {
  const value = props.observation.value
  if (value == null || Number.isNaN(Number(value))) return '—'
  return String(value)
})

const recordedAtLabel = computed(() => {
  const raw = props.observation.recordedAt
  if (!raw) return null
  const date = new Date(raw)
  if (Number.isNaN(date.getTime())) return raw
  return date.toLocaleString(undefined, {
    dateStyle: 'medium',
    timeStyle: 'short',
  })
})

function update(field: string, value: unknown) {
  emit('update', field, value)
}

function onCodeChange(code: string) {
  emit('update', 'observationCode', code)
  const match = CODE_OPTIONS.find((o) => o.value === code)
  if (match?.unit) {
    emit('update', 'unit', match.unit)
  }
}
</script>
