<template>
  <div class="h-full min-h-0 flex flex-col">
    <AppHeader
      title="Cover Sheets"
      description="Generate printable separators that reconnect scanned paper to batch metadata."
    />

    <div class="flex-1 overflow-y-auto p-4 sm:p-6 lg:p-8">
      <div class="max-w-7xl mx-auto space-y-6 lg:space-y-8">
        <!-- Top: 50 / 50 generation + preview -->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 lg:gap-8 items-start">
          <section class="card">
            <h2 class="text-base font-semibold text-ink-strong mb-4">Generate Cover Sheets</h2>

            <form @submit.prevent="handleGenerate" class="space-y-4">
              <div>
                <label for="cs-count" class="block text-sm font-semibold text-ink mb-2">
                  Quantity (1–100)
                </label>
                <input
                  id="cs-count"
                  v-model.number="count"
                  type="number"
                  min="1"
                  max="100"
                  class="form-input max-w-xs"
                  required
                />
              </div>

              <div>
                <label for="cs-batch-type" class="block text-sm font-semibold text-ink mb-2">
                  Batch Type
                </label>
                <select id="cs-batch-type" v-model="batchType" class="form-input" required>
                  <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>

              <div>
                <label for="cs-track" class="block text-sm font-semibold text-ink mb-2">Track</label>
                <select id="cs-track" v-model="track" class="form-input">
                  <option value="BACKFILL">Backfill (Track A)</option>
                  <option value="LIVE_CAPTURE">Live Capture (Track B)</option>
                </select>
              </div>

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

              <div>
                <label for="cs-clerk" class="block text-sm font-semibold text-ink mb-2">
                  Entry Clerk
                  <span class="font-normal text-ink-secondary">(optional)</span>
                </label>
                <select
                  id="cs-clerk"
                  v-model="assignToUserId"
                  class="form-input"
                  :disabled="clerksLoading"
                >
                  <option value="">No pre-assignment</option>
                  <option v-for="clerk in clerks" :key="clerk.id" :value="clerk.id">
                    {{ clerk.fullName }} ({{ clerk.username }})
                  </option>
                </select>
              </div>

              <InlineError
                v-if="generateError"
                title="Generation failed"
                :message="generateError"
                preserved="Your form values were kept."
                retry-label="Try again"
                @retry="handleGenerate"
              />

              <div class="flex flex-wrap gap-3 pt-1">
                <button type="submit" class="btn-primary" :disabled="generating || !batchType">
                  {{ generating ? 'Generating...' : 'Generate Cover Sheets' }}
                </button>
                <button
                  v-if="lastGeneratedIds.length > 0"
                  type="button"
                  class="btn-secondary"
                  :disabled="printing"
                  @click="printLastGenerated"
                >
                  {{ printing ? 'Opening PDF...' : 'Print Cover Sheets' }}
                </button>
              </div>

              <p
                v-if="lastGeneratedIds.length > 0"
                class="text-sm text-ink-secondary"
              >
                Last run: {{ lastGeneratedIds.length }} cover sheet(s) ready to print.
              </p>
            </form>
          </section>

          <!-- Live paper preview -->
          <section class="card flex flex-col">
            <h2 class="text-base font-semibold text-ink-strong mb-1">Preview</h2>
            <p class="text-sm text-ink-secondary mb-4">
              Approximate printable layout for the current form values.
            </p>

            <div class="cover-sheet-preview">
              <div class="flex items-center gap-2 px-5 py-4 border-b border-line bg-navy text-white">
                <svg viewBox="0 0 32 32" class="w-7 h-7 shrink-0" aria-hidden="true">
                  <path fill="#155EEF" d="M16 2 4 6.5v8.2c0 8 5.1 14.6 12 15.3 6.9-.7 12-7.3 12-15.3V6.5z"/>
                  <path fill="white" d="M16 8.5c-3.6 0-6.6 2.8-6.6 6.3 0 3.4 2.7 6.4 6.6 9.6 3.9-3.2 6.6-6.2 6.6-9.6 0-3.5-3-6.3-6.6-6.3m0 3.4c1.7 0 3.1 1.3 3.1 2.9s-1.4 2.9-3.1 2.9-3.1-1.3-3.1-2.9 1.4-2.9 3.1-2.9"/>
                </svg>
                <div class="leading-tight">
                  <p class="text-sm font-bold tracking-tight">VigilCare</p>
                  <p class="text-[11px] text-white/60">Records · Cover Sheet</p>
                </div>
              </div>

              <div class="flex-1 flex flex-col items-center justify-center px-6 py-8 gap-5">
                <!-- QR placeholder -->
                <div
                  class="w-28 h-28 border-2 border-ink-strong grid grid-cols-5 grid-rows-5 gap-0.5 p-1.5"
                  aria-hidden="true"
                >
                  <span
                    v-for="n in 25"
                    :key="n"
                    class="bg-ink-strong"
                    :class="qrCellClass(n)"
                  />
                </div>

                <div class="text-center space-y-1">
                  <p class="font-mono text-xs text-ink-secondary tracking-wider">
                    VCR-CS-XXXXXXXX
                  </p>
                  <p class="text-lg font-semibold text-ink-strong">
                    {{ previewBatchType }}
                  </p>
                  <p class="text-sm text-ink-secondary">
                    {{ track === 'BACKFILL' ? 'Backfill (Track A)' : 'Live Capture (Track B)' }}
                  </p>
                </div>

                <dl class="w-full max-w-xs text-sm space-y-2 border-t border-line pt-4">
                  <div class="flex justify-between gap-3">
                    <dt class="text-ink-secondary">Quantity</dt>
                    <dd class="font-medium text-ink-strong">{{ previewCount }}</dd>
                  </div>
                  <div class="flex justify-between gap-3">
                    <dt class="text-ink-secondary">Patient</dt>
                    <dd class="font-medium text-ink-strong text-right truncate">
                      {{ patientId ? 'Linked' : 'Not linked' }}
                    </dd>
                  </div>
                  <div class="flex justify-between gap-3">
                    <dt class="text-ink-secondary">Entry clerk</dt>
                    <dd class="font-medium text-ink-strong text-right truncate">
                      {{ assignedClerkLabel }}
                    </dd>
                  </div>
                  <div class="flex justify-between gap-3">
                    <dt class="text-ink-secondary">Generated</dt>
                    <dd class="font-medium text-ink-strong">{{ previewTimestamp }}</dd>
                  </div>
                </dl>
              </div>
            </div>
          </section>
        </div>

        <!-- Existing cover sheets table -->
        <section class="card">
          <div class="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-4 mb-4">
            <h2 class="text-base font-semibold text-ink-strong">Existing Cover Sheets</h2>

            <div class="flex flex-col sm:flex-row gap-4">
              <div>
                <label for="cs-status-filter" class="block text-sm font-semibold text-ink mb-2">
                  Status
                </label>
                <select
                  id="cs-status-filter"
                  v-model="statusFilter"
                  class="form-input"
                  @change="onFiltersChanged"
                >
                  <option value="all">All</option>
                  <option value="unused">Unused</option>
                  <option value="used">Used</option>
                </select>
              </div>
              <div class="min-w-[240px]">
                <label class="block text-sm font-semibold text-ink mb-2">Patient</label>
                <PatientSearch v-model="filterPatientId" @update:model-value="onFiltersChanged" />
              </div>
            </div>
          </div>

          <InlineError
            v-if="listError"
            class="mb-4"
            title="Could not load cover sheets"
            :message="listError"
            preserved="Your filters were preserved."
            retry-label="Retry"
            @retry="loadCoverSheets"
          />

          <div class="overflow-x-auto">
            <SkeletonBlock v-if="listLoading" variant="table" :rows="5" />
            <EmptyState
              v-else-if="coverSheets.length === 0"
              title="No cover sheets found."
              description="Generate cover sheets above, or adjust your filters."
            />
            <table v-else class="w-full min-w-[800px] text-sm">
              <thead>
                <tr class="border-b text-left text-ink-secondary">
                  <th class="py-2 px-4 font-medium">Code</th>
                  <th class="py-2 px-4 font-medium">Batch Type</th>
                  <th class="py-2 px-4 font-medium">Track</th>
                  <th class="py-2 px-4 font-medium">Patient</th>
                  <th class="py-2 px-4 font-medium">Assigned To</th>
                  <th class="py-2 px-4 font-medium">Status</th>
                  <th class="py-2 px-4 font-medium">Linked Batch</th>
                  <th class="py-2 px-4 font-medium">Created</th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="sheet in coverSheets"
                  :key="sheet.id"
                  class="border-b hover:bg-primary-50"
                >
                  <td class="py-2 px-4 font-mono text-xs text-ink-strong">{{ sheet.code }}</td>
                  <td class="py-2 px-4">{{ formatBatchType(sheet.batchType) }}</td>
                  <td class="py-2 px-4">
                    <span
                      :class="sheet.track === 'BACKFILL'
                        ? 'bg-primary-50 text-primary-800 border border-primary-100'
                        : 'bg-clinical-safe-bg text-clinical-safe border border-[#ABEFC6]'"
                      class="status-badge"
                    >
                      {{ sheet.track === 'BACKFILL' ? 'Backfill' : 'Live' }}
                    </span>
                  </td>
                  <td class="py-2 px-4">
                    <template v-if="sheet.patientName">
                      {{ sheet.patientName }}
                      <span v-if="sheet.patientMrn" class="text-ink-secondary">
                        ({{ sheet.patientMrn }})
                      </span>
                    </template>
                    <span v-else class="text-ink-disabled">—</span>
                  </td>
                  <td class="py-2 px-4">
                    {{ sheet.assignToUserName ?? '—' }}
                  </td>
                  <td class="py-2 px-4">
                    <StatusBadge :status="sheet.isUsed ? 'USED' : 'UNUSED'" />
                  </td>
                  <td class="py-2 px-4">
                    <router-link
                      v-if="sheet.batchId"
                      :to="{ path: '/intake', query: { batchId: sheet.batchId } }"
                      class="font-mono text-xs text-primary-600 hover:text-primary-800"
                    >
                      {{ sheet.batchId.substring(0, 8) }}…
                    </router-link>
                    <span v-else class="text-ink-disabled">—</span>
                  </td>
                  <td class="py-2 px-4 text-ink-secondary">
                    {{ formatDate(sheet.createdAt) }}
                  </td>
                </tr>
              </tbody>
            </table>
          </div>

          <div class="flex items-center justify-between mt-4 pt-4 border-t border-line">
            <p class="text-sm text-ink-secondary">Page {{ page }}</p>
            <div class="flex gap-2">
              <button
                type="button"
                class="btn-secondary text-sm"
                :disabled="page <= 1 || listLoading"
                @click="goToPage(page - 1)"
              >
                Previous
              </button>
              <button
                type="button"
                class="btn-secondary text-sm"
                :disabled="!hasNextPage || listLoading"
                @click="goToPage(page + 1)"
              >
                Next
              </button>
            </div>
          </div>
        </section>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { get, post, postBlob } from '../api/client'
