<template>
  <div class="h-full min-h-0 flex flex-col" data-testid="verification-form">
    <div class="flex-1 min-h-0 overflow-y-auto p-4 space-y-4">
      <div class="flex items-center justify-between gap-3">
        <div>
          <p class="evidence-level evidence-level--2 mb-1">
            <span class="evidence-level-mark" aria-hidden="true">2</span>
            Verified draft
          </p>
          <h2 class="text-base font-semibold text-ink-strong">Verification Review</h2>
        </div>
        <StatusBadge :status="batch?.status ?? 'PENDING_VERIFICATION'" />
      </div>

      <div
        v-if="batch?.rejectionReason"
        class="rounded-input border border-[#FECDCA] bg-clinical-danger-bg p-3"
      >
        <p class="text-sm font-medium text-clinical-danger">Previous Rejection Reason:</p>
        <p class="text-sm text-ink mt-1">{{ batch.rejectionReason }}</p>
      </div>

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

      <SeparationOfDutiesBanner
        v-model:blocked="sodBlocked"
        :entered-by-user-id="batch?.enteredByUserId"
        :entered-by-user-name="enteredByDisplayName"
        :current-user-id="auth.userId"
        :current-user-name="auth.userFullName"
      />

      <!-- Patient review -->
      <fieldset v-if="patientFields.length > 0" class="workstation-form-section">
        <legend class="workstation-form-legend">Patient Demographics</legend>
        <div class="space-y-2.5">
          <VerificationFieldCard
            v-for="field in patientFields"
            :key="field.path"
            :label="field.label"
            :value="field.value"
            :checked="fieldChecks[field.path] ?? false"
            :value-class="fieldConfidenceClass(field.path)"
            :ocr-label="fieldConfidenceLabel(field.path)"
            :ocr-level="fieldConfidenceLevel(field.path)"
            @toggle="(passed) => toggleCheck(field.path, passed)"
          />
        </div>
      </fieldset>

      <!-- Allergies review -->
      <fieldset v-if="allergyFields.length > 0" class="workstation-form-section">
        <legend class="workstation-form-legend">Allergies</legend>
        <div class="space-y-2.5">
          <VerificationFieldCard
            v-for="field in allergyFields"
            :key="field.path"
            :label="field.label"
            :value="field.value"
            :checked="fieldChecks[field.path] ?? false"
            :value-class="fieldConfidenceClass(field.path)"
            :ocr-label="fieldConfidenceLabel(field.path)"
            :ocr-level="fieldConfidenceLevel(field.path)"
            @toggle="(passed) => toggleCheck(field.path, passed)"
          />
        </div>
      </fieldset>

      <!-- Medications review -->
      <fieldset v-if="medicationFields.length > 0" class="workstation-form-section">
        <legend class="workstation-form-legend">Medications</legend>
        <div class="space-y-2.5">
          <VerificationFieldCard
            v-for="field in medicationFields"
            :key="field.path"
            :label="field.label"
            :value="field.value"
            :checked="fieldChecks[field.path] ?? false"
            :value-class="fieldConfidenceClass(field.path)"
            :ocr-label="fieldConfidenceLabel(field.path)"
            :ocr-level="fieldConfidenceLevel(field.path)"
            @toggle="(passed) => toggleCheck(field.path, passed)"
          />
        </div>
      </fieldset>

      <!-- Encounter review -->
      <fieldset
        v-if="showEncounterContext && encounterFields.length > 0"
        class="workstation-form-section"
      >
        <legend class="workstation-form-legend">Encounter Context</legend>
        <div class="space-y-2.5">
          <VerificationFieldCard
            v-for="field in encounterFields"
            :key="field.path"
            :label="field.label"
            :value="field.value"
            :checked="fieldChecks[field.path] ?? false"
            :value-class="fieldConfidenceClass(field.path)"
            :ocr-label="fieldConfidenceLabel(field.path)"
            :ocr-level="fieldConfidenceLevel(field.path)"
            @toggle="(passed) => toggleCheck(field.path, passed)"
          />
        </div>
      </fieldset>

      <!-- Observations review -->
      <fieldset
        v-if="showObservations"
        class="workstation-form-section"
      >
        <legend class="workstation-form-legend">
          Observations ({{ observations.length }})
        </legend>
        <p
          v-if="observations.length === 0"
          class="text-sm text-ink-secondary"
        >
          No observations recorded.
        </p>
        <div v-else class="space-y-3">
          <ObservationRow
            v-for="(obs, index) in observations"
            :key="obs.id"
            :observation="obs"
            :readonly="true"
            :show-verified="true"
            :verified="fieldChecks[`observations[${index}].value`] ?? false"
            :value-input-class="observationValueConfidenceClass(obs.observationCode)"
            :ocr-label="fieldConfidenceLabel(`observation.${obs.observationCode}.value`)"
            :ocr-level="fieldConfidenceLevel(`observation.${obs.observationCode}.value`)"
            @verify="(_obsId, passed) => toggleCheck(`observations[${index}].value`, passed)"
          />
        </div>
      </fieldset>

      <!-- Verification progress (field checks only — not analytics chrome) -->
      <div class="rounded-input border border-line bg-canvas p-3">
        <div class="flex items-center justify-between text-sm">
          <span class="text-ink-secondary">Fields verified:</span>
          <span :class="allChecked ? 'text-clinical-safe font-semibold' : 'text-ink'">
            {{ checkedCount }} / {{ totalFields }}
          </span>
        </div>
        <div class="w-full bg-line rounded-full h-1.5 mt-2">
          <div
            class="bg-clinical-safe h-1.5 rounded-full transition-all"
            :style="{ width: `${(checkedCount / Math.max(totalFields, 1)) * 100}%` }"
          />
        </div>
      </div>

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

      <AuditTrailPanel :batch-id="batchId" />
    </div>

    <WorkstationActionBar>
      <template #center>
        <div class="flex flex-col gap-2">
          <p class="evidence-level evidence-level--3 mb-0">
            <span class="evidence-level-mark" aria-hidden="true">3</span>
            Verification decision
          </p>
          <div class="flex flex-wrap items-center gap-4 text-sm" role="radiogroup" aria-label="Verification decision">
            <label class="inline-flex items-center gap-2 cursor-pointer">
              <input
                v-model="decision"
                type="radio"
                value="pass"
                class="text-clinical-safe"
                :disabled="sodBlocked || processing"
              />
              <span :class="sodBlocked ? 'text-ink-disabled' : 'text-ink'">Pass</span>
            </label>
            <label class="inline-flex items-center gap-2 cursor-pointer">
              <input
                v-model="decision"
                type="radio"
                value="reject"
                class="text-clinical-danger"
                :disabled="sodBlocked || processing"
              />
              <span :class="sodBlocked ? 'text-ink-disabled' : 'text-ink'">Reject</span>
            </label>
          </div>
        </div>
      </template>
      <template #primary>
        <button
          v-if="decision === 'pass'"
          type="button"
          class="btn-primary"
          :disabled="!allChecked || processing || sodBlocked"
          data-testid="verify-pass"
          @click="approveVerification"
        >
          {{ processing ? 'Processing...' : 'Pass Verification' }}
        </button>
        <button
          v-else-if="decision === 'reject'"
          type="button"
          class="btn-danger"
          :disabled="processing || sodBlocked"
          data-testid="verify-return"
          @click="showRejectDialog = true"
        >
          Return for Rework
        </button>
      </template>
    </WorkstationActionBar>

    <ConfirmDialog
      :open="showRejectDialog"
      title="Return for Rework"
      body="This returns the batch for rework. A reason is required."
      confirm-label="Return for Rework"
      variant="danger"
      :confirm-disabled="!rejectionReason.trim() || processing"
      @confirm="rejectVerification"
      @cancel="showRejectDialog = false"
    >
      <textarea
        v-model="rejectionReason"
        class="form-input"
        rows="4"
        placeholder="Reason for rejection (required)..."
      />
    </ConfirmDialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '../stores/auth'
