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

    <div class="flex-1 overflow-y-auto p-4 sm:p-6 lg:p-8">
      <div class="max-w-7xl mx-auto">
        <div class="mb-6">
          <h1 class="text-[1.75rem] font-semibold text-ink-strong leading-tight tracking-tight">
            Upload Scanned Document
          </h1>
          <p class="mt-1 text-sm text-ink-secondary">
            Create a digitization batch from a PDF or image scan.
          </p>
        </div>

        <div class="grid grid-cols-1 xl:grid-cols-[minmax(0,0.7fr)_minmax(0,0.3fr)] gap-6 lg:gap-8 items-start">
          <!-- Main — ~70%: upload + batch details -->
          <div class="space-y-6 min-w-0">
            <!-- Cover sheet quick lookup -->
            <section class="card">
              <h2 class="text-base font-semibold text-ink-strong mb-1">Cover Sheet Code</h2>
              <p class="text-sm text-ink-secondary mb-4">
                Optional. Scan or type a barcode to auto-fill batch details.
              </p>

              <div class="flex flex-col sm:flex-row gap-3 sm:items-end">
                <div class="flex-1 min-w-0">
                  <label for="cover-sheet-code" class="block text-sm font-semibold text-ink mb-2">
                    Code
                  </label>
                  <input
                    id="cover-sheet-code"
                    v-model="coverSheetCode"
                    @keydown.enter.prevent="lookupCoverSheet"
                    type="text"
                    class="form-input font-mono"
                    placeholder="VCR-CS-XXXXXXXX"
                    autofocus
                  />
                </div>
                <button
                  type="button"
                  @click="lookupCoverSheet"
                  class="btn-secondary shrink-0"
                  :disabled="!coverSheetCode.trim() || lookupLoading"
                >
                  {{ lookupLoading ? 'Looking up...' : 'Lookup' }}
                </button>
              </div>

              <InlineError
                v-if="lookupError"
                class="mt-4"
                title="Cover sheet lookup failed"
                :message="lookupError"
                preserved="You can still upload manually without a cover sheet."
                retry-label="Retry lookup"
                @retry="lookupCoverSheet"
              />

              <div
                v-if="resolvedCoverSheet"
                class="mt-4 rounded-input border border-[#ABEFC6] bg-clinical-safe-bg p-4"
                role="status"
              >
                <p class="text-sm font-semibold text-clinical-safe">Cover Sheet Found</p>
                <dl class="mt-2 text-sm text-ink space-y-1">
                  <div>
                    <dt class="inline font-medium text-ink-secondary">Type:</dt>
                    <dd class="inline ml-1">{{ formatBatchType(resolvedCoverSheet.batchType) }}</dd>
                  </div>
                  <div>
                    <dt class="inline font-medium text-ink-secondary">Track:</dt>
                    <dd class="inline ml-1">{{ formatTrack(resolvedCoverSheet.track) }}</dd>
                  </div>
                  <div v-if="resolvedCoverSheet.patientName">
                    <dt class="inline font-medium text-ink-secondary">Patient:</dt>
                    <dd class="inline ml-1">
                      {{ resolvedCoverSheet.patientName }}
                      <span v-if="resolvedCoverSheet.patientMrn" class="text-ink-secondary">
                        ({{ resolvedCoverSheet.patientMrn }})
                      </span>
                    </dd>
                  </div>
                  <div v-if="resolvedCoverSheet.assignToUserName">
                    <dt class="inline font-medium text-ink-secondary">Assign to:</dt>
                    <dd class="inline ml-1">{{ resolvedCoverSheet.assignToUserName }}</dd>
                  </div>
                </dl>
                <p class="text-sm text-ink-secondary mt-3">
                  Select a file and upload to create the batch with this cover sheet.
                </p>
                <button
                  type="button"
                  @click="clearCoverSheet"
                  class="text-xs font-medium text-clinical-safe hover:underline mt-2"
                >
                  Clear cover sheet (use manual upload)
                </button>
              </div>
            </section>

            <!-- Upload + batch form -->
            <section class="card">
              <h2 class="text-base font-semibold text-ink-strong mb-4">New Batch</h2>

              <form @submit.prevent="handleUpload" class="space-y-5">
                <!-- Drop zone -->
                <div>
                  <label class="block text-sm font-semibold text-ink mb-2">
                    Scanned Document
                  </label>

                  <div
                    v-if="!selectedFile"
                    class="upload-dropzone"
                    :class="{
                      'upload-dropzone--active': dragActive,
                      'upload-dropzone--error': !!fileError,
                    }"
                    @dragenter.prevent="onDragEnter"
                    @dragover.prevent="onDragEnter"
                    @dragleave.prevent="onDragLeave"
                    @drop.prevent="onDrop"
                    @click="triggerFilePicker"
                    @keydown.enter.prevent="triggerFilePicker"
                    @keydown.space.prevent="triggerFilePicker"
                    role="button"
                    tabindex="0"
                    aria-label="Choose or drop a scanned document"
                  >
                    <input
                      ref="fileInput"
                      type="file"
                      class="sr-only"
                      accept=".pdf,.jpg,.jpeg,.png"
                      @change="onFileChange"
                    />
                    <div class="flex flex-col items-center text-center pointer-events-none">
                      <svg
                        class="w-10 h-10 text-primary-500 mb-3"
                        viewBox="0 0 24 24"
                        fill="none"
                        aria-hidden="true"
                      >
                        <path
                          d="M12 16V4m0 0L8 8m4-4l4 4M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2"
                          stroke="currentColor"
                          stroke-width="1.75"
                          stroke-linecap="round"
                          stroke-linejoin="round"
                        />
                      </svg>
                      <p class="text-sm font-semibold text-ink-strong">Upload Files</p>
                      <p class="mt-1 text-sm text-ink-secondary">
                        Drag and drop, or click to browse
                      </p>
                      <p class="mt-3 text-xs text-ink-disabled">
                        PDF, JPEG, PNG — max 25 MB
                      </p>
                    </div>
                  </div>

                  <div
                    v-else
                    class="rounded-input border border-line bg-canvas p-4 flex items-start justify-between gap-3"
                  >
                    <div class="min-w-0">
                      <p class="text-sm font-medium text-ink-strong truncate">
                        {{ selectedFile.name }}
                      </p>
                      <p class="text-xs text-ink-secondary mt-0.5">
                        {{ formatFileSize(selectedFile.size) }}
                      </p>
                    </div>
                    <button
                      type="button"
                      class="text-sm font-medium text-ink-secondary hover:text-ink-strong shrink-0"
                      :disabled="batchStore.loading"
                      @click="clearFile"
                    >
                      Remove
                    </button>
                  </div>

                  <p v-if="fileError" class="text-sm text-clinical-danger mt-2">{{ fileError }}</p>
                </div>

                <!-- Batch type -->
                <div>
                  <label for="batch-type" class="block text-sm font-semibold text-ink mb-2">
                    Batch Type
                  </label>
                  <select
                    id="batch-type"
                    v-model="batchType"
                    class="form-input"
                    :required="!resolvedCoverSheet"
                    :disabled="!!resolvedCoverSheet"
                  >
                    <option value="">Select batch type...</option>
                    <option value="PATIENT_REGISTRATION">Patient Registration</option>
                    <option value="ENCOUNTER_SUMMARY">Encounter Summary</option>
                    <option value="VITALS_SHEET">Vitals Sheet</option>
                    <option value="LAB_RESULTS">Lab Results</option>
                    <option value="MEDICATION_LIST">Medication List</option>
                    <option value="ALLERGY_UPDATE">Allergy Update</option>
                    <option value="MIXED">Mixed</option>
                  </select>
                </div>

                <!-- Track -->
                <div>
                  <label for="track" class="block text-sm font-semibold text-ink mb-2">Track</label>
                  <select
                    id="track"
                    v-model="track"
                    class="form-input"
                    :disabled="!!resolvedCoverSheet"
                  >
                    <option value="BACKFILL">Backfill (Track A)</option>
                    <option value="LIVE_CAPTURE">Live Capture (Track B)</option>
                  </select>
                  <p class="mt-1.5 text-xs text-ink-secondary">
                    {{ track === 'BACKFILL'
                      ? 'Historical or archival document workflow.'
                      : 'Documents from current bedside workflows.' }}
                  </p>
                </div>

                <!-- Patient search -->
                <div>
                  <label class="block text-sm font-semibold text-ink mb-2">
                    Patient Link
                    <span class="font-normal text-ink-secondary">(optional)</span>
                  </label>
                  <PatientSearch v-model="patientId" />
                </div>

                <!-- Supersession (correction) -->
                <div
                  v-if="supersedesBatchId"
                  class="rounded-input border border-primary-100 bg-primary-50 p-4"
                >
                  <p class="text-sm font-semibold text-primary-800">Correction Batch</p>
                  <p class="text-sm text-primary-700 mt-1">
                    This upload will supersede batch
                    <span class="font-mono">{{ supersedesBatchId.substring(0, 8) }}…</span>
                  </p>
                  <button
                    type="button"
                    @click="clearCorrection"
                    class="text-xs font-medium text-primary-700 hover:underline mt-2"
                  >
                    Cancel correction (upload as new batch)
                  </button>
                </div>

                <InlineError
                  v-if="uploadError"
                  title="Upload failed"
                  :message="uploadError"
                  preserved="Your selected file and form values were kept."
                  retry-label="Try again"
                  @retry="handleUpload"
                />

                <div
                  v-if="uploadSuccess"
                  class="rounded-input border border-[#ABEFC6] bg-clinical-safe-bg p-4"
                  role="status"
                >
                  <p class="text-sm font-semibold text-clinical-safe">{{ uploadSuccess }}</p>
                  <p class="text-sm text-ink-secondary mt-1">
                    The batch appears in Recent Uploads and is ready for assignment.
                  </p>
                </div>

                <button
                  type="submit"
                  class="btn-primary"
                  :disabled="!canUpload"
                >
                  {{ uploadButtonLabel }}
                </button>
              </form>
            </section>
          </div>

          <!-- Right — ~30%: guidance + recent uploads -->
          <aside class="space-y-6 min-w-0 xl:sticky xl:top-4">
            <section class="card">
              <h2 class="text-base font-semibold text-ink-strong mb-2">Guidance</h2>
              <ul class="text-sm text-ink-secondary space-y-2 list-disc pl-4">
                <li>Prefer cover sheet lookup when a printed separator is available.</li>
                <li>Link a patient now when known; otherwise assign later in the batch workflow.</li>
                <li>Uploaded batches stay here until an entry clerk is assigned.</li>
              </ul>
            </section>

            <section class="card">
              <h2 class="text-base font-semibold text-ink-strong mb-4">Recent Uploads</h2>
              <InlineError
                v-if="assignError"
                class="mb-4"
                title="Assignment failed"
                :message="assignError"
                preserved="The batch remains unassigned."
                retry-label=""
              />
              <BatchList
                :batches="batchStore.batches"
                :loading="batchStore.loading"
                :error="batchStore.error"
                empty-title="No uploaded batches waiting for assignment."
                empty-description="New uploads appear here after a scan is submitted."
                show-assign
                @assign="openAssignDialog"
                @retry="loadRecent"
              />
            </section>
          </aside>
        </div>
      </div>
    </div>

    <AssignClerkDialog
      :show="assignDialogOpen"
      :batch-id="assignBatchId"
      @close="closeAssignDialog"
      @assigned="handleAssign"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import { get } from '../api/client'
