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

    <div class="p-4 sm:p-6 lg:p-8 max-w-6xl mx-auto flex-1 w-full">
      <h1 class="text-2xl font-bold mb-6">Cover Sheet Management</h1>

      <!-- Generate -->
      <div class="card mb-6">
        <h2 class="text-lg font-semibold mb-4">Generate Cover Sheets</h2>

        <form @submit.prevent="handleGenerate" class="space-y-4">
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-2">
              Count (1&ndash;100)
            </label>
            <input
              v-model.number="count"
              type="number"
              min="1"
              max="100"
              class="form-input max-w-xs"
              required
            />
          </div>

          <div>
            <label class="block text-sm font-medium text-gray-700 mb-2">Batch Type</label>
            <select 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 class="block text-sm font-medium text-gray-700 mb-2">Track</label>
            <select 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-medium text-gray-700 mb-2">
              Patient (optional)
            </label>
            <PatientSearch v-model="patientId" />
          </div>

          <div>
            <label class="block text-sm font-medium text-gray-700 mb-2">
              Assign to Clerk (optional)
            </label>
            <select 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>

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

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

      <!-- List -->
      <div class="card">
        <div class="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-4 mb-4">
          <h2 class="text-lg font-semibold">Cover Sheet List</h2>

          <div class="flex flex-col sm:flex-row gap-4">
            <div>
              <label class="block text-sm font-medium text-gray-700 mb-2">Status</label>
              <select 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-medium text-gray-700 mb-2">Patient</label>
              <PatientSearch v-model="filterPatientId" @update:model-value="onFiltersChanged" />
            </div>
          </div>
        </div>

        <div v-if="listError" class="text-clinical-danger text-sm mb-4">
          {{ listError }}
        </div>

        <div class="overflow-x-auto">
          <div v-if="listLoading" class="text-gray-500 text-center py-4">Loading...</div>
          <div v-else-if="coverSheets.length === 0" class="text-gray-500 text-center py-4">
            No cover sheets found.
          </div>
          <table v-else class="w-full min-w-[800px] text-sm">
            <thead>
              <tr class="border-b text-left text-gray-600">
                <th class="py-2 px-4">Code</th>
                <th class="py-2 px-4">Batch Type</th>
                <th class="py-2 px-4">Track</th>
                <th class="py-2 px-4">Patient</th>
                <th class="py-2 px-4">Assigned To</th>
                <th class="py-2 px-4">Status</th>
                <th class="py-2 px-4">Linked Batch</th>
                <th class="py-2 px-4">Created</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="sheet in coverSheets"
                :key="sheet.id"
                class="border-b hover:bg-gray-50"
              >
                <td class="py-2 px-4 font-mono text-xs">{{ 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-blue-100 text-blue-800'
                      : 'bg-green-100 text-green-800'"
                    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-gray-500">({{ sheet.patientMrn }})</span>
                  </template>
                  <span v-else class="text-gray-400">&mdash;</span>
                </td>
                <td class="py-2 px-4">
                  {{ sheet.assignToUserName ?? '—' }}
                </td>
                <td class="py-2 px-4">
                  <span
                    :class="sheet.isUsed
                      ? 'bg-gray-100 text-gray-800'
                      : 'bg-green-100 text-green-800'"
                    class="status-badge"
                  >
                    {{ sheet.isUsed ? 'Used' : 'Unused' }}
                  </span>
                </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-gray-400">&mdash;</span>
                </td>
                <td class="py-2 px-4 text-gray-500">
                  {{ formatDate(sheet.createdAt) }}
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="flex items-center justify-between mt-4 pt-4 border-t">
          <p class="text-sm text-gray-500">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>
      </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 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)

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()
}

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>