import { useBatchStore } from '../stores/batches'
import { useToast } from '../composables/useToast'
import { useOcrFieldConfidence } from '../composables/useOcrFieldConfidence'
import ObservationRow from '../components/ObservationRow.vue'
import VerificationFieldCard from '../components/VerificationFieldCard.vue'
import StatusBadge from '../components/StatusBadge.vue'
import SeparationOfDutiesBanner from '../components/SeparationOfDutiesBanner.vue'
import ConfirmDialog from '../components/ConfirmDialog.vue'
import WorkstationActionBar from '../components/WorkstationActionBar.vue'
import AuditTrailPanel from '../components/AuditTrailPanel.vue'
import type { BatchDetailResponse, DraftObservation } from '../types'

const props = defineProps<{
  batch: BatchDetailResponse | null
  batchId: string
}>()

const auth = useAuthStore()
const batchStore = useBatchStore()
const router = useRouter()
const toast = useToast()
const processing = ref(false)
const errorMessage = ref('')
const showRejectDialog = ref(false)
const rejectionReason = ref('')
const sodBlocked = ref(false)
const decision = ref<'pass' | 'reject' | null>(null)

const fieldChecks = ref<Record<string, boolean>>({})
const observations = ref<DraftObservation[]>([])

interface FieldInfo {
  path: string
  label: string
  value: string
}

const patientFields = ref<FieldInfo[]>([])
const allergyFields = ref<FieldInfo[]>([])
const medicationFields = ref<FieldInfo[]>([])
const encounterFields = ref<FieldInfo[]>([])

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 showEncounterContext = computed(() => fieldReqs.value?.showEncounterContext ?? false)
const showObservations = computed(() => fieldReqs.value?.showObservations ?? false)

const enteredByDisplayName = computed(() => {
  const name = props.batch?.enteredByUserName?.trim()
  if (name) return name
  const fromQueue = batchStore.batches.find((b) => b.id === props.batchId)
  return fromQueue?.enteredByUserName?.trim() || null
})