import { useToast } from '../composables/useToast'
import AppHeader from '../components/AppHeader.vue'
import PatientSearch from '../components/PatientSearch.vue'
import StatusBadge from '../components/StatusBadge.vue'
import EmptyState from '../components/EmptyState.vue'
import SkeletonBlock from '../components/SkeletonBlock.vue'
import InlineError from '../components/InlineError.vue'
import type { CoverSheetResponse, UserSummary } from '../types'

const toast = useToast()

const count = ref(10)
const batchType = ref('')
const track = ref('BACKFILL')
const patientId = ref<string | undefined>()
const assignToUserId = ref('')

const clerks = ref<UserSummary[]>([])
const clerksLoading = ref(false)
const generating = ref(false)
const printing = ref(false)
const generateError = ref('')
const lastGeneratedIds = ref<string[]>([])

const coverSheets = ref<CoverSheetResponse[]>([])
const listLoading = ref(false)
const listError = ref('')
const page = ref(1)
const pageSize = 20
const statusFilter = ref<'all' | 'used' | 'unused'>('all')
const filterPatientId = ref<string | undefined>()

const hasNextPage = computed(() => coverSheets.value.length === pageSize)

const previewCount = computed(() => Math.min(100, Math.max(1, count.value || 1)))

const previewBatchType = computed(() =>
  batchType.value ? formatBatchType(batchType.value) : 'Select a batch type',
)