import { useBatchStore } from '../stores/batches'
import { useToast } from '../composables/useToast'
import AppHeader from '../components/AppHeader.vue'
import PatientSearch from '../components/PatientSearch.vue'
import BatchList from '../components/BatchList.vue'
import AssignClerkDialog from '../components/AssignClerkDialog.vue'
import InlineError from '../components/InlineError.vue'
import type { CoverSheetResponse } from '../types'

const MAX_FILE_BYTES = 25 * 1024 * 1024
const ACCEPTED_TYPES = new Set(['application/pdf', 'image/jpeg', 'image/png'])

const route = useRoute()
const batchStore = useBatchStore()
const toast = useToast()

const fileInput = ref<HTMLInputElement | null>(null)
const selectedFile = ref<File | null>(null)
const dragActive = ref(false)
const dragDepth = ref(0)
const fileError = ref('')
const batchType = ref((route.query.batchType as string) || '')
const track = ref('BACKFILL')
const patientId = ref<string | undefined>((route.query.patientId as string) || undefined)
const supersedesBatchId = ref<string | undefined>((route.query.supersedesBatchId as string) || undefined)
const uploadError = ref('')
const uploadSuccess = ref('')
const assignError = ref('')
const assignDialogOpen = ref(false)
const assignBatchId = ref<string | null>(null)