watch(
  () => batchStore.currentDraft,
  (draft) => {
    if (!draft) return

    observations.value = draft.observations ?? []

    if (draft.patient) {
      patientFields.value = [
        { path: 'patient.fullName', label: 'Full Name', value: draft.patient.fullName ?? '' },
        { path: 'patient.dateOfBirth', label: 'Date of Birth', value: draft.patient.dateOfBirth ?? '' },
        { path: 'patient.sex', label: 'Sex', value: draft.patient.sex ?? '' },
        { path: 'patient.bloodType', label: 'Blood Type', value: draft.patient.bloodType ?? '' },
        { path: 'patient.emergencyContact', label: 'Emergency Contact', value: draft.patient.emergencyContact ?? '' },
      ]

      allergyFields.value = []
      if (showAllergies.value) {
        if (draft.patient.noKnownAllergies) {
          allergyFields.value = [
            { path: 'patient.noKnownAllergies', label: 'No Known Allergies', value: 'Yes (NKA)' },
          ]
        } else {
          const items = draft.patient.allergies ?? []
          allergyFields.value = items.map((item, i) => ({
            path: `patient.allergies[${i}]`,
            label: `Allergy ${i + 1}`,
            value: item,
          }))
          if (items.length === 0) {
            allergyFields.value = [
              { path: 'patient.allergies', label: 'Allergies', value: '(none entered)' },
            ]
          }
        }
      }

      medicationFields.value = []
      if (showMedications.value) {
        if (draft.patient.noActiveMedications) {
          medicationFields.value = [
            { path: 'patient.noActiveMedications', label: 'No Active Medications', value: 'Yes' },
          ]
        } else {
          const items = draft.patient.medications ?? []
          medicationFields.value = items.map((item, i) => ({
            path: `patient.medications[${i}]`,
            label: `Medication ${i + 1}`,
            value: item,
          }))
          if (items.length === 0) {
            medicationFields.value = [
              { path: 'patient.medications', label: 'Medications', value: '(none entered)' },
            ]
          }
        }
      }
    } else {
      patientFields.value = []
      allergyFields.value = []
      medicationFields.value = []
    }

    if (draft.encounter && showEncounterContext.value) {
      encounterFields.value = [
        { path: 'encounter.admissionDate', label: 'Admission Date', value: draft.encounter.admissionDate ?? '' },
        { path: 'encounter.department', label: 'Department', value: draft.encounter.department ?? '' },
        { path: 'encounter.roomBed', label: 'Room / Bed', value: draft.encounter.roomBed ?? '' },
        { path: 'encounter.admissionReason', label: 'Admission Reason', value: draft.encounter.admissionReason ?? '' },
      ]
      if (showEncounterSummary.value) {
        encounterFields.value.push(
          { path: 'encounter.status', label: 'Encounter Status', value: draft.encounter.status ?? '' },
          { path: 'encounter.dischargeDiagnosis', label: 'Discharge Diagnosis', value: draft.encounter.dischargeDiagnosis ?? '' },
        )
      }
    } else {
      encounterFields.value = []
    }

    if (!showObservations.value) {
      observations.value = []
    }

    fieldChecks.value = {}
    patientFields.value.forEach((f) => { fieldChecks.value[f.path] = false })
    allergyFields.value.forEach((f) => { fieldChecks.value[f.path] = false })
    medicationFields.value.forEach((f) => { fieldChecks.value[f.path] = false })
    encounterFields.value.forEach((f) => { fieldChecks.value[f.path] = false })
    observations.value.forEach((_, i) => { fieldChecks.value[`observations[${i}].value`] = false })
  },
  { immediate: true }
)

watch(sodBlocked, (blocked) => {
  if (blocked) decision.value = null
})

const totalFields = computed(
  () => patientFields.value.length + allergyFields.value.length + medicationFields.value.length
       + encounterFields.value.length + observations.value.length
)
const checkedCount = computed(
  () => Object.values(fieldChecks.value).filter(Boolean).length
)
const allChecked = computed(() => checkedCount.value === totalFields.value && totalFields.value > 0)

function toggleCheck(path: string, value?: boolean) {
  fieldChecks.value[path] = value ?? !fieldChecks.value[path]
}

async function approveVerification() {
  if (sodBlocked.value || decision.value !== 'pass') return
  processing.value = true
  errorMessage.value = ''
  try {
    const checks = Object.entries(fieldChecks.value).map(([fieldPath, passed]) => ({
      fieldPath,
      passed,
    }))
    await batchStore.verifyBatch(props.batchId, checks, true)
    toast.success('Batch verified successfully')
    router.push('/verification')
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Verification failed'
    errorMessage.value = msg
    toast.error(msg)
  } finally {
    processing.value = false
  }
}

async function rejectVerification() {
  if (sodBlocked.value) return
  processing.value = true
  errorMessage.value = ''
  try {
    await batchStore.rejectBatch(props.batchId, rejectionReason.value)
    showRejectDialog.value = false
    toast.warning('Batch returned for rework')
    router.push('/verification')
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Rejection failed'
    errorMessage.value = msg
    toast.error(msg)
  } finally {
    processing.value = false
  }
}
</script>