const assignedClerkLabel = computed(() => {
  if (!assignToUserId.value) return 'None'
  const clerk = clerks.value.find(c => c.id === assignToUserId.value)
  return clerk?.fullName ?? 'Selected'
})

const previewTimestamp = computed(() =>
  new Date().toLocaleString(undefined, {
    dateStyle: 'medium',
    timeStyle: 'short',
  }),
)

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

function formatDate(value: string): string {
  return new Date(value).toLocaleString()
}

/** Sparse checker pattern for QR placeholder cells */
function qrCellClass(n: number): string {
  const row = Math.ceil(n / 5)
  const col = ((n - 1) % 5) + 1
  const corner = (row <= 2 && col <= 2) || (row <= 2 && col >= 4) || (row >= 4 && col <= 2)
  const mid = (row + col) % 2 === 0
  return corner || mid ? 'opacity-100' : 'opacity-20'
}

async function loadClerks(): Promise<void> {
  clerksLoading.value = true
  try {
    const response = await get<UserSummary[]>('users', { role: 'DATA_ENTRY_CLERK' })
    clerks.value = response.success && response.data ? response.data : []
  } catch {
    clerks.value = []
  } finally {
    clerksLoading.value = false
  }
}

async function loadCoverSheets(): Promise<void> {
  listLoading.value = true
  listError.value = ''

  const params: Record<string, unknown> = {
    page: page.value,
    pageSize,
  }

  if (statusFilter.value === 'used') params.isUsed = true
  if (statusFilter.value === 'unused') params.isUsed = false
  if (filterPatientId.value) params.patientId = filterPatientId.value

  try {
    const response = await get<CoverSheetResponse[]>('cover-sheets', params)
    if (response.success && response.data) {
      coverSheets.value = response.data
    } else {
      coverSheets.value = []
      listError.value = response.error?.message ?? 'Failed to load cover sheets'
    }
  } catch (e: unknown) {
    coverSheets.value = []
    listError.value = e instanceof Error ? e.message : 'Failed to load cover sheets'
  } finally {
    listLoading.value = false
  }
}