const coverSheetCode = ref('')
const resolvedCoverSheet = ref<CoverSheetResponse | null>(null)
const lookupLoading = ref(false)
const lookupError = ref('')

const canUpload = computed(() => {
  if (!selectedFile.value || batchStore.loading) return false
  if (resolvedCoverSheet.value) return true
  return !!batchType.value
})

const uploadButtonLabel = computed(() => {
  if (batchStore.loading) return 'Uploading...'
  if (resolvedCoverSheet.value) return 'Upload with Cover Sheet'
  return 'Upload and Create Batch'
})

watch(coverSheetCode, () => {
  if (resolvedCoverSheet.value && coverSheetCode.value.trim().toUpperCase() !== resolvedCoverSheet.value.code) {
    resolvedCoverSheet.value = null
    lookupError.value = ''
  }
})

function formatBatchType(type: string): string {
  return type.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase())
}

function formatTrack(value: string): string {
  return value === 'BACKFILL' ? 'Backfill (Track A)' : 'Live Capture (Track B)'
}

function formatFileSize(bytes: number): string {
  return `${(bytes / 1024 / 1024).toFixed(2)} MB`
}

function triggerFilePicker() {
  fileInput.value?.click()
}

function validateFile(file: File): string | null {
  if (file.size > MAX_FILE_BYTES) return 'File exceeds the 25 MB limit.'
  if (file.type && !ACCEPTED_TYPES.has(file.type)) {
    return 'Unsupported file type. Use PDF, JPEG, or PNG.'
  }
  return null
}