function onFiltersChanged(): void {
  page.value = 1
  void loadCoverSheets()
}

function goToPage(nextPage: number): void {
  page.value = nextPage
  void loadCoverSheets()
}

async function handleGenerate(): Promise<void> {
  if (!batchType.value) return

  generating.value = true
  generateError.value = ''

  const payload: Record<string, unknown> = {
    count: Math.min(100, Math.max(1, count.value || 10)),
    batchType: batchType.value,
    track: track.value,
  }

  if (patientId.value) payload.patientId = patientId.value
  if (assignToUserId.value) payload.assignToUserId = assignToUserId.value

  try {
    const response = await post<CoverSheetResponse[]>('cover-sheets/generate', payload)
    if (!response.success || !response.data) {
      throw new Error(response.error?.message ?? 'Generation failed')
    }

    lastGeneratedIds.value = response.data.map(s => s.id)
    toast.success(`Generated ${response.data.length} cover sheet(s)`)
    page.value = 1
    await loadCoverSheets()
  } catch (e: unknown) {
    const msg = e instanceof Error ? e.message : 'Generation failed'
    generateError.value = msg
    toast.error(msg)
  } finally {
    generating.value = false
  }
}

async function printLastGenerated(): Promise<void> {
  if (lastGeneratedIds.value.length === 0) return

  printing.value = true
  try {
    const blob = await postBlob('cover-sheets/batch-pdf', {
      coverSheetIds: lastGeneratedIds.value,
    })
    const url = URL.createObjectURL(blob)
    window.open(url, '_blank')
    window.setTimeout(() => URL.revokeObjectURL(url), 60_000)
    toast.success('Cover sheet PDF opened in a new tab')
  } catch (e: unknown) {
    toast.error(e instanceof Error ? e.message : 'Failed to generate PDF')
  } finally {
    printing.value = false
  }
}

onMounted(async () => {
  await Promise.all([loadClerks(), loadCoverSheets()])
})
</script>