function setSelectedFile(file: File | null) {
  fileError.value = ''
  uploadError.value = ''
  uploadSuccess.value = ''
  if (!file) {
    selectedFile.value = null
    return
  }
  const error = validateFile(file)
  if (error) {
    selectedFile.value = null
    fileError.value = error
    return
  }
  selectedFile.value = file
}

function onFileChange(event: Event) {
  const input = event.target as HTMLInputElement
  setSelectedFile(input.files?.[0] ?? null)
}

function clearFile() {
  selectedFile.value = null
  fileError.value = ''
  if (fileInput.value) fileInput.value.value = ''
}

function onDragEnter() {
  dragDepth.value += 1
  dragActive.value = true
}

function onDragLeave() {
  dragDepth.value = Math.max(0, dragDepth.value - 1)
  if (dragDepth.value === 0) dragActive.value = false
}

function onDrop(event: DragEvent) {
  dragDepth.value = 0
  dragActive.value = false
  const file = event.dataTransfer?.files?.[0] ?? null
  setSelectedFile(file)
}

async function lookupCoverSheet(): Promise<void> {
  const code = coverSheetCode.value.trim().toUpperCase()
  if (!code) return

  lookupLoading.value = true
  lookupError.value = ''
  resolvedCoverSheet.value = null

  try {
    const response = await get<CoverSheetResponse>(
      `cover-sheets/lookup/${encodeURIComponent(code)}`,
    )

    if (!response.success || !response.data) {
      throw new Error(response.error?.message ?? 'Cover sheet not found')
    }

    if (response.data.isUsed) {
      throw new Error('Cover sheet has already been used')
    }

    resolvedCoverSheet.value = response.data
    coverSheetCode.value = response.data.code
    batchType.value = response.data.batchType
    track.value = response.data.track
    patientId.value = response.data.patientId ?? undefined
    toast.success('Cover sheet found')
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Lookup failed'
    lookupError.value = msg
    toast.error(msg)
  } finally {
    lookupLoading.value = false
  }
}

function clearCoverSheet(): void {
  coverSheetCode.value = ''
  resolvedCoverSheet.value = null
  lookupError.value = ''
}

async function handleUpload() {
  if (!selectedFile.value || !canUpload.value) return

  uploadError.value = ''
  uploadSuccess.value = ''
  try {
    const batch = await batchStore.uploadBatch(
      selectedFile.value,
      batchType.value,
      track.value,
      patientId.value,
      supersedesBatchId.value,
      resolvedCoverSheet.value?.code,
    )
    if (batch) {
      const isCorrection = !!supersedesBatchId.value
      const usedCoverSheet = !!resolvedCoverSheet.value
      selectedFile.value = null
      if (fileInput.value) fileInput.value.value = ''
      batchType.value = ''
      track.value = 'BACKFILL'
      patientId.value = undefined
      supersedesBatchId.value = undefined
      clearCoverSheet()
      const message = isCorrection
        ? 'Correction batch created'
        : usedCoverSheet
          ? 'Batch uploaded with cover sheet'
          : 'Batch uploaded successfully'
      uploadSuccess.value = message
      toast.success(message)
      await loadRecent()
    }
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Upload failed'
    uploadError.value = msg
    toast.error(msg)
  }
}

function clearCorrection() {
  supersedesBatchId.value = undefined
}

function openAssignDialog(batchId: string) {
  assignError.value = ''
  assignBatchId.value = batchId
  assignDialogOpen.value = true
}

function closeAssignDialog() {
  assignDialogOpen.value = false
  assignBatchId.value = null
}

async function handleAssign(batchId: string, clerkUserId: string) {
  assignError.value = ''
  try {
    await batchStore.assignBatch(batchId, clerkUserId)
    closeAssignDialog()
    toast.success('Batch assigned to entry clerk')
    await loadRecent()
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Assignment failed'
    assignError.value = msg
    toast.error(msg)
  }
}

async function loadRecent() {
  await batchStore.listBatches({ status: 'UPLOADED', page: 1, pageSize: 20 })
}

onMounted(loadRecent)
</script>
