<template>
  <v-app class="bg-modern">
    <v-main class="no-overflow">
      <v-container fluid class="no-scroll-container pa-2 pa-md-4">
        <v-row align="start" justify="center" class="fill-height layout-with-sidebar" no-gutters>
          <!-- Main Content -->
          <v-col cols="12" sm="11" md="10" lg="8" xl="7" class="d-flex flex-column main-content-col">
            <!-- Main Card dengan Glassmorphism -->
            <v-card class="main-card" elevation="0">
              
              <!-- Header Minimalis -->
              <div class="header-modern">
                <div class="header-content">
                  <div class="icon-circle">
                    <v-icon size="28" color="white">mdi-hospital-building</v-icon>
                  </div>
                  <div class="header-text">
                    <h1 class="title-modern">Check-in Pasien</h1>
                  </div>
                </div>
                
                <!-- Tabs Minimalis -->
                <v-tabs 
                  v-model="tab" 
                  align-tabs="center" 
                  class="tabs-modern mt-1"
                  bg-color="transparent"
                  slider-color="#FB8C00"
                  height="32"
                >
                  <v-tab value="checkin" class="tab-modern">
                    <v-icon size="18" class="mr-2">mdi-login</v-icon>
                    <span>Check-in</span>
                  </v-tab>
                  <v-tab value="generate" class="tab-modern">
                    <v-icon size="18" class="mr-2">mdi-qrcode</v-icon>
                    <span>Generate QR</span>
                  </v-tab>
                </v-tabs>
              </div>

                <v-card-text class="content-modern pa-4 pa-md-6">
                  <v-window v-model="tab" :key="`window-${tab}`">
                    <!-- Tab Check-in (Combined Scan QR + Manual) -->
                    <v-window-item value="checkin" :key="'checkin-tab'">
                      <div class="checkin-wrapper">
                        <v-row class="checkin-layout" no-gutters>
                        <!-- Left: Scan QR -->
                        <v-col cols="12" md="6" class="checkin-left-col">
                        <div class="tab-content">
                          <!-- Status Header -->
                          <div class="status-header mb-3">
                            <div class="status-icon-wrapper">
                              <v-icon :color="primaryColor" size="24">mdi-qrcode-scan</v-icon>
                            </div>
                            <div class="status-text">
                              <h3 class="status-title">
                                {{ isScanning ? 'Arahkan Kamera ke QR Code' : 'Siap untuk Scan QR Code' }}
                              </h3>
                              <p class="status-subtitle">
                                {{ isScanning ? 'Pastikan QR code terlihat jelas dan tidak terpotong' : 'Klik tombol di bawah untuk memulai scan' }}
                              </p>
                            </div>
                          </div>
                          
                          <!-- Camera Status Check -->
                          <div v-if="cameraChecking" class="text-center mb-4">
                            <v-progress-circular
                              indeterminate
                              :color="primaryColor"
                              size="24"
                              class="mr-2"
                            ></v-progress-circular>
                            <span class="text-body-2 text-grey">Memeriksa ketersediaan kamera...</span>
                          </div>
    
                          <!-- Camera Not Available Warning -->
                          <v-alert
                            v-else-if="!hasCamera && !isScanning"
                            type="warning"
                            variant="tonal"
                            class="mb-4"
                          >
                            <template v-slot:prepend>
                              <v-icon>mdi-camera-off</v-icon>
                            </template>
                            <div>
                              <p class="font-weight-bold mb-1">Kamera tidak terdeteksi</p>
                              <p class="text-body-2 mb-0">
                                Perangkat Anda tidak memiliki kamera atau kamera tidak dapat diakses. 
                                Silakan gunakan input <strong>Manual</strong> di sebelah kanan.
                              </p>
                            </div>
                          </v-alert>
    
                          <!-- QR Scanner Area dengan webcam -->
                          <div class="qr-scanner-container mb-4">
                            <div v-if="!isScanning" class="qr-placeholder">
                              <div class="scanner-overlay">
                                <div class="corner corner-tl"></div>
                                <div class="corner corner-tr"></div>
                                <div class="corner corner-bl"></div>
                                <div class="corner corner-br"></div>
                                <div class="scan-line"></div>
                              </div>
                              <v-icon size="64" :color="primaryColor" class="qr-icon">mdi-qrcode-scan</v-icon>
                            </div>
                            <div v-else class="qr-reader-container">
                              <div class="scanner-status mb-2">
                                <v-chip color="success" size="small" class="mr-2">
                                  <v-icon start size="16">mdi-camera</v-icon>
                                  Kamera Aktif
                                </v-chip>
                                <span class="text-caption text-grey">Preview kamera sedang berjalan</span>
                              </div>
                              <div id="qr-reader" class="qr-reader-wrapper">
                                <div class="scanner-loading-overlay" v-if="!cameraReady">
                                  <v-progress-circular
                                    indeterminate
                                    color="white"
                                    size="48"
                                  ></v-progress-circular>
                                  <p class="text-white mt-4">Memuat kamera...</p>
                                </div>
                              </div>
                              <div class="scanner-instruction">
                                <v-icon :color="primaryColor" size="16">mdi-information</v-icon>
                                <span class="text-caption">Arahkan kamera ke QR code. Pastikan QR code berada dalam kotak pemindaian.</span>
                              </div>
                            </div>
                          </div>
                          
                          <!-- Action Button Minimalis -->
                          <div class="action-buttons">
                            <v-btn
                              v-if="!isScanning"
                              class="btn-primary-modern btn-centered"
                              size="large"
                              elevation="0"
                              @click="startScanning"
                              :disabled="!hasCamera && !cameraChecking"
                              block
                            >
                              <v-icon start size="20">mdi-camera</v-icon>
                              {{ hasCamera ? 'Mulai Scan QR' : 'Kamera Tidak Tersedia' }}
                            </v-btn>
                            <v-btn
                              v-else
                              class="btn-stop-modern btn-centered"
                              size="large"
                              elevation="0"
                              @click="stopScanning"
                              block
                            >
                              <v-icon start size="20">mdi-camera-off</v-icon>
                              Stop Scan
                            </v-btn>
                          </div>
    
                          <!-- Info tambahan -->
                          <div class="info-card mt-3">
                            <v-alert
                              type="info"
                              variant="tonal"
                              :color="primaryColor"
                              class="text-body-2 info-alert-centered"
                              density="compact"
                            >
                              <div class="d-flex align-center justify-center">
                                <v-icon size="16" class="mr-2">mdi-lightbulb-outline</v-icon>
                                <span style="font-size: 12px;">Tips: Pastikan pencahayaan cukup untuk hasil scan optimal</span>
                              </div>
                            </v-alert>
                          </div>
    
                          <!-- Test Camera Button (Debug) -->
                          <div class="test-camera-section mt-2 mb-2">
                            <v-btn
                              variant="outlined"
                              color="primary"
                              size="small"
                              class="text-none btn-centered-small btn-test-camera"
                              @click="testCamera"
                              block
                            >
                              <v-icon start size="18" color="#1565C0">mdi-camera</v-icon>
                              Test Kamera
                            </v-btn>
                            <p class="text-caption text-grey text-center mt-1" style="font-size: 11px;">
                              Klik untuk menguji apakah browser dapat mengakses kamera
                            </p>
                          </div>
    
                          <!-- Quick Access Buttons -->
                          <div class="quick-actions mt-4">
                            <p class="text-caption text-grey text-center mb-3">Akses Cepat</p>
                            <v-row dense>
                              <v-col cols="12">
                                <v-btn
                                  variant="outlined"
                                  :color="primaryColor"
                                  block
                                  size="small"
                                  class="text-none"
                                  @click="openHistoryDialog"
                                >
                                  <v-icon start size="18">mdi-history</v-icon>
                                  Riwayat Check-in
                                </v-btn>
                              </v-col>
                              <v-col cols="12">
                                <v-btn
                                  variant="outlined"
                                  color="primary"
                                  block
                                  size="small"
                                  class="text-none"
                                  @click="openQRHistoryDialog"
                                >
                                  <v-icon start size="18" color="#1565C0">mdi-qrcode-scan</v-icon>
                                  Riwayat QR Scan
                                </v-btn>
                              </v-col>
                            </v-row>
                          </div>
                        </div>
                      </v-col>

                        <!-- Right: Manual Input -->
                        <v-col cols="12" md="6" class="checkin-right-col">
                        <div class="tab-content">
                          <!-- Status Header -->
                          <div class="status-header mb-3">
                            <div class="status-icon-wrapper">
                              <v-icon :color="secondaryColor" size="24">mdi-keyboard</v-icon>
                            </div>
                            <div class="status-text">
                              <h3 class="status-title">Input Manual</h3>
                              <p class="status-subtitle">Masukkan nomor Antrean Code atau Barcode Pasien</p>
                            </div>
                          </div>
    
                          <v-form @submit.prevent="checkInManual" ref="manualForm">
                            <v-text-field
                              v-model="manualInput"
                              label="Nomor Antrean Code / Barcode Pasien" 
                              placeholder="Contoh: 26011301220"
                              prepend-inner-icon="mdi-account-card-details"
                              variant="outlined"
                              :color="primaryColor"
                              class="input-modern mb-4"
                              required
                              :rules="[v => !!v || 'Field ini wajib diisi']"
                              density="comfortable"
                              hide-details="auto"
                            >
                              <template v-slot:append-inner>
                                <v-icon :color="manualInput ? 'success' : 'grey'" size="20">
                                  {{ manualInput ? 'mdi-check-circle' : 'mdi-circle-outline' }}
                                </v-icon>
                              </template>
                            </v-text-field>
    
                            <v-btn
                              class="btn-primary-modern btn-centered"
                              size="large"
                              type="submit"
                              elevation="0"
                              block
                            >
                              <v-icon start size="20">mdi-login</v-icon>
                              Check-in Sekarang
                            </v-btn>
                          </v-form>
    
                          <!-- Quick Access Buttons -->
                          <div class="quick-actions mt-4">
                            <p class="text-caption text-grey text-center mb-3">Akses Cepat</p>
                            <v-row dense>
                              <v-col cols="12">
                                <v-btn
                                  variant="outlined"
                                  :color="primaryColor"
                                  block
                                  size="small"
                                  class="text-none"
                                  @click="openHistoryDialog"
                                >
                                  <v-icon start size="18">mdi-history</v-icon>
                                  Lihat Semua Riwayat
                                </v-btn>
                              </v-col>
                            </v-row>
                          </div>

                          <!-- Riwayat Check-in -->
                          <div class="history-section mt-6">
                            <div class="d-flex align-center justify-space-between mb-3">
                              <h4 class="text-subtitle-1 font-weight-bold">
                                <v-icon size="20" class="mr-2" :color="primaryColor">mdi-history</v-icon>
                                Riwayat Check-in
                              </h4>
                              <v-chip size="x-small" color="grey-lighten-2">
                                {{ recentHistory.length }} item
                              </v-chip>
                            </div>
                            
                            <div v-if="recentHistory.length > 0" class="recent-history-list">
                              <!-- Info jumlah data -->
                              <div v-if="recentHistory.length > recentHistoryItemsPerPage" class="mb-2 text-caption text-grey-darken-1">
                                Menampilkan {{ (recentHistoryPage - 1) * recentHistoryItemsPerPage + 1 }} - {{ Math.min(recentHistoryPage * recentHistoryItemsPerPage, recentHistory.length) }} dari {{ recentHistory.length }} riwayat
                              </div>
                              
                              <v-card
                                v-for="(item, index) in paginatedRecentHistory"
                                :key="index"
                                variant="flat"
                                elevation="0"
                                class="mb-1 history-item-compact"
                                :class="getStatusClass(item.status)"
                              >
                                <v-card-text class="pa-1">
                                  <div class="history-item-content">
                                    <!-- Header Row: Status Badge & Time -->
                                    <div class="d-flex align-center justify-space-between mb-1">
                                      <div class="d-flex align-center gap-1">
                                        <div class="history-status-badge" :class="`status-${getStatusColor(item.status)}`">
                                          <v-icon size="12">{{ getStatusIcon(item.status) }}</v-icon>
                                        </div>
                                        <div>
                                          <div class="history-status-text" :class="`text-${getStatusColor(item.status)}`">
                                            {{ getStatusText(item.status) }}
                                          </div>
                                          <div class="history-method-text">
                                            {{ item.method }}
                                          </div>
                                        </div>
                                      </div>
                                      <div class="history-time-badge">
                                        <v-icon size="10" class="mr-1">mdi-clock-outline</v-icon>
                                        <span>{{ formatTime(item.checkInTime) }}</span>
                                      </div>
                                    </div>
                                    
                                    <!-- Content Row: Klinik & Queue Number -->
                                    <div class="d-flex align-center justify-space-between mb-1 flex-wrap gap-1">
                                      <div v-if="item.klinik && item.klinik !== 'N/A'" class="history-klinik-badge">
                                        <v-icon size="10" class="mr-1">mdi-hospital-building</v-icon>
                                        <span>{{ item.klinik }}</span>
                                      </div>
                                      <div v-if="item.klinikQueueNumber || item.queueNumber" class="history-queue-badge">
                                        <v-icon size="10" class="mr-1">mdi-ticket</v-icon>
                                        <span class="font-weight-semibold">{{ item.klinikQueueNumber || item.queueNumber }}</span>
                                      </div>
                                    </div>
                                    
                                    <!-- Footer Row: Patient ID & Payment -->
                                    <div v-if="item.patientId || (item.pembayaran && item.pembayaran !== 'N/A')" class="d-flex align-center flex-wrap gap-1 pt-1 border-top-history">
                                      <div v-if="item.patientId" class="history-info-badge">
                                        <v-icon size="10" class="mr-1">mdi-account-circle</v-icon>
                                        <span>{{ item.patientId }}</span>
                                      </div>
                                      <div v-if="item.pembayaran && item.pembayaran !== 'N/A'" class="history-info-badge">
                                        <v-icon size="10" class="mr-1">mdi-credit-card</v-icon>
                                        <span>{{ item.pembayaran }}</span>
                                      </div>
                                    </div>
                                  </div>
                                </v-card-text>
                              </v-card>
                              
                              <!-- Pagination untuk recent history -->
                              <div v-if="totalRecentHistoryPages > 1" class="mt-3 d-flex justify-center">
                                <v-pagination
                                  v-model="recentHistoryPage"
                                  :length="totalRecentHistoryPages"
                                  :total-visible="5"
                                  color="primary"
                                  size="small"
                                  density="compact"
                                  rounded="circle"
                                ></v-pagination>
                              </div>
                            </div>
                            
                            <div v-else class="text-center py-6">
                              <v-icon size="48" color="grey-lighten-1" class="mb-2">mdi-history</v-icon>
                              <p class="text-body-2 text-grey">Belum ada riwayat check-in</p>
                            </div>
                          </div>
                        </div>
                      </v-col>
                      </v-row>
                      </div>
                    </v-window-item>

                  <!-- Tab Generate QR -->
                  <v-window-item value="generate">
                    <div class="tab-content">
                      <!-- Status Header -->
                      <div class="status-header mb-3">
                        <div class="status-icon-wrapper">
                          <v-icon :color="primaryColor" size="24">mdi-qrcode</v-icon>
                        </div>
                        <div class="status-text">
                          <h3 class="status-title">Generate QR Code untuk Testing</h3>
                          <p class="status-subtitle">Buat QR code yang bisa Anda scan di tab "Scan QR"</p>
                        </div>
                      </div>

                      <!-- Quick Preset Buttons -->
                      <div class="mb-3">
                        <p class="text-caption text-grey text-center mb-2">Quick Test QR Codes:</p>
                        <v-row dense>
                          <v-col cols="6">
                            <v-btn
                              variant="outlined"
                              color="success"
                              size="small"
                              @click="generateQuickQR('ALLOWED')"
                              class="text-none"
                              block
                            >
                              <v-icon start size="16">mdi-check-circle</v-icon>
                              Test ALLOWED
                            </v-btn>
                          </v-col>
                          <v-col cols="6">
                            <v-btn
                              variant="outlined"
                              color="warning"
                              size="small"
                              @click="generateQuickQR('NOT_ALLOWED')"
                              class="text-none"
                              block
                            >
                              <v-icon start size="16">mdi-clock-alert</v-icon>
                              Test NOT_ALLOWED
                            </v-btn>
                          </v-col>
                        </v-row>
                      </div>

                      <!-- Form Generate -->
                      <v-form @submit.prevent="generateQRCode">
                        <v-select
                          v-model="selectedKlinik"
                          label="Pilih Klinik/Poli"
                          :items="klinikOptions"
                          prepend-inner-icon="mdi-hospital-building"
                          variant="outlined"
                          :color="primaryColor"
                          class="input-modern mb-3"
                          density="comfortable"
                          :rules="[v => !!v || 'Klinik/Poli harus dipilih']"
                          hide-details="auto"
                          required
                        ></v-select>
                        
                        <v-text-field
                          v-model="generatePatientId"
                          label="ID Pasien"
                          placeholder="Auto-generate: P-00001"
                          prepend-inner-icon="mdi-identifier"
                          variant="outlined"
                          :color="primaryColor"
                          class="input-modern mb-3"
                          density="comfortable"
                          readonly
                          hint="ID Pasien akan di-generate secara otomatis secara sequential"
                          persistent-hint
                          hide-details="auto"
                        >
                          <template v-slot:append-inner>
                            <v-btn
                              icon
                              size="small"
                              variant="text"
                              @click="generatePatientId = generateSequentialPatientId()"
                              title="Generate ID Baru"
                            >
                              <v-icon size="18">mdi-refresh</v-icon>
                            </v-btn>
                          </template>
                        </v-text-field>

                        <v-select
                          v-model="generateStatus"
                          label="Status Check-in"
                          :items="statusOptions"
                          prepend-inner-icon="mdi-shield-check"
                          variant="outlined"
                          :color="primaryColor"
                          class="input-modern mb-4"
                          density="comfortable"
                          hide-details="auto"
                        ></v-select>

                        <div class="d-flex justify-center">
                          <v-btn
                            class="btn-primary-modern btn-centered"
                            size="large"
                            type="submit"
                            elevation="0"
                            :disabled="!selectedKlinik"
                          >
                            <v-icon start size="20">mdi-qrcode-plus</v-icon>
                            Generate QR Code
                          </v-btn>
                        </div>
                      </v-form>

                      <!-- QR Code Display -->
                      <div v-if="generatedQRData" class="qr-display mt-6">
                        <v-card variant="outlined" class="pa-4">
                          <div class="text-center">
                            <p class="text-subtitle-2 text-grey mb-3">QR Code Anda:</p>
                            <div id="qrcode" class="qr-code-container mb-4"></div>
                            
                            <v-chip :color="generateStatus === 'ALLOWED' ? 'success' : 'warning'" class="mb-3">
                              <v-icon start>{{ generateStatus === 'ALLOWED' ? 'mdi-check' : 'mdi-clock-alert' }}</v-icon>
                              {{ generateStatus === 'ALLOWED' ? 'Diizinkan Check-in' : 'Belum Diizinkan' }}
                            </v-chip>

                            <p class="text-body-2 text-grey mb-4">
                              Data: {{ generatedQRData }}
                            </p>

                            <!-- Action Buttons -->
                            <v-row dense>
                              <v-col cols="4">
                                <v-btn
                                  variant="outlined"
                                  :color="primaryColor"
                                  block
                                  size="small"
                                  @click="downloadQR"
                                  class="text-none"
                                >
                                  <v-icon start size="18">mdi-download</v-icon>
                                  Download
                                </v-btn>
                              </v-col>
                              <v-col cols="4">
                                <v-btn
                                  variant="outlined"
                                  :color="primaryColor"
                                  block
                                  size="small"
                                  @click="copyQRToClipboard"
                                  class="text-none"
                                >
                                  <v-icon start size="18">mdi-content-copy</v-icon>
                                  Copy
                                </v-btn>
                              </v-col>
                              <v-col cols="4">
                                <v-btn
                                  variant="outlined"
                                  :color="primaryColor"
                                  block
                                  size="small"
                                  @click="shareQR"
                                  class="text-none"
                                >
                                  <v-icon start size="18">mdi-share-variant</v-icon>
                                  Share
                                </v-btn>
                              </v-col>
                            </v-row>
                          </div>
                        </v-card>

                        <!-- Instructions -->
                        <v-alert
                          type="success"
                          variant="tonal"
                          class="mt-4 text-body-2"
                        >
                          <template v-slot:prepend>
                            <v-icon>mdi-information</v-icon>
                          </template>
                          <strong>Cara menggunakan untuk Testing:</strong>
                          <ol class="ml-4 mt-2">
                            <li>Gunakan tombol <strong>"Test ALLOWED"</strong> atau <strong>"Test NOT_ALLOWED"</strong> untuk generate QR cepat, atau isi form manual</li>
                            <li>Klik <strong>"Download"</strong> untuk menyimpan QR code ke komputer</li>
                            <li>Buka file QR code yang didownload (bisa di HP atau layar lain)</li>
                            <li>Pindah ke tab <strong>"Scan QR"</strong> dan scan QR code tersebut</li>
                            <li>Atau gunakan <strong>"Copy"</strong> untuk menyalin QR ke clipboard dan paste di aplikasi lain</li>
                          </ol>
                        </v-alert>
                      </div>
                    </div>
                  </v-window-item>
                </v-window>
              </v-card-text>
            </v-card>

            <!-- Stats Footer (Horizontal) - For Small Screens -->
            <div class="stats-footer-horizontal mt-3">
              <div class="stat-item-footer stat-item-footer-primary">
                <div class="stat-icon-footer">
                  <v-icon color="#5865f2" size="20">mdi-clock-outline</v-icon>
                </div>
                <div class="stat-content-footer">
                  <div class="stat-value-footer">{{ statsToday }}</div>
                  <div class="stat-label-footer">Hari Ini</div>
                </div>
              </div>
              <div class="stat-item-footer stat-item-footer-success">
                <div class="stat-icon-footer">
                  <v-icon color="#57f287" size="20">mdi-check-circle</v-icon>
                </div>
                <div class="stat-content-footer">
                  <div class="stat-value-footer">{{ statsCompleted }}</div>
                  <div class="stat-label-footer">Selesai</div>
                </div>
              </div>
              <div class="stat-item-footer stat-item-footer-secondary">
                <div class="stat-icon-footer">
                  <v-icon color="#faa61a" size="20">mdi-account-group</v-icon>
                </div>
                <div class="stat-content-footer">
                  <div class="stat-value-footer">{{ statsWaiting }}</div>
                  <div class="stat-label-footer">Menunggu</div>
                </div>
              </div>
            </div>
          </v-col>

          <!-- Stats Sidebar (Discord-style) - Right Side -->
          <v-col cols="auto" class="stats-sidebar-right d-none d-lg-flex">
            <div class="stats-sidebar-discord">
              <div class="stat-item-discord stat-item-primary" :title="`Hari Ini: ${statsToday} check-in`">
                <div class="stat-icon-discord">
                  <v-icon color="#5865f2" size="26">mdi-clock-outline</v-icon>
                </div>
                <div class="stat-content-discord">
                  <div class="stat-value-discord">{{ statsToday }}</div>
                  <div class="stat-label-discord">Hari Ini</div>
                </div>
              </div>
              <div class="stat-item-discord stat-item-success" :title="`Selesai: ${statsCompleted} check-in`">
                <div class="stat-icon-discord">
                  <v-icon color="#57f287" size="26">mdi-check-circle</v-icon>
                </div>
                <div class="stat-content-discord">
                  <div class="stat-value-discord">{{ statsCompleted }}</div>
                  <div class="stat-label-discord">Selesai</div>
                </div>
              </div>
              <div class="stat-item-discord stat-item-secondary" :title="`Menunggu: ${statsWaiting} pasien`">
                <div class="stat-icon-discord">
                  <v-icon color="#faa61a" size="26">mdi-account-group</v-icon>
                </div>
                <div class="stat-content-discord">
                  <div class="stat-value-discord">{{ statsWaiting }}</div>
                  <div class="stat-label-discord">Menunggu</div>
                </div>
              </div>
            </div>
          </v-col>
        </v-row>
      </v-container>
    </v-main>
    
    <!-- Enhanced Dialog with Blur -->
    <v-dialog 
      v-model="infoDialog" 
      max-width="500" 
      persistent
      transition="dialog-transition"
      scrim="rgba(0, 0, 0, 0.5)"
      class="blur-dialog"
    >
      <v-card class="rounded-xl dialog-card" elevation="24">
        <div class="dialog-header text-center pa-6" :class="lastCheckInResult?.success && infoAction === 'checkin' ? 'success-header' : lastCheckInResult?.status === 'NOT_ALLOWED' ? 'warning-header' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'warning-header' : 'error-header'">
          <div class="icon-wrapper mb-3">
            <div class="icon-bg" :class="lastCheckInResult?.success && infoAction === 'checkin' ? 'icon-bg-success' : lastCheckInResult?.status === 'NOT_ALLOWED' ? 'icon-bg-warning' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'icon-bg-warning' : 'icon-bg-error'">
              <v-icon size="56" color="white" class="dialog-icon">
                {{ lastCheckInResult?.success && infoAction === 'checkin' ? 'mdi-check-circle' : lastCheckInResult?.status === 'NOT_ALLOWED' ? 'mdi-clock-alert' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'mdi-check-circle' : 'mdi-close-circle' }}
              </v-icon>
            </div>
          </div>
          
          <h2 class="text-h5 font-weight-bold text-white mb-2">
            {{ lastCheckInResult?.success && infoAction === 'checkin' 
              ? 'Check-in Berhasil!' 
              : lastCheckInResult?.status === 'NOT_ALLOWED'
              ? 'Belum Diizinkan'
              : lastCheckInResult?.status === 'ALREADY_CHECKED_IN'
              ? 'Sudah Check-in'
              : 'Check-in Gagal' }}
          </h2>
          
          <div class="status-badge mt-2">
            <v-chip 
              :color="lastCheckInResult?.success && infoAction === 'checkin' ? 'white' : 'white'" 
              :text-color="lastCheckInResult?.success && infoAction === 'checkin' ? 'success' : lastCheckInResult?.status === 'NOT_ALLOWED' ? 'orange' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'orange' : 'error'"
              size="small"
              class="font-weight-bold"
            >
              <v-icon start size="14">
                {{ lastCheckInResult?.success && infoAction === 'checkin' ? 'mdi-check' : lastCheckInResult?.status === 'NOT_ALLOWED' ? 'mdi-clock-alert' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'mdi-check-circle' : 'mdi-close-circle' }}
              </v-icon>
              {{ lastCheckInResult?.success && infoAction === 'checkin' 
                ? 'Berhasil' 
                : lastCheckInResult?.status === 'NOT_ALLOWED'
                ? 'Menunggu'
                : lastCheckInResult?.status === 'ALREADY_CHECKED_IN'
                ? 'Sudah Check-in'
                : 'Gagal' }}
            </v-chip>
          </div>
        </div>
        
        <v-card-text class="pa-5">
          <div class="message-container">
            <div class="text-body-1 font-weight-medium mb-4 text-center" style="white-space: pre-line; color: $neutral-800;">{{ infoMessage }}</div>
            
            <v-divider class="my-4"></v-divider>
            
            <div v-if="lastCheckInResult" class="instruction-box pa-3 rounded-lg mb-4" :class="lastCheckInResult.success && infoAction === 'checkin' ? 'instruction-success' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'instruction-warning' : 'instruction-warning'">
              <div class="d-flex align-start">
                <v-icon :color="lastCheckInResult.success && infoAction === 'checkin' ? 'success' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'orange' : 'orange'" class="mr-2 mt-1" size="20">
                  {{ lastCheckInResult.success && infoAction === 'checkin' ? 'mdi-check-circle' : lastCheckInResult?.status === 'ALREADY_CHECKED_IN' ? 'mdi-check-circle' : 'mdi-timer-sand' }}
                </v-icon>
                <div>
                  <p class="text-body-2 font-weight-medium mb-1">
                    {{ lastCheckInResult.success && infoAction === 'checkin' ? 'Status Check-in:' : 'Status:' }}
                  </p>
                  <p class="text-body-2 text-grey-darken-1 mb-0">
                    {{ lastCheckInResult.success && infoAction === 'checkin' 
                      ? 'Check-in telah berhasil dilakukan. Pasien dapat melanjutkan ke tahap selanjutnya.' 
                      : lastCheckInResult.status === 'NOT_ALLOWED'
                      ? 'Mohon menunggu hingga antrean Anda dipanggil oleh petugas'
                      : lastCheckInResult.status === 'ALREADY_CHECKED_IN'
                      ? 'Tiket ini sudah melakukan check-in sebelumnya. Tidak perlu check-in ulang.'
                      : 'Proses check-in gagal. Silakan coba lagi atau hubungi petugas.' }}
                  </p>
                </div>
              </div>
            </div>
            
            <!-- Patient Info Card -->
            <v-card variant="outlined" class="patient-info-card" elevation="0">
              <v-card-text class="py-3">
                <div class="d-flex justify-space-between align-center">
                  <div class="d-flex align-center">
                    <v-icon color="primary" class="mr-2 patient-info-icon" size="20">mdi-account-circle</v-icon>
                    <div>
                      <p class="text-caption patient-info-label mb-0">ID Pasien</p>
                      <p class="text-body-2 patient-info-value mb-0 font-weight-medium">{{ scannedData?.split('|')[0] || 'N/A' }}</p>
                    </div>
                  </div>
                  <div class="text-right">
                    <p class="text-caption patient-info-label mb-0">Waktu Scan</p>
                    <p class="text-body-2 patient-info-value mb-0 font-weight-medium">{{ getCurrentTime() }}</p>
                  </div>
                </div>
              </v-card-text>
            </v-card>
          </div>
        </v-card-text>
        
        <v-card-actions class="pa-3 pt-0">
          <v-row dense>
            <v-col v-if="infoAction === 'kembali'" cols="12">
              <v-btn
                color="grey-darken-1"
                class="text-white font-weight-semibold text-none dialog-button"
                size="large"
                block
                variant="flat"
                @click="handleInfoAction"
                elevation="0"
                prepend-icon="mdi-arrow-left"
                rounded="lg"
              >
                Kembali
              </v-btn>
            </v-col>
            <template v-else>
              <v-col cols="12">
                <v-btn
                  :color="lastCheckInResult?.success && infoAction === 'checkin' ? 'success' : 'primary'"
                  class="text-white font-weight-semibold text-none dialog-button"
                  size="large"
                  block
                  variant="flat"
                  @click="handleInfoAction"
                  elevation="2"
                  :prepend-icon="lastCheckInResult?.success && infoAction === 'checkin' ? 'mdi-check' : 'mdi-close'"
                  rounded="lg"
                >
                  Tutup
                </v-btn>
              </v-col>
            </template>
          </v-row>
        </v-card-actions>
      </v-card>
    </v-dialog>
    
    <!-- Enhanced Snackbar -->
    <v-snackbar
      v-model="snackbar.show"
      :color="snackbar.color"
      :timeout="snackbar.timeout"
      location="bottom right"
      rounded="pill"
      elevation="24"
      class="custom-snackbar"
    >
      <div class="d-flex align-center">
        <v-avatar :color="snackbar.color" size="32" class="mr-3">
          <v-icon size="20" color="white">{{ snackbar.icon }}</v-icon>
        </v-avatar>
        <div>
          <div class="font-weight-bold">{{ snackbar.title }}</div>
          <div class="text-body-2">{{ snackbar.message }}</div>
        </div>
      </div>
    </v-snackbar>

    <!-- History Dialog -->
    <v-dialog 
      v-model="historyDialog" 
      max-width="800" 
      persistent
      transition="dialog-transition"
      scrim="rgba(0, 0, 0, 0.5)"
      class="blur-dialog"
    >
      <v-card class="rounded-xl dialog-card" elevation="24">
        <div class="dialog-header text-center pa-5" style="background: linear-gradient(135deg, $primary-600 0%, $primary-700 100%);">
          <h2 class="text-h5 font-weight-bold text-white mb-1">
            <v-icon color="white" class="mr-2" size="24">mdi-history</v-icon>
            Riwayat Check-in
          </h2>
          <p class="text-body-2 text-white opacity-90">Daftar check-in yang telah dilakukan</p>
        </div>
        
        <v-card-text class="pa-3">
          <!-- Header Stats -->
          <div class="history-header-stats mb-3">
            <div class="history-header-title mb-2">
              <h3 class="text-subtitle-1 font-weight-bold d-flex align-center">
                <v-icon size="20" class="mr-2" color="primary">mdi-history</v-icon>
                Riwayat Check-in
              </h3>
            </div>
            <v-row dense>
              <v-col cols="6" md="3">
                <div class="stat-card-header">
                  <div class="stat-icon-header stat-icon-total">
                    <v-icon size="20">mdi-history</v-icon>
                  </div>
                  <div class="stat-content-header">
                    <div class="stat-value-header">{{ checkInHistory.length }}</div>
                    <div class="stat-label-header">Total</div>
                  </div>
                </div>
              </v-col>
              <v-col cols="6" md="3">
                <div class="stat-card-header">
                  <div class="stat-icon-header stat-icon-success">
                    <v-icon size="20">mdi-check-circle</v-icon>
                  </div>
                  <div class="stat-content-header">
                    <div class="stat-value-header">{{ checkInHistory.filter(item => item.status === 'success' || item.status === 'ALLOWED').length }}</div>
                    <div class="stat-label-header">Berhasil</div>
                  </div>
                </div>
              </v-col>
              <v-col cols="6" md="3">
                <div class="stat-card-header">
                  <div class="stat-icon-header stat-icon-failed">
                    <v-icon size="20">mdi-close-circle</v-icon>
                  </div>
                  <div class="stat-content-header">
                    <div class="stat-value-header">{{ checkInHistory.filter(item => item.status === 'failed' || item.status === 'NOT_ALLOWED').length }}</div>
                    <div class="stat-label-header">Gagal</div>
                  </div>
                </div>
              </v-col>
              <v-col cols="6" md="3">
                <div class="stat-card-header">
                  <div class="stat-icon-header stat-icon-filtered">
                    <v-icon size="20">mdi-filter</v-icon>
                  </div>
                  <div class="stat-content-header">
                    <div class="stat-value-header">{{ filteredHistory.length }}</div>
                    <div class="stat-label-header">Tersaring</div>
                  </div>
                </div>
              </v-col>
            </v-row>
          </div>

          <!-- Filter dan Search -->
          <div class="mb-3">
            <v-row dense>
              <v-col cols="12" md="6">
                <v-text-field
                  v-model="historySearch"
                  label="Cari ID Pasien, Nomor Antrean, atau Klinik"
                  prepend-inner-icon="mdi-magnify"
                  variant="outlined"
                  density="comfortable"
                  clearable
                  hide-details
                ></v-text-field>
              </v-col>
              <v-col cols="12" md="3">
                <v-select
                  v-model="historyStatusFilter"
                  label="Filter Status"
                  :items="historyStatusOptions"
                  variant="outlined"
                  density="comfortable"
                  hide-details
                  clearable
                ></v-select>
              </v-col>
              <v-col cols="12" md="3">
                <v-btn
                  color="error"
                  variant="outlined"
                  block
                  @click="clearHistory"
                  :disabled="checkInHistory.length === 0"
                >
                  <v-icon start>mdi-delete</v-icon>
                  Hapus Semua
                </v-btn>
              </v-col>
            </v-row>
          </div>

          <!-- History List -->
          <div v-if="filteredHistory.length > 0">
            <!-- Info jumlah data -->
            <div class="mb-2 text-body-2 text-grey-darken-1">
              Menampilkan {{ (historyPage - 1) * historyItemsPerPage + 1 }} - {{ Math.min(historyPage * historyItemsPerPage, filteredHistory.length) }} dari {{ filteredHistory.length }} riwayat
            </div>
            
            <div class="history-list">
              <v-card
                v-for="(item, index) in paginatedHistory"
                :key="index"
                variant="flat"
                elevation="0"
                class="mb-1 history-item-dialog"
                :class="getStatusClass(item.status)"
              >
              <v-card-text class="pa-2">
                <div class="d-flex justify-space-between align-start">
                  <div class="flex-grow-1">
                    <!-- Header: Status & Method -->
                    <div class="d-flex align-center mb-1 gap-1">
                      <div class="history-status-badge-dialog" :class="`status-${getStatusColor(item.status)}`">
                        <v-icon size="14">{{ getStatusIcon(item.status) }}</v-icon>
                      </div>
                      <div>
                        <div class="history-status-text-dialog" :class="`text-${getStatusColor(item.status)}`">
                          {{ getStatusText(item.status) }}
                        </div>
                        <div class="history-method-text-dialog">
                          {{ item.method }}
                        </div>
                      </div>
                    </div>
                    
                    <!-- Queue Number -->
                    <div v-if="item.klinikQueueNumber || item.queueNumber" class="mb-1">
                      <div class="history-queue-badge-dialog">
                        <v-icon size="12" class="mr-1">mdi-ticket</v-icon>
                        <span class="font-weight-semibold">{{ item.klinikQueueNumber || item.queueNumber }}</span>
                      </div>
                    </div>
                    
                    <!-- Info Badges: Patient ID, Klinik & Pembayaran -->
                    <div class="d-flex flex-wrap gap-1 mb-1">
                      <div v-if="item.patientId" class="history-info-badge-dialog">
                        <v-icon size="12" class="mr-1">mdi-account-circle</v-icon>
                        <span>{{ item.patientId }}</span>
                      </div>
                      <div v-if="item.klinik && item.klinik !== 'N/A'" class="history-klinik-badge-dialog">
                        <v-icon size="12" class="mr-1">mdi-hospital-building</v-icon>
                        <span>{{ item.klinik }}</span>
                      </div>
                      <div v-if="item.pembayaran" class="history-payment-badge-dialog">
                        <v-icon size="12" class="mr-1">mdi-credit-card</v-icon>
                        <span>{{ item.pembayaran }}</span>
                      </div>
                    </div>
                    
                    <!-- Time Info -->
                    <div class="d-flex flex-wrap gap-1">
                      <div class="history-time-badge-dialog">
                        <v-icon size="10" class="mr-1">mdi-clock-outline</v-icon>
                        <span>{{ formatDateTime(item.checkInTime) }}</span>
                      </div>
                      <div v-if="item.checkInDate" class="history-time-badge-dialog">
                        <v-icon size="10" class="mr-1">mdi-calendar</v-icon>
                        <span>{{ formatDate(item.checkInDate) }}</span>
                      </div>
                    </div>
                  </div>
                  
                  <div class="ml-2">
                    <v-btn
                      icon
                      size="small"
                      variant="text"
                      color="error"
                      @click="deleteHistoryItem(index)"
                      class="history-delete-btn"
                    >
                      <v-icon size="18">mdi-delete-outline</v-icon>
                    </v-btn>
                  </div>
                </div>
              </v-card-text>
            </v-card>
            </div>
            
            <!-- Pagination -->
            <div v-if="totalHistoryPages > 1" class="mt-3 d-flex justify-center">
              <v-pagination
                v-model="historyPage"
                :length="totalHistoryPages"
                :total-visible="7"
                color="primary"
                rounded="circle"
              ></v-pagination>
            </div>
          </div>

          <!-- Empty State -->
          <div v-else class="text-center py-6">
            <v-icon size="48" color="grey-lighten-1" class="mb-2">mdi-history</v-icon>
            <p class="text-h6 text-grey mb-1">Belum ada riwayat check-in</p>
            <p class="text-body-2 text-grey">Riwayat check-in akan muncul di sini setelah Anda melakukan check-in</p>
          </div>
        </v-card-text>
        
        <v-card-actions class="pa-3 pt-0">
          <v-spacer></v-spacer>
          <v-btn
            color="primary"
            class="text-white font-weight-semibold text-none"
            size="large"
            variant="flat"
            @click="historyDialog = false"
            prepend-icon="mdi-close"
            rounded="lg"
            elevation="2"
          >
            Tutup
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <!-- QR History Dialog -->
    <v-dialog 
      v-model="qrHistoryDialog" 
      max-width="800" 
      persistent
      transition="dialog-transition"
      scrim="rgba(0, 0, 0, 0.5)"
      class="blur-dialog"
    >
      <v-card class="rounded-xl dialog-card" elevation="24">
        <div class="dialog-header text-center pa-5" style="background: linear-gradient(135deg, $secondary-500 0%, $secondary-600 100%);">
          <h2 class="text-h5 font-weight-bold text-white mb-1">
            <v-icon color="white" class="mr-2" size="24">mdi-qrcode-scan</v-icon>
            Riwayat QR Scan
          </h2>
          <p class="text-body-2 text-white opacity-90">Daftar QR code yang telah di-scan</p>
        </div>
        
        <v-card-text class="pa-3">
          <!-- Header Stats -->
          <div class="history-header-stats mb-3">
            <div class="history-header-title mb-2">
              <h3 class="text-subtitle-1 font-weight-bold d-flex align-center">
                <v-icon size="20" class="mr-2" color="secondary">mdi-qrcode-scan</v-icon>
                Riwayat QR Scan
              </h3>
            </div>
            <v-row dense>
              <v-col cols="6" md="4">
                <div class="stat-card-header">
                  <div class="stat-icon-header stat-icon-total">
                    <v-icon size="20">mdi-qrcode-scan</v-icon>
                  </div>
                  <div class="stat-content-header">
                    <div class="stat-value-header">{{ scannedQRHistory.length }}</div>
                    <div class="stat-label-header">Total Scan</div>
                  </div>
                </div>
              </v-col>
              <v-col cols="6" md="4">
                <div class="stat-card-header">
                  <div class="stat-icon-header stat-icon-filtered">
                    <v-icon size="20">mdi-filter</v-icon>
                  </div>
                  <div class="stat-content-header">
                    <div class="stat-value-header">{{ filteredQRHistory.length }}</div>
                    <div class="stat-label-header">Tersaring</div>
                  </div>
                </div>
              </v-col>
              <v-col cols="12" md="4">
                <v-btn
                  color="error"
                  variant="outlined"
                  block
                  @click="clearQRHistory"
                  :disabled="scannedQRHistory.length === 0"
                  class="mt-2 mt-md-0"
                >
                  <v-icon start>mdi-delete</v-icon>
                  Hapus Semua
                </v-btn>
              </v-col>
            </v-row>
          </div>

          <!-- Filter dan Search -->
          <div class="mb-3">
            <v-row dense>
              <v-col cols="12">
                <v-text-field
                  v-model="historySearch"
                  label="Cari Data QR Code"
                  prepend-inner-icon="mdi-magnify"
                  variant="outlined"
                  density="comfortable"
                  clearable
                  hide-details
                ></v-text-field>
              </v-col>
            </v-row>
          </div>

          <!-- QR History List -->
          <div v-if="filteredQRHistory.length > 0" class="history-list">
            <v-card
              v-for="(item, index) in filteredQRHistory"
              :key="index"
              variant="flat"
              elevation="0"
              class="mb-2 history-item-dialog history-item-qr"
            >
              <v-card-text class="pa-2">
                <div class="d-flex justify-space-between align-start">
                  <div class="flex-grow-1">
                    <!-- QR Data -->
                    <div class="mb-1">
                      <div class="history-qr-badge-dialog">
                        <v-icon size="14" class="mr-1">mdi-qrcode</v-icon>
                        <span class="font-weight-semibold">{{ item.data }}</span>
                      </div>
                    </div>
                    
                    <!-- Time Info -->
                    <div class="d-flex flex-wrap gap-1">
                      <div class="history-time-badge-dialog">
                        <v-icon size="10" class="mr-1">mdi-clock-outline</v-icon>
                        <span>{{ item.time }}</span>
                      </div>
                      <div class="history-time-badge-dialog">
                        <v-icon size="10" class="mr-1">mdi-calendar</v-icon>
                        <span>{{ item.date }}</span>
                      </div>
                    </div>
                  </div>
                  
                  <div class="ml-2 d-flex gap-1">
                    <v-btn
                      icon
                      size="small"
                      variant="text"
                      color="primary"
                      @click="useQRData(item.data)"
                      class="history-action-btn"
                    >
                      <v-icon size="18">mdi-refresh</v-icon>
                    </v-btn>
                    <v-btn
                      icon
                      size="small"
                      variant="text"
                      color="error"
                      @click="deleteQRHistoryItem(index)"
                      class="history-delete-btn"
                    >
                      <v-icon size="18">mdi-delete-outline</v-icon>
                    </v-btn>
                  </div>
                </div>
              </v-card-text>
            </v-card>
          </div>

          <!-- Empty State -->
          <div v-else class="text-center py-6">
            <v-icon size="48" color="grey-lighten-1" class="mb-2">mdi-qrcode-scan</v-icon>
            <p class="text-h6 text-grey mb-1">Belum ada riwayat QR scan</p>
            <p class="text-body-2 text-grey">Riwayat QR scan akan muncul di sini setelah Anda melakukan scan</p>
          </div>
        </v-card-text>
        
        <v-card-actions class="pa-3 pt-0">
          <v-spacer></v-spacer>
          <v-btn
            color="primary"
            class="text-white font-weight-semibold text-none"
            size="large"
            variant="flat"
            @click="qrHistoryDialog = false"
            prepend-icon="mdi-close"
            rounded="lg"
            elevation="2"
          >
            Tutup
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

  </v-app>
</template>

<script setup lang="ts">
import { ref, computed, nextTick, onMounted, onUnmounted, watch } from 'vue';
import { useQueueStore } from '@/stores/queueStore';
import { useMasterStore } from '@/stores/masterStore';

definePageMeta({
  // middleware:['auth'],
  layout: false,
})

const queueStore = useQueueStore();
const masterStore = useMasterStore();


// TypeScript declaration for QRCode
declare global {
  interface Window {
    QRCode: any;
  }
}

// --- DESAIN & TEMA ---
const primaryColor = ref('#1565C0');
const secondaryColor = ref('#FB8C00');

// --- LOGIKA ---
const tab = ref('checkin');
const infoDialog = ref(false);
const infoMessage = ref('');
const infoAction = ref<'checkin' | 'kembali'>('kembali');
let autoCloseTimer: ReturnType<typeof setTimeout> | null = null; 
const scannedData = ref<string | null>(null);
const manualInput = ref('');
const manualForm = ref(null);
const lastCheckInResult = ref<{ success: boolean; patientId: string; status: string } | null>(null);

// QR Scanner state
const isScanning = ref(false);
const hasCamera = ref(false);
const cameraChecking = ref(true);
const cameraReady = ref(false);
let html5QrCode: any = null;
const qrCodeId = 'qr-reader';
let lastScannedQR: string | null = null;
let lastScanTime: number = 0;
const SCAN_DEBOUNCE_MS = 2000; // 2 detik debounce untuk mencegah scan berulang

// Daftar QR code yang sudah berhasil di-scan (untuk mencegah double antrian)
const SUCCESSFUL_SCANS_KEY = 'successful_qr_scans';
const successfulScans = ref<Set<string>>(new Set());

// Detect mobile device
const isMobile = ref(false);
if (typeof window !== 'undefined') {
  isMobile.value = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || 
                   (window.innerWidth <= 768);
}

// History Dialog
const historyDialog = ref(false);
const historySearch = ref('');
const historyStatusFilter = ref('');
const historyPage = ref(1);
const historyItemsPerPage = ref(10);
const checkInHistory = ref<Array<{
  patientId: string;
  queueNumber?: string;
  klinikQueueNumber?: string;
  pembayaran?: string;
  status: string;
  checkInTime: string;
  checkInDate: string;
  method: string;
  klinik?: string;
  kodeKlinik?: string;
}>>([]);

// QR History Dialog
const qrHistoryDialog = ref(false);
const scannedQRHistory = ref<Array<{
  data: string;
  timestamp: string;
  date: string;
  time: string;
}>>([]);

const historyStatusOptions = [
  { title: 'Berhasil', value: 'success' },
  { title: 'Gagal', value: 'failed' },
  { title: 'Pending', value: 'pending' }
];

// Generate QR variables
const generatePatientId = ref('');
const generateStatus = ref('ALLOWED');
const generatedQRData = ref('');
const selectedKlinik = ref('');
const statusOptions = [
  { title: 'Diizinkan Check-in', value: 'ALLOWED' },
  { title: 'Belum Diizinkan', value: 'NOT_ALLOWED' }
];

// Get klinik list for dropdown
const klinikOptions = computed(() => {
  const klinikList = masterStore.klinikList.map((k: { kode: string; nama: string }) => ({
    title: `${k.kode} - ${k.nama}`,
    value: k.kode
  }));
  
  // Tambahkan opsi "UM" (Umum) di awal list
  return [
    { title: 'UM - Umum', value: 'UM' },
    ...klinikList
  ];
});

// Sequential Patient ID Management
const PATIENT_ID_STORAGE_KEY = 'checkin_patient_id_counter';
const QUEUE_NUMBER_STORAGE_KEY = 'checkin_queue_number_counters';
const LAST_RESET_TIME_KEY = 'checkin_last_reset_time';
const RESET_HOUR = 22; // Jam 10 malam (22:00)
const HISTORY_STORAGE_KEY = 'checkin_history';

// Check and reset daily at 10 PM (22:00)
const checkAndResetDaily = () => {
  if (typeof window === 'undefined') return;
  
  const now = new Date();
  const currentHour = now.getHours();
  const currentDate = now.toISOString().split('T')[0]; // YYYY-MM-DD
  
  // Get last reset time
  const lastResetTime = localStorage.getItem(LAST_RESET_TIME_KEY);
  let lastResetDate = null;
  
  if (lastResetTime) {
    const lastReset = new Date(lastResetTime);
    lastResetDate = lastReset.toISOString().split('T')[0];
  }
  
  // Check if it's 10 PM or later and hasn't been reset today
  // Reset happens at 22:00 (10 PM) or later, but only once per day
  const shouldReset = currentHour >= RESET_HOUR && lastResetDate !== currentDate;
  
  if (shouldReset) {
    // Reset counters to 0 (so next will be 0001)
    localStorage.setItem(PATIENT_ID_STORAGE_KEY, '0');
    localStorage.setItem(QUEUE_NUMBER_STORAGE_KEY, '{}');
    
    // Clear check-in history (reset riwayat check-in)
    checkInHistory.value = [];
    if (typeof window !== 'undefined') {
      localStorage.removeItem(HISTORY_STORAGE_KEY);
    }
    
    // Save reset time
    localStorage.setItem(LAST_RESET_TIME_KEY, now.toISOString());
    
    console.log('✅ Daily reset executed at', now.toLocaleString('id-ID'), '- Counters and history reset');
  }
};

// Generate sequential patient ID (P-00001, P-00002, etc.)
const generateSequentialPatientId = (): string => {
  if (typeof window === 'undefined') return 'P-00001';
  
  // Check and reset if needed (before generating)
  checkAndResetDaily();
  
  let counter = parseInt(localStorage.getItem(PATIENT_ID_STORAGE_KEY) || '0', 10);
  counter += 1;
  localStorage.setItem(PATIENT_ID_STORAGE_KEY, counter.toString());
  
  return `P-${String(counter).padStart(5, '0')}`;
};

// Generate sequential queue number based on klinik code (AN-0001, AS-0001, etc.)
const generateSequentialQueueNumber = (kodeKlinik: string): string => {
  if (typeof window === 'undefined') return `${kodeKlinik}-0001`;
  
  // Check and reset if needed (before generating)
  checkAndResetDaily();
  
  const counters = JSON.parse(localStorage.getItem(QUEUE_NUMBER_STORAGE_KEY) || '{}');
  let counter = parseInt(counters[kodeKlinik] || '0', 10);
  counter += 1;
  counters[kodeKlinik] = counter;
  localStorage.setItem(QUEUE_NUMBER_STORAGE_KEY, JSON.stringify(counters));
  
  return `${kodeKlinik}-${String(counter).padStart(4, '0')}`;
};


const snackbar = ref({
  show: false,
  title: '',
  message: '',
  color: '',
  icon: '',
  timeout: 4000,
});

// Check camera availability
const checkCameraAvailability = async () => {
  cameraChecking.value = true;
  hasCamera.value = false;
  
  // Check if browser supports mediaDevices
  if (typeof navigator === 'undefined' || !navigator.mediaDevices) {
    console.error('navigator.mediaDevices is not supported');
    showSnackbar('Error', 'Browser tidak mendukung akses kamera. Pastikan menggunakan HTTPS atau localhost.', 'error', 'mdi-camera-off');
    cameraChecking.value = false;
    return;
  }

  try {
    // First, request permission by trying to get user media
    // This is required for enumerateDevices to return device labels
    const stream = await navigator.mediaDevices.getUserMedia({ video: true });
    
    // Stop the stream immediately after getting permission
    stream.getTracks().forEach(track => track.stop());
    
    // Now enumerate devices (will have labels after permission granted)
    const devices = await navigator.mediaDevices.enumerateDevices();
    const videoDevices = devices.filter(device => device.kind === 'videoinput');
    
    hasCamera.value = videoDevices.length > 0;
    
    if (hasCamera.value) {
      console.log(`Found ${videoDevices.length} camera(s):`, videoDevices.map(d => d.label || d.deviceId));
    } else {
      console.warn('No video input devices found');
      showSnackbar('Warning', 'Tidak ada kamera yang terdeteksi', 'warning', 'mdi-camera-off');
    }
  } catch (err: any) {
    console.error('Error checking camera:', err);
    hasCamera.value = false;
    
    let errorMessage = 'Gagal mengakses kamera. ';
    if (err.name === 'NotAllowedError' || err.name === 'PermissionDeniedError') {
      errorMessage += 'Izin kamera ditolak. Mohon izinkan akses kamera di pengaturan browser.';
    } else if (err.name === 'NotFoundError' || err.name === 'DevicesNotFoundError') {
      errorMessage += 'Tidak ada kamera yang ditemukan.';
    } else if (err.name === 'NotReadableError' || err.name === 'TrackStartError') {
      errorMessage += 'Kamera sedang digunakan aplikasi lain.';
    } else if (err.name === 'OverconstrainedError' || err.name === 'ConstraintNotSatisfiedError') {
      errorMessage += 'Kamera tidak memenuhi persyaratan.';
    } else {
      errorMessage += `Error: ${err.message || err.name}`;
    }
    
    showSnackbar('Error', errorMessage, 'error', 'mdi-camera-off');
  } finally {
    cameraChecking.value = false;
  }
};

// Test camera function for debugging
const testCamera = async () => {
  try {
    showSnackbar('Info', 'Menguji akses kamera...', 'info', 'mdi-camera');
    
    if (typeof navigator === 'undefined') {
      showSnackbar('Error', 'navigator is undefined - pastikan di browser, bukan SSR', 'error', 'mdi-alert');
      return;
    }
    
    if (!navigator.mediaDevices) {
      showSnackbar('Error', 'navigator.mediaDevices is undefined - pastikan menggunakan HTTPS atau localhost', 'error', 'mdi-alert');
      return;
    }
    
    if (!navigator.mediaDevices.getUserMedia) {
      showSnackbar('Error', 'getUserMedia is not supported', 'error', 'mdi-alert');
      return;
    }
    
    const stream = await navigator.mediaDevices.getUserMedia({ 
      video: {
        facingMode: 'user',
        width: { ideal: 1920, min: 1280 },
        height: { ideal: 1080, min: 720 }
      } 
    });
    
    showSnackbar('Success', 'Kamera berhasil diakses!', 'success', 'mdi-check-circle');
    
    // Stop stream after 2 seconds
    setTimeout(() => {
      stream.getTracks().forEach(track => track.stop());
    }, 2000);
    
  } catch (err: any) {
    console.error('Test camera error:', err);
    let errorMsg = `Error: ${err.name || 'Unknown'}`;
    if (err.message) errorMsg += ` - ${err.message}`;
    showSnackbar('Error', errorMsg, 'error', 'mdi-alert');
  }
};

// QR Scanner Functions
const startScanning = async () => {
  // Check camera first
  if (!hasCamera.value) {
    await checkCameraAvailability();
    if (!hasCamera.value) {
      showSnackbar('Error', 'Kamera tidak tersedia. Silakan gunakan input manual atau pastikan kamera terhubung.', 'error', 'mdi-camera-off');
      return;
    }
  }

  try {
    // Set scanning state first to render the element
    isScanning.value = true;
    
    // Wait for DOM to update and element to be rendered
    await nextTick();
    
    // Wait a bit more to ensure element is fully rendered
    await new Promise(resolve => setTimeout(resolve, 200));
    
    // Check if element exists
    const qrElement = document.getElementById(qrCodeId);
    if (!qrElement) {
      console.error(`Element with id "${qrCodeId}" not found in DOM`);
      isScanning.value = false;
      showSnackbar('Error', 'Element scanner tidak ditemukan. Silakan refresh halaman.', 'error', 'mdi-alert');
      return;
    }
    
    // Cleanup existing instance if any (untuk handle refresh)
    if (html5QrCode) {
      try {
        // Try to check if scanner is active and stop it
        try {
          if (html5QrCode.getState && html5QrCode.getState() === 2) { // Scanning state
            await html5QrCode.stop();
            await html5QrCode.clear();
          }
        } catch {
          // If getState doesn't exist or fails, just try to stop
          await html5QrCode.stop().catch(() => {});
          await html5QrCode.clear().catch(() => {});
        }
        html5QrCode = null;
      } catch (err) {
        console.warn('Error cleaning up existing QR scanner:', err);
        html5QrCode = null;
      }
    }
    
    // Dynamic import html5-qrcode
    if (!html5QrCode) {
      const { Html5Qrcode: Html5QrcodeClass } = await import('html5-qrcode');
      html5QrCode = new Html5QrcodeClass(qrCodeId);
      console.log('Html5Qrcode initialized');
    }

    if (html5QrCode) {
      cameraReady.value = false;
      
      // Konfigurasi kamera untuk mobile dan desktop
      const cameraConfig = isMobile.value 
        ? { facingMode: "environment" } // Mobile: gunakan kamera belakang
        : { facingMode: "user" }; // Desktop: gunakan kamera depan (webcam)
      
      // Video constraints yang dioptimalkan untuk kualitas tinggi
      const baseVideoConstraints = isMobile.value
        ? {
            facingMode: "environment",
            width: { ideal: 1280, min: 640, max: 1920 },
            height: { ideal: 720, min: 480, max: 1080 }
          }
        : {
            facingMode: "user",
            width: { ideal: 1920, min: 1280, max: 1920 },
            height: { ideal: 1080, min: 720, max: 1080 }
          };
      
      // Tambahkan advanced constraints hanya jika didukung
      const videoConstraints: any = { ...baseVideoConstraints };
      
      console.log('Starting QR scanner with config:', {
        isMobile: isMobile.value,
        cameraConfig,
        videoConstraints
      });
      
      try {
        await html5QrCode.start(
          cameraConfig,
          {
            fps: isMobile.value ? 30 : 30, // FPS tinggi untuk deteksi lebih baik dan smooth
            qrbox: function(viewfinderWidth: number, viewfinderHeight: number) {
              // QR box dengan ukuran lebih besar untuk deteksi lebih mudah
              const minEdgeSize = Math.min(viewfinderWidth, viewfinderHeight);
              // Gunakan 80-90% dari viewfinder untuk area scanning yang lebih besar
              const percentageSize = Math.floor(minEdgeSize * 0.80);
              // Atau ukuran tetap yang lebih besar
              const fixedSize = isMobile.value ? 250 : 250;
              // Gunakan yang lebih besar antara percentage atau fixed
              const qrboxSize = Math.max(percentageSize, fixedSize);
              
              // Pastikan tidak melebihi viewfinder
              const finalSize = Math.min(qrboxSize, minEdgeSize * 0.80);
              
              console.log('QR Box size:', finalSize, 'Viewfinder:', viewfinderWidth, 'x', viewfinderHeight);
              
              return {
                width: Math.max(finalSize, 250), // Minimum 250px untuk deteksi lebih baik
                height: Math.max(finalSize, 250)
              };
            },
            aspectRatio: 1.0,
            disableFlip: false,
            videoConstraints: videoConstraints,
            rememberLastUsedCamera: true,
            showTorchButtonIfSupported: true,
            // Tambahkan opsi untuk meningkatkan deteksi
            verbose: false // Set true untuk debugging
          },
          (decodedText: string, decodedResult: any) => {
            // QR Code berhasil di-scan
            console.log('✅ QR Code detected:', decodedText);
            console.log('📊 Decoded result:', decodedResult);
            
            // Validasi dan proses QR code
            if (decodedText && decodedText.trim() !== '') {
              handleQRScanSuccess(decodedText);
            } else {
              console.warn('Empty QR code detected');
            }
          },
          (errorMessage: string) => {
            // Log error untuk debugging - hanya log error penting
            // Error ini biasanya muncul terus menerus saat tidak ada QR code yang terdeteksi
            // Jadi kita filter untuk menghindari spam console
            if (errorMessage) {
              // Filter out common non-critical errors
              const isCriticalError = !errorMessage.includes('NotFoundException') && 
                                     !errorMessage.includes('No QR') &&
                                     !errorMessage.includes('QR code parse error') &&
                                     !errorMessage.includes('QR code parse error, error') &&
                                     !errorMessage.includes('QR code decode error');
              
              if (isCriticalError) {
                console.warn('QR Scanner warning:', errorMessage);
              }
            }
          }
        );
        
        // Set camera ready setelah sedikit delay untuk memastikan video sudah dimuat
        setTimeout(() => {
          cameraReady.value = true;
          console.log('Camera ready, scanner is active');
        }, 500);
        
        showSnackbar('Info', 'Scanner aktif. Arahkan kamera ke QR code dan pastikan pencahayaan cukup', 'info', 'mdi-camera');
      } catch (cameraError: any) {
        console.error('Camera error:', cameraError);
        
        // Jika kamera belakang tidak tersedia di mobile, coba kamera depan
        if (isMobile.value && cameraError.name === 'NotFoundError') {
          try {
            console.log('Trying front camera as fallback...');
            await html5QrCode.start(
              { facingMode: "user" },
              {
                fps: 30,
                qrbox: function(viewfinderWidth: number, viewfinderHeight: number) {
                  const minEdgeSize = Math.min(viewfinderWidth, viewfinderHeight);
                  const percentageSize = Math.floor(minEdgeSize * 0.85);
                  const fixedSize = 300;
                  const qrboxSize = Math.max(percentageSize, fixedSize);
                  const finalSize = Math.min(qrboxSize, minEdgeSize * 0.95);
                  
                  return {
                    width: Math.max(finalSize, 250),
                    height: Math.max(finalSize, 250)
                  };
                },
                aspectRatio: 1.0,
                disableFlip: false,
                videoConstraints: {
                  facingMode: "user",
                  width: { ideal: 1280, min: 640, max: 1920 },
                  height: { ideal: 720, min: 480, max: 1080 }
                },
                rememberLastUsedCamera: true,
                verbose: false
              },
              (decodedText: string, decodedResult: any) => {
                console.log('✅ QR Code detected (front camera):', decodedText);
                if (decodedText && decodedText.trim() !== '') {
                  handleQRScanSuccess(decodedText);
                }
              },
              (errorMessage: string) => {
                if (errorMessage) {
                  const isCriticalError = !errorMessage.includes('NotFoundException') && 
                                         !errorMessage.includes('No QR') &&
                                         !errorMessage.includes('QR code parse error') &&
                                         !errorMessage.includes('QR code decode error');
                  
                  if (isCriticalError) {
                    console.warn('QR Scanner (front) warning:', errorMessage);
                  }
                }
              }
            );
            
            setTimeout(() => {
              cameraReady.value = true;
            }, 500);
            
            showSnackbar('Info', 'Menggunakan kamera depan. Arahkan QR code ke kamera', 'info', 'mdi-camera');
          } catch (fallbackError: any) {
            console.error('Fallback camera also failed:', fallbackError);
            throw cameraError; // Throw original error
          }
        } else {
          // Coba menggunakan deviceId langsung jika facingMode gagal
          try {
            console.log('Trying to get camera devices...');
            const devices = await navigator.mediaDevices.enumerateDevices();
            const videoDevices = devices.filter(device => device.kind === 'videoinput');
            
            if (videoDevices.length > 0) {
              // Gunakan kamera pertama yang tersedia
              const deviceId = videoDevices[0].deviceId;
              console.log('Using device:', deviceId, videoDevices[0].label);
              
              await html5QrCode.start(
                { deviceId: { exact: deviceId } },
                {
                  fps: 30,
                  qrbox: function(viewfinderWidth: number, viewfinderHeight: number) {
                    const minEdgeSize = Math.min(viewfinderWidth, viewfinderHeight);
                    const percentageSize = Math.floor(minEdgeSize * 0.80);
                    const fixedSize = isMobile.value ? 300 : 400;
                    const qrboxSize = Math.max(percentageSize, fixedSize);
                    const finalSize = Math.min(qrboxSize, minEdgeSize * 0.80);
                    
                    return {
                      width: Math.max(finalSize, 250),
                      height: Math.max(finalSize, 250)
                    };
                  },
                  aspectRatio: 1.0,
                  disableFlip: false,
                  videoConstraints: {
                    deviceId: { exact: deviceId },
                    width: { ideal: isMobile.value ? 1280 : 1920, min: isMobile.value ? 640 : 1280, max: isMobile.value ? 1920 : 1920 },
                    height: { ideal: isMobile.value ? 720 : 1080, min: isMobile.value ? 480 : 720, max: isMobile.value ? 1080 : 1080 }
                  },
                  rememberLastUsedCamera: true,
                  verbose: false
                },
                (decodedText: string, decodedResult: any) => {
                  console.log('✅ QR Code detected (deviceId):', decodedText);
                  if (decodedText && decodedText.trim() !== '') {
                    handleQRScanSuccess(decodedText);
                  }
                },
                (errorMessage: string) => {
                  if (errorMessage) {
                    const isCriticalError = !errorMessage.includes('NotFoundException') && 
                                           !errorMessage.includes('No QR') &&
                                           !errorMessage.includes('QR code parse error') &&
                                           !errorMessage.includes('QR code decode error');
                    
                    if (isCriticalError) {
                      console.warn('QR Scanner (deviceId) warning:', errorMessage);
                    }
                  }
                }
              );
              
              setTimeout(() => {
                cameraReady.value = true;
              }, 500);
              
              showSnackbar('Info', 'Scanner aktif menggunakan kamera yang tersedia', 'info', 'mdi-camera');
            } else {
              throw cameraError;
            }
          } catch (deviceError: any) {
            console.error('DeviceId approach also failed:', deviceError);
            throw cameraError;
          }
        }
      }
    }
  } catch (err: any) {
    console.error('Error starting scanner:', err);
    isScanning.value = false;
    cameraReady.value = false;
    
    // Don't set hasCamera to false if it was detected, just log the error
    let errorMessage = 'Gagal memulai scanner. ';
    
    if (err.message && err.message.includes('not found')) {
      errorMessage = 'Element scanner tidak ditemukan. Silakan refresh halaman dan coba lagi.';
      console.error('Element not found error. Element ID:', qrCodeId);
    } else if (err.name === 'NotAllowedError') {
      errorMessage = 'Akses kamera ditolak. Mohon izinkan akses kamera di pengaturan browser.';
    } else if (err.name === 'NotFoundError') {
      errorMessage = 'Kamera tidak ditemukan. Silakan gunakan input manual.';
      hasCamera.value = false;
    } else if (err.name === 'NotReadableError') {
      errorMessage = 'Kamera sedang digunakan aplikasi lain. Tutup aplikasi lain yang menggunakan kamera.';
    } else {
      errorMessage += err.message || err.name || 'Unknown error';
    }
    
    showSnackbar('Error', errorMessage, 'error', 'mdi-alert');
  }
};

const stopScanning = async () => {
  try {
    if (html5QrCode) {
      // Stop scanner
      if (isScanning.value) {
        await html5QrCode.stop();
        await html5QrCode.clear();
      }
      
      // Note: Media tracks are automatically stopped when html5QrCode.stop() is called
      
      isScanning.value = false;
      cameraReady.value = false;
      showSnackbar('Info', 'Scanner dihentikan', 'info', 'mdi-camera-off');
    }
  } catch (err: any) {
    console.error('Error stopping scanner:', err);
    isScanning.value = false;
    cameraReady.value = false;
    // Force cleanup
    html5QrCode = null;
  }
};

const handleQRScanSuccess = (decodedText: string) => {
  console.log('🎯 QR Scan Success! Data:', decodedText);
  
  // Validasi data QR
  if (!decodedText || decodedText.trim() === '') {
    console.warn('QR Code data is empty');
    showSnackbar('Error', 'QR Code tidak valid atau kosong', 'error', 'mdi-alert');
    return;
  }
  
  // Cek apakah QR code sudah pernah berhasil di-scan (mencegah double antrian)
  // Hanya abaikan jika benar-benar sudah berhasil check-in sebelumnya (status di-loket)
  if (isQRCodeAlreadyScanned(decodedText)) {
    // Verifikasi ulang: cek apakah pasien benar-benar sudah check-in di queueStore
    const cleanInput = String(decodedText).trim();
    const patientInStore = queueStore.allPatients.find(p => {
      const patientBarcode = String(p.barcode || '').trim();
      return patientBarcode === cleanInput || patientBarcode.toUpperCase() === cleanInput.toUpperCase();
    });
    
    if (patientInStore && patientInStore.status === 'di-loket') {
      // Pasien benar-benar sudah check-in, abaikan scan
      console.log('⏭️ Scan diabaikan: QR code sudah pernah berhasil di-scan dan pasien sudah di-loket');
      showSnackbar('Peringatan', 'QR Code ini sudah pernah berhasil di-scan. Tidak dapat digunakan lagi untuk mencegah double antrian.', 'warning', 'mdi-alert-circle');
      return;
    } else {
      // Pasien belum benar-benar check-in, mungkin ada masalah di data sebelumnya
      // Biarkan scan berlanjut untuk verifikasi ulang
      console.warn('⚠️ QR code marked as scanned but patient not in di-loket status, allowing re-scan for verification');
      // Hapus dari successful scans untuk memungkinkan scan ulang
      if (typeof window !== 'undefined' && successfulScans.value.has(decodedText)) {
        successfulScans.value.delete(decodedText);
        const scansArray = Array.from(successfulScans.value);
        localStorage.setItem(SUCCESSFUL_SCANS_KEY, JSON.stringify(scansArray));
      }
    }
  }
  
  // Debounce: cegah scan berulang dalam waktu singkat
  const now = Date.now();
  if (lastScannedQR === decodedText && (now - lastScanTime) < SCAN_DEBOUNCE_MS) {
    console.log('⏭️ Scan diabaikan (debounce): QR code sama dalam waktu singkat');
    return;
  }
  
  // Update last scan info
  lastScannedQR = decodedText;
  lastScanTime = now;
  
  // Simpan data QR yang di-scan
  scannedData.value = decodedText;
  
  // Scanner tetap berjalan untuk memungkinkan scan QR code berikutnya
  
  // Proses data QR
  try {
    // onDetect is async, so we need to handle it properly
    onDetect(decodedText).catch((error) => {
      console.error('Error processing QR data in onDetect:', error);
      // Jangan simpan sebagai successful scan jika ada error
      // Hanya tampilkan error message
      showSnackbar('Error', `Gagal memproses data QR Code: ${error.message || 'Error tidak diketahui'}`, 'error', 'mdi-alert');
      
      // Simpan ke history sebagai failed
      saveToHistory({
        patientId: decodedText,
        queueNumber: null,
        klinikQueueNumber: null,
        pembayaran: 'N/A',
        status: 'failed',
        checkInTime: new Date().toISOString(),
        checkInDate: new Date().toISOString(),
        method: 'QR Scan',
        klinik: 'N/A',
        kodeKlinik: null
      });
    });
  } catch (error) {
    console.error('Error processing QR data:', error);
    showSnackbar('Error', `Gagal memproses data QR Code: ${error instanceof Error ? error.message : 'Error tidak diketahui'}`, 'error', 'mdi-alert');
    
    // Simpan ke history sebagai failed
    saveToHistory({
      patientId: decodedText,
      queueNumber: null,
      klinikQueueNumber: null,
      pembayaran: 'N/A',
      status: 'failed',
      checkInTime: new Date().toISOString(),
      checkInDate: new Date().toISOString(),
      method: 'QR Scan',
      klinik: 'N/A',
      kodeKlinik: null
    });
  }
  
  // Simpan ke localStorage untuk riwayat (selalu simpan, baik berhasil atau gagal)
  saveScannedQRData(decodedText);
};

// Simpan data QR yang di-scan ke localStorage
const saveScannedQRData = (qrData: string) => {
  if (typeof window !== 'undefined') {
    const scannedQRs = JSON.parse(localStorage.getItem('scanned_qr_data') || '[]');
    scannedQRs.unshift({
      data: qrData,
      timestamp: new Date().toISOString(),
      date: new Date().toLocaleDateString('id-ID'),
      time: new Date().toLocaleTimeString('id-ID').replace(/\./g, ':')
    });
    
    // Simpan maksimal 50 item
    if (scannedQRs.length > 50) {
      scannedQRs.pop();
    }
    
    localStorage.setItem('scanned_qr_data', JSON.stringify(scannedQRs));
  }
};

// Load successful scans dari localStorage
const loadSuccessfulScans = () => {
  if (typeof window !== 'undefined') {
    const stored = localStorage.getItem(SUCCESSFUL_SCANS_KEY);
    if (stored) {
      try {
        const scansArray = JSON.parse(stored);
        successfulScans.value = new Set(scansArray);
      } catch (e) {
        console.error('Error loading successful scans:', e);
        successfulScans.value = new Set();
      }
    }
  }
};

// Simpan successful scan ke localStorage
const saveSuccessfulScan = (qrData: string) => {
  if (typeof window !== 'undefined') {
    successfulScans.value.add(qrData);
    const scansArray = Array.from(successfulScans.value);
    localStorage.setItem(SUCCESSFUL_SCANS_KEY, JSON.stringify(scansArray));
  }
};

// Cek apakah QR code sudah pernah berhasil di-scan
const isQRCodeAlreadyScanned = (qrData: string): boolean => {
  return successfulScans.value.has(qrData);
};

// Watch tab changes untuk stop scanner saat pindah tab
watch(tab, (newTab) => {
  if (newTab !== 'checkin' && isScanning.value) {
    stopScanning();
  }
  // Check camera when switching to checkin tab
  if (newTab === 'checkin' && !hasCamera.value && !cameraChecking.value) {
    checkCameraAvailability();
  }
  // Reset generate patient ID when switching to generate tab (to ensure fresh ID after reset)
  if (newTab === 'generate') {
    // Check and reset daily first
    checkAndResetDaily();
    // Generate new patient ID (will start from 00001 if reset happened)
    generatePatientId.value = generateSequentialPatientId();
  }
});

// Check camera on mount and initialize patient ID
onMounted(async () => {
  if (typeof window !== 'undefined') {
    // Wait for DOM to be ready
    await nextTick();
    
    // Reset tab to checkin (untuk handle refresh)
    tab.value = 'checkin';
    
    // Wait again to ensure tab is rendered
    await nextTick();
    
    // Reset state saat mount (untuk handle refresh)
    isScanning.value = false;
    cameraReady.value = false;
    scannedData.value = null;
    manualInput.value = '';
    
    // Cleanup QR scanner instance jika masih ada dari refresh sebelumnya
    if (html5QrCode) {
      try {
        if (isScanning.value) {
          await html5QrCode.stop();
          await html5QrCode.clear();
        }
        html5QrCode = null;
      } catch (err) {
        console.warn('Error cleaning up QR scanner on mount:', err);
        html5QrCode = null;
      }
    }
    
    // Clear any existing video streams (cleanup dari refresh sebelumnya)
    // Note: We rely on html5QrCode cleanup to stop media tracks
    
    // Initialize patient ID if empty
    if (!generatePatientId.value) {
      generatePatientId.value = generateSequentialPatientId();
    }
    
    // Set default klinik if available
    if (!selectedKlinik.value && klinikOptions.value.length > 0) {
      selectedKlinik.value = klinikOptions.value[0].value;
    }
    
    // Check camera availability
    if (typeof navigator !== 'undefined') {
      if (navigator.mediaDevices && typeof navigator.mediaDevices.getUserMedia === 'function') {
        checkCameraAvailability();
      } else {
        console.warn('MediaDevices API not available. Make sure you are using HTTPS or localhost.');
        hasCamera.value = false;
        cameraChecking.value = false;
        showSnackbar('Warning', 'MediaDevices API tidak tersedia. Pastikan menggunakan HTTPS atau localhost.', 'warning', 'mdi-alert');
      }
    } else {
      hasCamera.value = false;
      cameraChecking.value = false;
    }
    
    // Load history untuk ditampilkan di sidebar
    loadHistory();
    
    // Check and reset daily at 10 PM
    checkAndResetDaily();
    
    // Set interval to check every minute for reset time
    setInterval(() => {
      checkAndResetDaily();
    }, 60000); // Check every minute
  } else {
    hasCamera.value = false;
    cameraChecking.value = false;
  }
});

// Cleanup saat component unmount
onUnmounted(async () => {
  // Stop scanning jika aktif
  if (html5QrCode) {
    try {
      if (isScanning.value) {
        await html5QrCode.stop();
        await html5QrCode.clear();
      }
      // Destroy instance
      html5QrCode = null;
    } catch (err) {
      console.warn('Error stopping scanner on unmount:', err);
      html5QrCode = null;
    }
  }
  
  // Note: Media tracks are automatically stopped when html5QrCode.stop() is called
  // No need to manually stop tracks here
  
  // Clear auto-close timer jika ada
  if (autoCloseTimer) {
    clearTimeout(autoCloseTimer);
    autoCloseTimer = null;
  }
  
  // Reset state
  isScanning.value = false;
  cameraReady.value = false;
});

// Helper function untuk extract barcode/patientId dari format QR code
// Handle format: "barcode" atau "patientId|status" (contoh: "P-00001|ALLOWED")
// Returns: { barcode: string, status?: string }
const extractQRData = (qrData: string): { barcode: string; status?: string } => {
  const cleanData = String(qrData || '').trim();
  
  // Check jika format "patientId|status" (untuk testing QR code)
  if (cleanData.includes('|')) {
    const parts = cleanData.split('|');
    const patientId = parts[0]?.trim() || '';
    const status = parts[1]?.trim();
    return {
      barcode: patientId,
      status: status
    };
  }
  
  // Format thermal print: hanya barcode saja
  return {
    barcode: cleanData
  };
};

// Helper function untuk extract kode dan angka dari noAntrian
// Contoh: "UM0014 | Onsite - ..." -> { kode: "UM", angka: "0014" }
// Contoh: "F-RA001 | Onsite - ..." -> { kode: "RA", angka: "001" } (handle "F-" prefix)
const extractKodeAndAngka = (noAntrian: string): { kode: string; angka: string } | null => {
  if (!noAntrian) return null;
  // Handle format "F-RA001" by matching after "F-" prefix if exists
  const match = noAntrian.toUpperCase().match(/^(?:F-)?([A-Z]+)(\d+)/);
  if (match) {
    return { kode: match[1], angka: match[2] };
  }
  return null;
};

// Helper function untuk membandingkan input dengan noAntrian (kode + angka harus match)
// Ini mencegah false positive ketika angka sama tapi kode beda (misalnya UM0014 vs AN0014)
// Handle format "F-RA001" dengan menghapus prefix "F-" untuk comparison
const matchNoAntrian = (input: string, noAntrian: string): boolean => {
  if (!input || !noAntrian) return false;
  
  const cleanInput = String(input).trim().toUpperCase();
  const noAntrianUpper = String(noAntrian).toUpperCase();
  
  // Remove "F-" prefix from both input and noAntrian for comparison
  const cleanInputWithoutPrefix = cleanInput.replace(/^F-/, '');
  const noAntrianWithoutPrefix = noAntrianUpper.replace(/^F-/, '');
  
  // 1. Extract kode + angka dari noAntrian (misalnya "F-RA001 | ..." -> kode: "RA", angka: "001")
  const noAntrianParts = extractKodeAndAngka(noAntrian);
  if (!noAntrianParts) {
    // Jika noAntrian tidak punya format kode+angka, gunakan exact match saja
    // Check both with and without prefix
    return noAntrianUpper === cleanInput || noAntrianWithoutPrefix === cleanInputWithoutPrefix;
  }
  
  // 2. Extract kode + angka dari input (misalnya "F-RA001" atau "RA001" -> kode: "RA", angka: "001")
  const inputParts = extractKodeAndAngka(cleanInput);
  
  // 3. Jika input punya kode + angka, HARUS match kode dan angka
  if (inputParts) {
    // Kode HARUS sama (case-insensitive sudah di-handle oleh extractKodeAndAngka)
    if (inputParts.kode !== noAntrianParts.kode) {
      return false; // Kode berbeda, tidak match
    }
    // Jika kode sama, bandingkan angka
    return inputParts.angka === noAntrianParts.angka || 
           inputParts.angka === noAntrianParts.angka.padStart(inputParts.angka.length, '0') ||
           noAntrianParts.angka === inputParts.angka.padStart(noAntrianParts.angka.length, '0');
  }
  
  // 4. Jika input hanya angka (tidak punya kode), JANGAN match
  // Ini mencegah match "002" dengan "UM1002" atau "AN002" dengan "UM1002"
  const inputAngka = cleanInputWithoutPrefix.replace(/[^0-9]/g, '');
  if (inputAngka && inputAngka === cleanInputWithoutPrefix) {
    // Input hanya angka, tidak match karena tidak ada kode
    return false;
  }
  
  // 5. Exact match untuk kasus lain (jika input mengandung kode tapi tidak ter-extract)
  // Check both with and without prefix
  if (noAntrianUpper === cleanInput || noAntrianWithoutPrefix === cleanInputWithoutPrefix) {
    return true;
  }
  
  // 6. Check jika noAntrian dimulai dengan input + spasi atau pipe (untuk partial match yang aman)
  // Contoh: "F-RA001" match dengan "F-RA001 | ..." atau "RA001" match dengan "F-RA001 | ..."
  // Tapi TIDAK match dengan "UM1002" karena kode berbeda
  if (noAntrianParts && inputParts) {
    // Jika kedua-duanya punya kode+angka, hanya match jika kode sama
    if (inputParts.kode === noAntrianParts.kode) {
      // Check jika noAntrian dimulai dengan format "F-KODEANGKA |" atau "KODEANGKA | ..."
      const noAntrianPrefix = `${noAntrianParts.kode}${noAntrianParts.angka}`;
      const inputPrefix = `${inputParts.kode}${inputParts.angka}`;
      
      // Pastikan input prefix sama dengan noAntrian prefix
      if (inputPrefix === noAntrianPrefix) {
        // Check jika noAntrian dimulai dengan prefix ini (with or without "F-") diikuti spasi, pipe, atau end of string
        if (noAntrianWithoutPrefix.startsWith(noAntrianPrefix)) {
          const nextChar = noAntrianWithoutPrefix[noAntrianPrefix.length];
          if (!nextChar || nextChar === ' ' || nextChar === '|') {
            return true;
          }
        }
        // Also check with "F-" prefix
        if (noAntrianUpper.startsWith(`F-${noAntrianPrefix}`)) {
          const nextChar = noAntrianUpper[`F-${noAntrianPrefix}`.length];
          if (!nextChar || nextChar === ' ' || nextChar === '|') {
            return true;
          }
        }
      }
    }
  }
  
  return false;
};

const onDetect = async (decodedText: string) => {
    // Format QR Code yang didukung:
    // 1. Format thermal print: hanya BARCODE saja (contoh: 250811100163)
    // 2. Format testing: "patientId|status" (contoh: P-00001|ALLOWED)
    // Status akan dicek real-time dari queueStore saat scan QR
    
    console.log('🔍 onDetect called with QR data:', decodedText);
    
    // Extract barcode/patientId dari QR data (handle format testing dengan pipe)
    const qrData = extractQRData(decodedText);
    const searchBarcode = qrData.barcode; // Barcode/patientId untuk dicari di queueStore
    
    // Clean input - remove whitespace and normalize
    const cleanInput = String(searchBarcode).trim();
    const cleanInputUpper = cleanInput.toUpperCase();
    
    console.log('🔍 Extracted barcode/patientId:', searchBarcode);
    console.log('🔍 Cleaned input:', cleanInput);
    console.log('📊 Total patients in store:', queueStore.allPatients.length);
    
    // IMPORTANT: Hanya cari dengan EXACT barcode match untuk menghindari false positive
    // Format barcode: YYMMDD + 5 digit (contoh: 26011500001)
    // Jangan gunakan fallback ke noAntrian atau no karena bisa menyebabkan false positive
    // Contoh masalah: RA020 dengan barcode 26011500001 terdeteksi sebagai RA002 dengan barcode 26011500198
    const foundPatient = queueStore.allPatients.find(p => {
      if (!p) return false;
      
      // Normalize barcode untuk comparison (remove whitespace, case-insensitive)
      const patientBarcode = String(p.barcode || '').trim();
      
      // EXACT barcode match (case-insensitive, whitespace-insensitive)
      // Ini adalah satu-satunya cara yang aman untuk match pasien
      if (patientBarcode === cleanInput || 
          patientBarcode.toLowerCase() === cleanInput.toLowerCase()) {
        console.log('✅ Found by exact barcode match:', patientBarcode, '===', cleanInput);
        return true;
      }
      
      return false;
    });
    
    if (!foundPatient) {
      // Tiket belum di-generate (tidak ada di queueStore)
      console.error('❌ Patient not found. QR data:', decodedText);
      console.error('🔍 Extracted barcode/patientId:', searchBarcode);
      console.error('📋 Available barcodes (first 10):', queueStore.allPatients.slice(0, 10).map(p => ({
        no: p.no,
        barcode: p.barcode,
        noAntrian: p.noAntrian?.split(' |')[0]
      })));
      
      saveToHistory({
        patientId: searchBarcode || decodedText,
        queueNumber: null,
        klinikQueueNumber: null,
        pembayaran: 'N/A',
        status: 'failed',
        checkInTime: new Date().toISOString(),
        checkInDate: new Date().toISOString(),
        method: 'QR Scan'
      });
      
      const errorMsg = `❌ Tiket Belum Di-generate!\n\nQR Code: ${decodedText}\nBarcode/Patient ID: ${searchBarcode}\n\nTiket belum terdaftar di sistem. Pastikan tiket sudah di-generate terlebih dahulu.`;
      infoMessage.value = errorMsg;
      infoAction.value = 'checkin';
      infoDialog.value = true;
      showSnackbar('Error', 'Tiket belum terdaftar di sistem. Pastikan tiket sudah di-generate.', 'error', 'mdi-alert-circle');
      return;
    }
    
    // CATATAN: Validasi processStage dihapus karena terlalu ketat
    // Yang penting adalah status pasien (waiting/pending), bukan processStage
    // Pasien yang sudah dipanggil (status: waiting) harus bisa check-in
    // meskipun processStage-nya bukan 'loket' (bisa 'klinik' atau 'penunjang')
    // Validasi processStage akan dilakukan di checkInPatient() di queueStore
    // yang akan mengecek status pasien secara real-time
    
    // IMPORTANT: Refresh data pasien dari queueStore untuk mendapatkan status REAL-TIME
    // Jangan gunakan foundPatient.status karena mungkin sudah stale
    // Cari ulang pasien dari queueStore dengan EXACT barcode match
    const freshPatient = queueStore.allPatients.find(p => {
      const patientBarcode = String(p.barcode || '').trim();
      // Hanya exact barcode match untuk menghindari false positive
      return patientBarcode === foundPatient.barcode || 
             patientBarcode === searchBarcode ||
             patientBarcode === cleanInput;
    });
    
    if (!freshPatient) {
      console.error('❌ Patient not found in queueStore after refresh');
      saveToHistory({
        patientId: foundPatient.barcode,
        queueNumber: foundPatient.noAntrian,
        klinikQueueNumber: foundPatient.noAntrian?.split(" |")[0] || foundPatient.noAntrian,
        pembayaran: foundPatient.pembayaran || 'N/A',
        status: 'failed',
        checkInTime: new Date().toISOString(),
        checkInDate: new Date().toISOString(),
        method: 'QR Scan',
        klinik: foundPatient.klinik || 'N/A',
        kodeKlinik: foundPatient.kodeKlinik || null
      });
      
      const errorMsg = `❌ Pasien tidak ditemukan di sistem setelah refresh data.`;
      infoMessage.value = errorMsg;
      infoAction.value = 'checkin';
      infoDialog.value = true;
      showSnackbar('Error', 'Pasien tidak ditemukan di sistem', 'error', 'mdi-alert-circle');
      return;
    }
    
    // Gunakan data pasien yang fresh untuk validasi
    const patientStatus = freshPatient.status;
    const klinikQueueNumber = freshPatient.noAntrian?.split(" |")[0] || freshPatient.noAntrian || 'N/A';
    
    console.log('🔍 Fresh patient status:', {
      barcode: freshPatient.barcode,
      noAntrian: freshPatient.noAntrian,
      status: patientStatus,
      processStage: freshPatient.processStage
    });
    
    // Cek apakah sudah check-in (status === 'di-loket') - gunakan data fresh
    if (patientStatus === 'di-loket') {
      // Sudah check-in sebelumnya
      saveToHistory({
        patientId: freshPatient.barcode,
        queueNumber: freshPatient.noAntrian,
        klinikQueueNumber: klinikQueueNumber,
        pembayaran: freshPatient.pembayaran || 'N/A',
        status: 'failed',
        checkInTime: new Date().toISOString(),
        checkInDate: new Date().toISOString(),
        method: 'QR Scan',
        klinik: freshPatient.klinik || 'N/A',
        kodeKlinik: freshPatient.kodeKlinik || null
      });
      
      lastCheckInResult.value = {
        success: false,
        patientId: freshPatient.barcode,
        status: 'ALREADY_CHECKED_IN'
      };
      
      const errorMsg = `⚠️ Sudah Check-in!\n\nNomor Antrean ${klinikQueueNumber} sudah melakukan check-in sebelumnya.`;
      infoMessage.value = errorMsg;
      infoAction.value = 'checkin';
      infoDialog.value = true;
      showSnackbar('Warning', `Tiket ${klinikQueueNumber} sudah check-in sebelumnya`, 'warning', 'mdi-check-circle');
      return;
    }
    
    if (patientStatus === 'menunggu') {
      // Status "menunggu" = belum dipanggil oleh admin loket, belum muncul di AntrianLoket
      // TIDAK BOLEH check-in
      saveToHistory({
        patientId: freshPatient.barcode,
        queueNumber: freshPatient.noAntrian,
        klinikQueueNumber: klinikQueueNumber,
        pembayaran: freshPatient.pembayaran || 'N/A',
        status: 'NOT_ALLOWED',
        checkInTime: new Date().toISOString(),
        checkInDate: new Date().toISOString(),
        method: 'QR Scan',
        klinik: freshPatient.klinik || 'N/A',
        kodeKlinik: freshPatient.kodeKlinik || null
      });
      
      lastCheckInResult.value = {
        success: false,
        patientId: freshPatient.barcode,
        status: 'NOT_ALLOWED'
      };
      
      const errorMsg = `⏳ Belum Diizinkan Check-in\n\nNomor Antrean ${klinikQueueNumber} belum dipanggil oleh admin loket. Mohon menunggu hingga nomor antrean Anda dipanggil dan muncul di layar Antrian Loket.`;
      infoMessage.value = errorMsg;
      infoAction.value = 'kembali';
      infoDialog.value = true;
      showSnackbar('Info', `Tiket ${klinikQueueNumber} belum dipanggil. Mohon menunggu.`, 'info', 'mdi-clock-alert');
      return;
    }
    
    // Status "waiting" atau "pending" → BOLEH check-in
    // Panggil checkInPatient untuk validasi dan update status ke "di-loket"
    // Gunakan barcode pasien yang fresh, bukan decodedText (untuk memastikan format benar)
    const patientBarcodeForCheckIn = freshPatient.barcode || searchBarcode || decodedText;
    console.log('🔍 Calling checkInPatient with barcode (fresh):', patientBarcodeForCheckIn);
    console.log('🔍 Original QR data:', decodedText, '| Extracted barcode:', searchBarcode);
    const checkInResult = queueStore.checkInPatient(patientBarcodeForCheckIn);
    
    if (checkInResult.success && checkInResult.patient) {
      // Check-in berhasil
      const successKlinikQueueNumber = checkInResult.patient.noAntrian?.split(" |")[0] || checkInResult.patient.noAntrian || 'N/A';
      
      lastCheckInResult.value = {
        success: true,
        patientId: checkInResult.patient.barcode,
        status: 'ALLOWED'
      };
      
      saveToHistory({
        patientId: checkInResult.patient.barcode,
        queueNumber: checkInResult.patient.noAntrian,
        klinikQueueNumber: successKlinikQueueNumber,
        pembayaran: checkInResult.patient.pembayaran || 'N/A',
        status: 'success',
        checkInTime: new Date().toISOString(),
        checkInDate: new Date().toISOString(),
        method: 'QR Scan',
        klinik: checkInResult.patient.klinik || 'N/A',
        kodeKlinik: checkInResult.patient.kodeKlinik || null
      });
      
      saveSuccessfulScan(decodedText);
      const successMsg = `✅ Check-in Berhasil!\n\nPasien ${successKlinikQueueNumber} berhasil melakukan check-in dan status berubah menjadi di loket.`;
      infoMessage.value = successMsg;
      infoAction.value = 'checkin';
      infoDialog.value = true;
      showSnackbar('Berhasil', `Check-in berhasil. Tiket ${successKlinikQueueNumber} siap diproses.`, 'success', 'mdi-check-circle');
    } else {
      // Check-in gagal (misalnya validasi di checkInPatient gagal)
      saveToHistory({
        patientId: foundPatient.barcode,
        queueNumber: foundPatient.noAntrian,
        klinikQueueNumber: klinikQueueNumber,
        pembayaran: foundPatient.pembayaran || 'N/A',
        status: 'failed',
        checkInTime: new Date().toISOString(),
        checkInDate: new Date().toISOString(),
        method: 'QR Scan',
        klinik: foundPatient.klinik || 'N/A',
        kodeKlinik: foundPatient.kodeKlinik || null
      });
      
      lastCheckInResult.value = {
        success: false,
        patientId: foundPatient.barcode,
        status: 'FAILED'
      };
      
      const errorMsg = `❌ Check-in Gagal!\n\n${checkInResult.message || 'Status pasien tidak memungkinkan untuk check-in.'}`;
      infoMessage.value = errorMsg;
      infoAction.value = 'checkin';
      infoDialog.value = true;
      showSnackbar('Gagal', checkInResult.message || 'Check-in gagal dilakukan', 'error', 'mdi-close-circle');
    }
};

const handleInfoAction = async () => {
    // Clear auto-close timer jika ada
    if (autoCloseTimer) {
      clearTimeout(autoCloseTimer);
      autoCloseTimer = null;
    }
    
    infoDialog.value = false;
    
    // Scanner tetap berjalan setelah dialog ditutup
    // Ini memungkinkan user untuk segera memproses QR code berikutnya
    // tanpa perlu memulai scanner lagi
};

// Watch infoDialog untuk auto-close setelah 3 detik
watch(infoDialog, (isOpen: boolean) => {
  // Clear timer yang ada jika dialog ditutup
  if (autoCloseTimer) {
    clearTimeout(autoCloseTimer);
    autoCloseTimer = null;
  }
  
  // Jika dialog dibuka, set timer untuk auto-close setelah 3 detik
  if (isOpen) {
    autoCloseTimer = setTimeout(() => {
      infoDialog.value = false;
      autoCloseTimer = null;
    }, 5000); // 5   detik
  }
});

const showSnackbar = (title: string, message: string, color: string, icon: string) => {
    snackbar.value.title = title;
    snackbar.value.message = message;
    snackbar.value.color = color;
    snackbar.value.icon = icon;
    snackbar.value.show = true;
};

const checkInManual = async () => {
  if (!manualInput.value) {
    showSnackbar('Error', 'Mohon isi nomor antrean, barcode, atau ID pasien', 'error', 'mdi-alert');
    return;
  }

  const inputValue = manualInput.value.trim();
  
  // Extract barcode/patientId dari input (handle format testing dengan pipe)
  const qrData = extractQRData(inputValue);
  const searchBarcode = qrData.barcode; // Barcode/patientId untuk dicari di queueStore
  
  const cleanInput = String(searchBarcode).trim();
  const cleanInputUpper = cleanInput.toUpperCase();
  
  console.log('🔍 checkInManual called with:', inputValue);
  console.log('🔍 Extracted barcode/patientId:', searchBarcode);
  console.log('🔍 Cleaned input:', cleanInput);
  console.log('📊 Total patients in store:', queueStore.allPatients.length);
  
  // IMPORTANT: Hanya cari dengan EXACT barcode match untuk menghindari false positive
  // Format barcode: YYMMDD + 5 digit (contoh: 26011500001)
  // Jangan gunakan fallback ke noAntrian atau no karena bisa menyebabkan false positive
  // Contoh masalah: RA020 dengan barcode 26011500001 terdeteksi sebagai RA002 dengan barcode 26011500198
  const foundPatient = queueStore.allPatients.find(p => {
    if (!p) return false;
    
    // Normalize barcode untuk comparison (remove whitespace, case-insensitive)
    const patientBarcode = String(p.barcode || '').trim();
    
    // EXACT barcode match (case-insensitive, whitespace-insensitive)
    // Ini adalah satu-satunya cara yang aman untuk match pasien
    if (patientBarcode === cleanInput || 
        patientBarcode.toLowerCase() === cleanInput.toLowerCase()) {
      console.log('✅ Found by exact barcode match:', patientBarcode, '===', cleanInput);
      return true;
    }
    
    return false;
  });
  
  if (!foundPatient) {
    // Tiket belum di-generate (tidak ada di queueStore)
    console.error('❌ Patient not found. Input:', inputValue);
    console.error('🔍 Extracted barcode/patientId:', searchBarcode);
    console.error('📋 Available barcodes (first 10):', queueStore.allPatients.slice(0, 10).map(p => ({
      no: p.no,
      barcode: p.barcode,
      noAntrian: p.noAntrian?.split(' |')[0]
    })));
    
    saveToHistory({
      patientId: searchBarcode || inputValue,
      queueNumber: null,
      klinikQueueNumber: null,
      pembayaran: 'N/A',
      status: 'failed',
      checkInTime: new Date().toISOString(),
      checkInDate: new Date().toISOString(),
      method: 'Manual',
      klinik: 'N/A',
      kodeKlinik: null
    });
    
    const errorMsg = `❌ Tiket Belum Di-generate!\n\nInput: ${inputValue}\nBarcode/Patient ID: ${searchBarcode}\n\nTiket belum terdaftar di sistem. Pastikan tiket sudah di-generate terlebih dahulu.`;
    infoMessage.value = errorMsg;
    infoAction.value = 'checkin';
    infoDialog.value = true;
    showSnackbar('Error', 'Tiket belum terdaftar di sistem. Pastikan tiket sudah di-generate.', 'error', 'mdi-alert-circle');
    return;
  }
  
  // CATATAN: Validasi processStage dihapus karena terlalu ketat
  // Yang penting adalah status pasien (waiting/pending), bukan processStage
  // Pasien yang sudah dipanggil (status: waiting) harus bisa check-in
  // meskipun processStage-nya bukan 'loket' (bisa 'klinik' atau 'penunjang')
  // Validasi processStage akan dilakukan di checkInPatient() di queueStore
  // yang akan mengecek status pasien secara real-time
  
  // IMPORTANT: Refresh data pasien dari queueStore untuk mendapatkan status REAL-TIME
  // Jangan gunakan foundPatient.status karena mungkin sudah stale
  // Cari ulang pasien dari queueStore dengan EXACT barcode match
  const freshPatient = queueStore.allPatients.find(p => {
    const patientBarcode = String(p.barcode || '').trim();
    // Hanya exact barcode match untuk menghindari false positive
    return patientBarcode === foundPatient.barcode || 
           patientBarcode === searchBarcode ||
           patientBarcode === cleanInput;
  });
  
  if (!freshPatient) {
    console.error('❌ Patient not found in queueStore after refresh');
    saveToHistory({
      patientId: foundPatient.barcode,
      queueNumber: foundPatient.noAntrian,
      klinikQueueNumber: foundPatient.noAntrian?.split(" |")[0] || foundPatient.noAntrian,
      pembayaran: foundPatient.pembayaran || 'N/A',
      status: 'failed',
      checkInTime: new Date().toISOString(),
      checkInDate: new Date().toISOString(),
      method: 'Manual',
      klinik: foundPatient.klinik || 'N/A',
      kodeKlinik: foundPatient.kodeKlinik || null
    });
    
    const errorMsg = `❌ Pasien tidak ditemukan di sistem setelah refresh data.`;
    infoMessage.value = errorMsg;
    infoAction.value = 'checkin';
    infoDialog.value = true;
    showSnackbar('Error', 'Pasien tidak ditemukan di sistem', 'error', 'mdi-alert-circle');
    return;
  }
  
  // Gunakan data pasien yang fresh untuk validasi
  const patientStatus = freshPatient.status;
  const klinikQueueNumber = freshPatient.noAntrian?.split(" |")[0] || freshPatient.noAntrian || 'N/A';
  
  console.log('🔍 Fresh patient status:', {
    barcode: freshPatient.barcode,
    noAntrian: freshPatient.noAntrian,
    status: patientStatus,
    processStage: freshPatient.processStage
  });
  
  // Cek apakah sudah check-in (status === 'di-loket') - gunakan data fresh
  if (patientStatus === 'di-loket') {
    // Sudah check-in sebelumnya
    saveToHistory({
      patientId: freshPatient.barcode,
      queueNumber: freshPatient.noAntrian,
      klinikQueueNumber: klinikQueueNumber,
      pembayaran: freshPatient.pembayaran || 'N/A',
      status: 'failed',
      checkInTime: new Date().toISOString(),
      checkInDate: new Date().toISOString(),
      method: 'Manual',
      klinik: freshPatient.klinik || 'N/A',
      kodeKlinik: freshPatient.kodeKlinik || null
    });
    
    lastCheckInResult.value = {
      success: false,
      patientId: freshPatient.barcode,
      status: 'ALREADY_CHECKED_IN'
    };
    
    const errorMsg = `⚠️ Sudah Check-in!\n\nNomor Antrean ${klinikQueueNumber} sudah melakukan check-in sebelumnya.`;
    infoMessage.value = errorMsg;
    infoAction.value = 'checkin';
    infoDialog.value = true;
    showSnackbar('Warning', `Tiket ${klinikQueueNumber} sudah check-in sebelumnya`, 'warning', 'mdi-check-circle');
    return;
  }
  
  if (patientStatus === 'menunggu') {
    // Status "menunggu" = belum dipanggil oleh admin loket, belum muncul di AntrianLoket
    // TIDAK BOLEH check-in
    saveToHistory({
      patientId: freshPatient.barcode,
      queueNumber: freshPatient.noAntrian,
      klinikQueueNumber: klinikQueueNumber,
      pembayaran: freshPatient.pembayaran || 'N/A',
      status: 'NOT_ALLOWED',
      checkInTime: new Date().toISOString(),
      checkInDate: new Date().toISOString(),
      method: 'Manual',
      klinik: freshPatient.klinik || 'N/A',
      kodeKlinik: freshPatient.kodeKlinik || null
    });
    
    lastCheckInResult.value = {
      success: false,
      patientId: freshPatient.barcode,
      status: 'NOT_ALLOWED'
    };
    
    const errorMsg = `⏳ Belum Diizinkan Check-in\n\nNomor Antrean ${klinikQueueNumber} belum dipanggil oleh admin loket. Mohon menunggu hingga nomor antrean Anda dipanggil dan muncul di layar Antrian Loket.`;
    infoMessage.value = errorMsg;
    infoAction.value = 'kembali';
    infoDialog.value = true;
    showSnackbar('Info', `Tiket ${klinikQueueNumber} belum dipanggil. Mohon menunggu.`, 'info', 'mdi-clock-alert');
    return;
  }
  
  // Status "waiting" atau "pending" → BOLEH check-in
  // Panggil checkInPatient untuk validasi dan update status ke "di-loket"
  // Gunakan barcode pasien yang fresh, bukan inputValue (untuk memastikan format benar)
  const patientBarcodeForCheckIn = freshPatient.barcode || searchBarcode || inputValue;
  console.log('🔍 Calling checkInPatient with barcode (fresh):', patientBarcodeForCheckIn);
  console.log('🔍 Original input:', inputValue, '| Extracted barcode:', searchBarcode);
  const checkInResult = queueStore.checkInPatient(patientBarcodeForCheckIn);
  
  if (checkInResult.success && checkInResult.patient) {
    // Check-in berhasil
    const successKlinikQueueNumber = checkInResult.patient.noAntrian?.split(" |")[0] || checkInResult.patient.noAntrian || 'N/A';
    
    lastCheckInResult.value = {
      success: true,
      patientId: checkInResult.patient.barcode,
      status: 'ALLOWED'
    };
    
    saveToHistory({
      patientId: checkInResult.patient.barcode,
      queueNumber: checkInResult.patient.noAntrian,
      klinikQueueNumber: successKlinikQueueNumber,
      pembayaran: checkInResult.patient.pembayaran || 'N/A',
      status: 'success',
      checkInTime: new Date().toISOString(),
      checkInDate: new Date().toISOString(),
      method: 'Manual',
      klinik: checkInResult.patient.klinik || 'N/A',
      kodeKlinik: checkInResult.patient.kodeKlinik || null
    });
    
    const successMsg = `✅ Check-in Berhasil!\n\nPasien ${successKlinikQueueNumber} berhasil melakukan check-in dan status berubah menjadi di loket.`;
    infoMessage.value = successMsg;
    infoAction.value = 'checkin';
    infoDialog.value = true;
    showSnackbar('Berhasil', `Check-in manual berhasil. Tiket ${successKlinikQueueNumber} siap diproses.`, 'success', 'mdi-check-circle');
    
    manualInput.value = '';
    if (manualForm.value) {
      (manualForm.value as any).reset();
    }
  } else {
    // Check-in gagal (misalnya validasi di checkInPatient gagal)
    saveToHistory({
      patientId: foundPatient.barcode,
      queueNumber: foundPatient.noAntrian,
      klinikQueueNumber: klinikQueueNumber,
      pembayaran: foundPatient.pembayaran || 'N/A',
      status: 'failed',
      checkInTime: new Date().toISOString(),
      checkInDate: new Date().toISOString(),
      method: 'Manual',
      klinik: foundPatient.klinik || 'N/A',
      kodeKlinik: foundPatient.kodeKlinik || null
    });
    
    lastCheckInResult.value = {
      success: false,
      patientId: foundPatient.barcode,
      status: 'FAILED'
    };
    
    const errorMsg = `❌ Check-in Gagal!\n\n${checkInResult.message || 'Status pasien tidak memungkinkan untuk check-in.'}`;
    infoMessage.value = errorMsg;
    infoAction.value = 'checkin';
    infoDialog.value = true;
    showSnackbar('Gagal', checkInResult.message || 'Check-in manual gagal dilakukan', 'error', 'mdi-close-circle');
  }
};

// Quick generate QR for testing
const generateQuickQR = (status: string) => {
  // Check and reset daily first (before generating)
  checkAndResetDaily();
  
  // Auto-generate sequential patient ID
  generatePatientId.value = generateSequentialPatientId();
  generateStatus.value = status;
  // Use first klinik if none selected
  if (!selectedKlinik.value && klinikOptions.value.length > 0) {
    selectedKlinik.value = klinikOptions.value[0].value;
  }
  generateQRCode();
};

// Generate QR Code function
const generateQRCode = async () => {
  // Check and reset daily first (before generating)
  checkAndResetDaily();
  
  // Auto-generate patient ID if empty
  if (!generatePatientId.value) {
    generatePatientId.value = generateSequentialPatientId();
  }
  
  if (!selectedKlinik.value) {
    showSnackbar('Error', 'Mohon pilih Klinik/Poli', 'error', 'mdi-alert');
    return;
  }

  generatedQRData.value = `${generatePatientId.value}|${generateStatus.value}`;
  
  await nextTick();
  
  // Clear previous QR code
  const qrContainer = document.getElementById('qrcode');
  if (qrContainer) {
    qrContainer.innerHTML = '';
    
    try {
      // Use qrcode package that's already installed
      const QRCode = (await import('qrcode')).default;
      
      // Create QR code as data URL
      // Konsisten dengan useThermalPrint.ts: version 3, error correction H, margin 0.5
      const qrDataUrl = await QRCode.toDataURL(generatedQRData.value, {
        errorCorrectionLevel: 'H', // High error correction for better scanning
        type: 'image/png',
        quality: 1,
        margin: 0.5, // Reduced margin untuk memperkecil Positioning Detection Markers
        width: 300, // Lebih besar untuk testing/preview (thermal print menggunakan 100)
        version: 3, // QR Code version 3 (konsisten dengan useThermalPrint.ts)
        color: {
          dark: '#000000', // Black
          light: '#FFFFFF' // White
        }
      });
      
      // Create img element and append to container
      const img = document.createElement('img');
      img.src = qrDataUrl;
      img.alt = 'QR Code';
      img.style.width = '100%';
      img.style.maxWidth = '300px';
      img.style.height = 'auto';
      img.style.display = 'block';
      img.style.margin = '0 auto';
      qrContainer.appendChild(img);
      
      console.log('QR Code created successfully:', generatedQRData.value);
      showSnackbar('Berhasil!', 'QR Code berhasil di-generate. Silakan scan untuk testing', 'success', 'mdi-check-circle');
    } catch (error) {
      console.error('Error creating QR code:', error);
      showSnackbar('Error', 'Gagal membuat QR Code. Silakan coba lagi', 'error', 'mdi-alert');
    }
  } else {
    showSnackbar('Error', 'Container QR Code tidak ditemukan', 'error', 'mdi-alert');
  }
};

const downloadQR = async () => {
  const img = document.querySelector('#qrcode img') as HTMLImageElement;
  if (img && img.src) {
    try {
      // Convert img src (data URL) to blob
      const response = await fetch(img.src);
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      const klinikCode = selectedKlinik.value || 'UNKNOWN';
      const fileName = `QR-Test-${klinikCode}-${generatePatientId.value}-${generateStatus.value}-${Date.now()}.png`;
      link.download = fileName;
      link.href = url;
      link.style.display = 'none';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
      showSnackbar('Berhasil!', `QR Code berhasil didownload: ${fileName}`, 'success', 'mdi-download');
    } catch (error) {
      console.error('Download error:', error);
      // Fallback: use img src directly
      const link = document.createElement('a');
      const klinikCode = selectedKlinik.value || 'UNKNOWN';
      link.download = `QR-Test-${klinikCode}-${generatePatientId.value}-${generateStatus.value}.png`;
      link.href = img.src;
      link.click();
      showSnackbar('Berhasil!', 'QR Code berhasil didownload', 'success', 'mdi-download');
    }
  } else {
    showSnackbar('Error', 'QR Code belum di-generate. Silakan generate terlebih dahulu', 'error', 'mdi-alert');
  }
};

const copyQRToClipboard = async () => {
  const img = document.querySelector('#qrcode img') as HTMLImageElement;
  if (img && img.src) {
    try {
      // Convert img src to blob
      const response = await fetch(img.src);
      const blob = await response.blob();
      
      try {
        await navigator.clipboard.write([
          new ClipboardItem({
            'image/png': blob
          })
        ]);
        showSnackbar('Berhasil!', 'QR Code berhasil disalin ke clipboard', 'success', 'mdi-content-copy');
      } catch (err: any) {
        console.error('Clipboard error:', err);
        // Fallback: download instead
        showSnackbar('Info', 'Copy ke clipboard tidak didukung. Gunakan tombol Download.', 'info', 'mdi-information');
      }
    } catch (error) {
      console.error('Copy error:', error);
      showSnackbar('Error', 'Gagal menyalin QR Code', 'error', 'mdi-alert');
    }
  } else {
    showSnackbar('Error', 'QR Code belum di-generate. Silakan generate terlebih dahulu', 'error', 'mdi-alert');
  }
};

const shareQR = async () => {
  const img = document.querySelector('#qrcode img') as HTMLImageElement;
  if (img && img.src) {
    try {
      // Convert img src to blob
      const response = await fetch(img.src);
      const blob = await response.blob();
      const klinikCode = selectedKlinik.value || 'UNKNOWN';
      const file = new File([blob], `QR-Test-${klinikCode}-${generatePatientId.value}-${generateStatus.value}.png`, { type: 'image/png' });
      
      if (navigator.share && navigator.canShare({ files: [file] })) {
        try {
          await navigator.share({
            files: [file],
            title: 'QR Code Check-in Test',
            text: `QR Code untuk testing: ${generatedQRData.value}`
          });
          showSnackbar('Berhasil!', 'QR Code berhasil dibagikan', 'success', 'mdi-share');
        } catch (err: any) {
          if (err.name !== 'AbortError') {
            // Fallback to copy or download
            copyQRToClipboard();
          }
        }
      } else {
        // Fallback: try copy to clipboard
        copyQRToClipboard();
      }
    } catch (error) {
      console.error('Share error:', error);
      showSnackbar('Error', 'Gagal membagikan QR Code', 'error', 'mdi-alert');
    }
  } else {
    showSnackbar('Error', 'QR Code belum di-generate. Silakan generate terlebih dahulu', 'error', 'mdi-alert');
  }
};

// History Functions
const loadHistory = () => {
  if (typeof window !== 'undefined') {
    const stored = localStorage.getItem(HISTORY_STORAGE_KEY);
    if (stored) {
      try {
        checkInHistory.value = JSON.parse(stored);
      } catch (e) {
        console.error('Error loading history:', e);
        checkInHistory.value = [];
      }
    }
  }
};

const saveToHistory = (item: {
  patientId: string;
  queueNumber?: string;
  klinikQueueNumber?: string;
  pembayaran?: string;
  status: string;
  checkInTime: string;
  checkInDate: string;
  method: string;
  kodeKlinik?: string;
  klinik?: string;
}) => {
  // JANGAN generate nomor antrean baru - selalu gunakan nomor dari pasien yang ditemukan
  // Jika queueNumber tidak ada, gunakan klinikQueueNumber atau patientId sebagai fallback
  // Tapi jangan generate nomor baru karena itu akan mengubah nomor antrean yang sebenarnya
  let queueNumber = item.queueNumber;
  if (!queueNumber && item.klinikQueueNumber) {
    // Jika queueNumber tidak ada tapi ada klinikQueueNumber, gunakan itu
    queueNumber = item.klinikQueueNumber;
  } else if (!queueNumber && item.patientId) {
    // Jika masih tidak ada, gunakan patientId (barcode) sebagai fallback
    queueNumber = item.patientId;
  }
  // Jangan generate nomor baru - biarkan null/undefined jika memang tidak ada
  // Ini memastikan nomor antrean yang ditampilkan sesuai dengan yang ada di tiket
  
  const historyItem = {
    ...item,
    queueNumber: queueNumber || item.klinikQueueNumber || item.patientId || null,
  };
  
  // Jika status baru adalah "success" atau "ALLOWED", cek apakah ada history lama dengan patientId yang sama
  // yang masih berstatus "NOT_ALLOWED", "pending", atau "failed"
  // Jika ada, hapus entry lama tersebut agar tidak terhitung sebagai "menunggu"
  if (item.status === 'success' || item.status === 'ALLOWED') {
    // Cari dan hapus entry lama dengan patientId yang sama yang masih menunggu
    const waitingStatuses = ['NOT_ALLOWED', 'pending', 'failed'];
    const indexToRemove = checkInHistory.value.findIndex(
      (history: {
        patientId: string;
        queueNumber?: string;
        klinikQueueNumber?: string;
        pembayaran?: string;
        status: string;
        checkInTime: string;
        checkInDate: string;
        method: string;
        kodeKlinik?: string;
      }) => 
        history.patientId === item.patientId && 
        waitingStatuses.includes(history.status)
    );
    
    if (indexToRemove !== -1) {
      // Hapus entry lama yang masih menunggu
      checkInHistory.value.splice(indexToRemove, 1);
      console.log(`✅ Menghapus entry lama untuk pasien ${item.patientId} yang masih menunggu`);
    }
  }
  
  checkInHistory.value.unshift(historyItem);
  
  // Simpan maksimal 100 item
  if (checkInHistory.value.length > 100) {
    checkInHistory.value = checkInHistory.value.slice(0, 100);
  }
  
  if (typeof window !== 'undefined') {
    localStorage.setItem(HISTORY_STORAGE_KEY, JSON.stringify(checkInHistory.value));
  }
};

const deleteHistoryItem = (index: number) => {
  // Index dari paginatedHistory, perlu dikonversi ke index di checkInHistory
  const paginatedItem = paginatedHistory.value[index];
  if (!paginatedItem) return;
  
  // Cari index sebenarnya di checkInHistory
  const actualIndex = checkInHistory.value.findIndex(h => 
    h.patientId === paginatedItem.patientId && 
    h.checkInTime === paginatedItem.checkInTime &&
    h.method === paginatedItem.method
  );
  
  if (actualIndex !== -1) {
    checkInHistory.value.splice(actualIndex, 1);
    if (typeof window !== 'undefined') {
      localStorage.setItem(HISTORY_STORAGE_KEY, JSON.stringify(checkInHistory.value));
    }
    showSnackbar('Berhasil', 'Riwayat berhasil dihapus', 'success', 'mdi-check');
    
    // Reset ke halaman sebelumnya jika halaman saat ini kosong
    if (paginatedHistory.value.length === 0 && historyPage.value > 1) {
      historyPage.value = Math.max(1, historyPage.value - 1);
    }
  }
};

const clearHistory = () => {
  checkInHistory.value = [];
  if (typeof window !== 'undefined') {
    localStorage.removeItem(HISTORY_STORAGE_KEY);
  }
  showSnackbar('Berhasil', 'Semua riwayat berhasil dihapus', 'success', 'mdi-check');
};

const openHistoryDialog = () => {
  // Pastikan history dimuat ulang saat dialog dibuka
  loadHistory();
  // Reset filter dan pagination saat membuka dialog
  historySearch.value = '';
  historyStatusFilter.value = '';
  historyPage.value = 1;
  historyDialog.value = true;
};

const openQRHistoryDialog = () => {
  loadScannedQRHistory();
  qrHistoryDialog.value = true;
};

const loadScannedQRHistory = () => {
  if (typeof window !== 'undefined') {
    const stored = localStorage.getItem('scanned_qr_data');
    if (stored) {
      try {
        scannedQRHistory.value = JSON.parse(stored);
      } catch (e) {
        console.error('Error loading QR history:', e);
        scannedQRHistory.value = [];
      }
    } else {
      scannedQRHistory.value = [];
    }
  }
};

const clearQRHistory = () => {
  scannedQRHistory.value = [];
  if (typeof window !== 'undefined') {
    localStorage.removeItem('scanned_qr_data');
  }
  showSnackbar('Berhasil', 'Semua riwayat QR scan berhasil dihapus', 'success', 'mdi-check');
};

const deleteQRHistoryItem = (index: number) => {
  scannedQRHistory.value.splice(index, 1);
  if (typeof window !== 'undefined') {
    localStorage.setItem('scanned_qr_data', JSON.stringify(scannedQRHistory.value));
  }
  showSnackbar('Berhasil', 'Riwayat QR scan berhasil dihapus', 'success', 'mdi-check');
};

const useQRData = (qrData: string) => {
  qrHistoryDialog.value = false;
  scannedData.value = qrData;
  onDetect(qrData);
};

const filteredQRHistory = computed(() => {
  let filtered = [...scannedQRHistory.value];
  
  // Filter by search
  if (historySearch.value) {
    const search = historySearch.value.toLowerCase();
    filtered = filtered.filter(item => 
      item.data.toLowerCase().includes(search)
    );
  }
  
  return filtered;
});

const filteredHistory = computed(() => {
  // Pastikan history sudah dimuat
  if (checkInHistory.value.length === 0 && typeof window !== 'undefined') {
    loadHistory();
  }
  
  let filtered = [...checkInHistory.value];
  
  // Sort by checkInTime (terbaru di atas)
  filtered.sort((a, b) => {
    const timeA = new Date(a.checkInTime || a.checkInDate || 0).getTime();
    const timeB = new Date(b.checkInTime || b.checkInDate || 0).getTime();
    return timeB - timeA; // Descending order (newest first)
  });
  
  // Filter by search
  if (historySearch.value) {
    const search = historySearch.value.toLowerCase();
    filtered = filtered.filter(item => 
      item.patientId.toLowerCase().includes(search) ||
      (item.queueNumber && item.queueNumber.toLowerCase().includes(search)) ||
      (item.klinikQueueNumber && item.klinikQueueNumber.toLowerCase().includes(search)) ||
      (item.method && item.method.toLowerCase().includes(search)) ||
      (item.klinik && item.klinik.toLowerCase().includes(search))
    );
  }
  
  // Filter by status
  if (historyStatusFilter.value) {
    filtered = filtered.filter(item => {
      if (historyStatusFilter.value === 'success') {
        return item.status === 'ALLOWED' || item.status === 'success';
      } else if (historyStatusFilter.value === 'failed') {
        return item.status === 'NOT_ALLOWED' || item.status === 'failed';
      }
      return true;
    });
  }
  
  return filtered;
});

// Paginated history
const paginatedHistory = computed(() => {
  const start = (historyPage.value - 1) * historyItemsPerPage.value;
  const end = start + historyItemsPerPage.value;
  return filteredHistory.value.slice(start, end);
});

// Total pages untuk pagination
const totalHistoryPages = computed(() => {
  return Math.ceil(filteredHistory.value.length / historyItemsPerPage.value);
});

// Reset page saat filter berubah
watch([historySearch, historyStatusFilter], () => {
  historyPage.value = 1;
});

// Recent history untuk ditampilkan di sidebar
// Hanya menampilkan riwayat dari hari ini setelah reset (setelah jam 10 malam)
const recentHistory = computed(() => {
  const todayAfterReset = getTodayAfterReset();
  
  // Filter hanya riwayat dari hari ini setelah reset
  const todayHistory = checkInHistory.value.filter(item => {
    const itemDate = new Date(item.checkInDate || item.checkInTime);
    const itemDateStr = itemDate.toISOString().split('T')[0];
    return itemDateStr === todayAfterReset;
  });
  
  // Sort by checkInTime (terbaru di atas)
  return todayHistory.sort((a, b) => {
    const timeA = new Date(a.checkInTime || a.checkInDate || 0).getTime();
    const timeB = new Date(b.checkInTime || b.checkInDate || 0).getTime();
    return timeB - timeA; // Descending order (newest first)
  });
});

// Pagination untuk recent history
const recentHistoryPage = ref(1);
const recentHistoryItemsPerPage = ref(5);

// Paginated recent history
const paginatedRecentHistory = computed(() => {
  const start = (recentHistoryPage.value - 1) * recentHistoryItemsPerPage.value;
  const end = start + recentHistoryItemsPerPage.value;
  return recentHistory.value.slice(start, end);
});

// Total pages untuk recent history pagination
const totalRecentHistoryPages = computed(() => {
  return Math.ceil(recentHistory.value.length / recentHistoryItemsPerPage.value);
});

const getStatusColor = (status: string) => {
  if (status === 'ALLOWED' || status === 'success') return 'success';
  if (status === 'NOT_ALLOWED') return 'warning';
  if (status === 'failed') return 'error';
  return 'warning';
};

const getStatusIcon = (status: string) => {
  if (status === 'ALLOWED' || status === 'success') return 'mdi-check-circle';
  if (status === 'NOT_ALLOWED') return 'mdi-clock-alert';
  if (status === 'failed') return 'mdi-close-circle';
  return 'mdi-clock-alert';
};

const getStatusText = (status: string) => {
  if (status === 'ALLOWED' || status === 'success') return 'Berhasil';
  if (status === 'NOT_ALLOWED') return 'Menunggu';
  if (status === 'failed') return 'Gagal';
  return 'Pending';
};

const getStatusClass = (status: string) => {
  if (status === 'ALLOWED' || status === 'success') return 'history-success';
  if (status === 'NOT_ALLOWED') return 'history-pending';
  if (status === 'failed') return 'history-failed';
  return 'history-pending';
};

const formatDateTime = (dateString: string) => {
  const date = new Date(dateString);
  // Format jam dengan titik dua (HH:MM:SS)
  const timeString = date.toLocaleTimeString('id-ID', { 
    hour: '2-digit', 
    minute: '2-digit',
    second: '2-digit'
  });
  return timeString.replace(/\./g, ':');
};

const formatTime = (dateString: string) => {
  const date = new Date(dateString);
  // Format: HH:MM:SS (menggunakan titik dua)
  const timeString = date.toLocaleTimeString('id-ID', { 
    hour: '2-digit', 
    minute: '2-digit',
    second: '2-digit'
  });
  return timeString.replace(/\./g, ':');
};

const getCurrentTime = () => {
  // Format jam dengan titik dua (HH:MM:SS)
  const timeString = new Date().toLocaleTimeString('id-ID', { 
    hour: '2-digit', 
    minute: '2-digit',
    second: '2-digit'
  });
  return timeString.replace(/\./g, ':');
};

const formatDate = (dateString: string) => {
  const date = new Date(dateString);
  return date.toLocaleDateString('id-ID', {
    day: '2-digit',
    month: 'short',
    year: 'numeric'
  });
};

// Statistics computed properties
const statsToday = computed(() => {
  const todayAfterReset = getTodayAfterReset();
  
  return checkInHistory.value.filter(item => {
    const itemDate = new Date(item.checkInDate || item.checkInTime);
    const itemDateStr = itemDate.toISOString().split('T')[0];
    
    // Only count items from today (after reset time consideration)
    if (itemDateStr !== todayAfterReset) return false;
    
    // Only count successful check-ins
    return item.status === 'success' || item.status === 'ALLOWED';
  }).length;
});

// Get today's date after reset (after 10 PM, consider next day)
const getTodayAfterReset = (): string => {
  const now = new Date();
  const currentHour = now.getHours();
  
  // If it's 10 PM or later, consider it as next day for stats
  if (currentHour >= RESET_HOUR) {
    const tomorrow = new Date(now);
    tomorrow.setDate(tomorrow.getDate() + 1);
    return tomorrow.toISOString().split('T')[0];
  }
  
  return now.toISOString().split('T')[0];
};

const statsCompleted = computed(() => {
  const todayAfterReset = getTodayAfterReset();
  
  return checkInHistory.value.filter(item => {
    const itemDate = new Date(item.checkInDate || item.checkInTime);
    const itemDateStr = itemDate.toISOString().split('T')[0];
    
    // Only count items from today (after reset time consideration)
    if (itemDateStr !== todayAfterReset) return false;
    
    return item.status === 'success' || item.status === 'ALLOWED';
  }).length;
});

const statsWaiting = computed(() => {
  // Ambil data menunggu dari queueStore untuk stage 'loket'
  // Menghitung pasien dengan status 'menunggu' (belum dipanggil) atau 'waiting' (sudah dipanggil tapi belum check-in)
  // Di halaman CheckInPasien, kita menghitung total yang masih menunggu check-in (belum + sudah dipanggil)
  try {
    const loketPatients = queueStore.getPatientsByStage('loket');
    const menungguPatients = loketPatients.value.menunggu || [];
    const waitingPatients = loketPatients.value.waiting || [];
    
    // Total pasien yang masih menunggu check-in (belum dipanggil + sudah dipanggil tapi belum check-in)
    return menungguPatients.length + waitingPatients.length;
  } catch (error) {
    console.error('Error calculating statsWaiting:', error);
    return 0;
  }
});

// Load history on mount
if (typeof window !== 'undefined') {
  loadHistory();
  loadScannedQRHistory();
  loadSuccessfulScans();
}
</script>

<style scoped lang="scss">
@use '@/assets/scss/colors' as *;

/* Modern Minimalist Background */
.bg-modern {
  background: $neutral-100;
  min-height: 100vh;
  max-height: 100vh;
  position: relative;
  overflow: hidden;
}

.no-scroll-container {
  height: 100vh;
  max-height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
}

.no-scroll-container::-webkit-scrollbar {
  width: 4px;
}

.no-scroll-container::-webkit-scrollbar-track {
  background: transparent;
}

.no-scroll-container::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 2px;
}

.no-overflow {
  overflow: hidden !important;
  height: 100vh;
  max-height: 100vh;
}

.bg-modern::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: 
    radial-gradient(circle at 20% 50%, rgba(21, 101, 192, 0.05) 0%, transparent 50%),
    radial-gradient(circle at 80% 80%, rgba(21, 101, 192, 0.05) 0%, transparent 50%);
  pointer-events: none;
  z-index: 0;
}

/* Main Card dengan Glassmorphism */
.main-card {
  background: rgba($neutral-100, 0.95) !important;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 24px !important;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1) !important;
  overflow: hidden;
  position: relative;
  z-index: 1;
}

/* Header Modern Minimalis */
.header-modern {
  background: linear-gradient(135deg, $primary-600 0%, $primary-700 100%);
  padding: 8px 20px 6px;
  position: relative;
  overflow: hidden;
}

.header-modern::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
  pointer-events: none;
}

.header-content {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 0;
}

.icon-circle {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.header-text {
  text-align: left;
}

.title-modern {
  font-size: 18px;
  font-weight: 700;
  color: $neutral-100;
  margin: 0;
  letter-spacing: -0.5px;
}

.subtitle-modern {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.85);
  margin: 1px 0 0;
  font-weight: 400;
}

/* Tabs Modern */
.tabs-modern {
  position: relative;
  z-index: 1;
}

.tabs-modern :deep(.v-tab) {
  text-transform: none;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.2px;
  color: rgba(255, 255, 255, 0.8);
  min-width: auto;
  padding: 0 16px;
  transition: all 0.3s ease;
}

.tabs-modern :deep(.v-tab--selected) {
  color: $secondary-500 !important;
  background: rgba($secondary-500, 0.2);
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

.tabs-modern :deep(.v-tab--selected .v-icon) {
  color: $secondary-500 !important;
}

.tabs-modern :deep(.v-tab--selected span) {
  color: $secondary-500 !important;
}

.tabs-modern :deep(.v-slider) {
  display: none;
}

.tab-modern {
  display: flex;
  align-items: center;
  gap: 6px;
}

.tab-modern .v-icon {
  font-size: 18px !important;
}

/* Content Area */
.content-modern {
  background: $neutral-100;
  max-height: calc(100vh - 200px);
  overflow-y: auto;
}

.content-modern::-webkit-scrollbar {
  width: 4px;
}

.content-modern::-webkit-scrollbar-track {
  background: transparent;
}

.content-modern::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 2px;
}

.tab-content {
  animation: fadeIn 0.4s ease-out;
  height: 100%;
}

/* Two-column layout styling */
.checkin-wrapper {
  width: 100%;
  min-height: 100%;
}

.checkin-layout {
  gap: 0 !important;
  display: flex !important;
  flex-wrap: wrap !important;
  margin: 0 !important;
  width: 100% !important;
}

.checkin-left-col {
  padding-right: 16px !important;
  border-right: 1px solid rgba(0, 0, 0, 0.08) !important;
  display: flex !important;
  flex-direction: column !important;
  flex: 0 0 50% !important;
  max-width: 50% !important;
}

.checkin-right-col {
  padding-left: 16px !important;
  display: flex !important;
  flex-direction: column !important;
  flex: 0 0 50% !important;
  max-width: 50% !important;
}

@media (max-width: 959px) {
  .checkin-layout {
    flex-direction: column !important;
  }
  
  .checkin-left-col {
    border-right: none !important;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08) !important;
    padding-right: 0 !important;
    padding-bottom: 24px !important;
    margin-bottom: 24px !important;
    flex: 0 0 100% !important;
    width: 100% !important;
    max-width: 100% !important;
  }
  
  .checkin-right-col {
    padding-left: 0 !important;
    padding-top: 24px !important;
    flex: 0 0 100% !important;
    width: 100% !important;
    max-width: 100% !important;
  }
}

/* History Section Styling */
.history-section {
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  padding-top: 16px;
}

.recent-history-list {
  max-height: 400px;
  overflow-y: auto;
  padding-right: 4px;
}

.recent-history-list::-webkit-scrollbar {
  width: 4px;
}

.recent-history-list::-webkit-scrollbar-track {
  background: transparent;
}

.recent-history-list::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 2px;
}

.history-item-content {
  width: 100%;
  position: relative;
  padding-left: 0;
}

.history-item-compact :deep(.v-card-text) {
  padding: 12px 16px !important;
  border-left: none !important;
  position: relative;
  z-index: 0;
}

.history-item-compact {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  background: $neutral-100 !important;
  border: 1px solid $neutral-400 !important;
  border-radius: 8px !important;
  border-left: 3px solid transparent !important;
}

.history-item-compact::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: transparent;
  z-index: 1;
  border-radius: 8px 0 0 8px;
}

.history-item-compact :deep(.v-card__underlay) {
  display: none;
}

.history-item-compact :deep(.v-card__border) {
  border: none !important;
}

.history-item-compact:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
  border-color: $neutral-500 !important;
}

.history-item-compact.history-success::before {
  background: $success-500 !important;
}

.history-item-compact.history-success {
  background: rgba($success-100, 0.5) !important;
  border-left-color: $success-500 !important;
}

.history-item-compact.history-success :deep(.v-card-text) {
  background: transparent !important;
}

.history-item-compact.history-failed::before {
  background: $danger-500 !important;
}

.history-item-compact.history-failed {
  background: rgba($danger-100, 0.5) !important;
  border-left-color: $danger-500 !important;
}

.history-item-compact.history-failed :deep(.v-card-text) {
  background: transparent !important;
}

.history-item-compact.history-pending::before {
  background: $secondary-500 !important;
}

.history-item-compact.history-pending {
  background: rgba($secondary-100, 0.5) !important;
  border-left-color: $secondary-500 !important;
}

.history-item-compact.history-pending :deep(.v-card-text) {
  background: transparent !important;
}

/* Status Badge */
.history-status-badge {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.history-status-badge.status-success {
  background: rgba($success-500, 0.15);
  color: $success-600;
}

.history-status-badge.status-error,
.history-status-badge.status-warning {
  background: rgba($danger-500, 0.15);
  color: $danger-600;
}

.history-status-badge.status-warning {
  background: rgba($secondary-500, 0.15);
  color: $secondary-600;
}

.history-status-text {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  margin-bottom: 0;
}

.history-status-text.text-success {
  color: $success-600;
}

.history-status-text.text-error {
  color: $danger-600;
}

.history-status-text.text-warning {
  color: $secondary-600;
}

.history-method-text {
  font-size: 10px;
  color: $neutral-600;
  font-weight: 400;
}

/* Time Badge */
.history-time-badge {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: $neutral-300;
  border-radius: 4px;
  font-size: 10px;
  color: $neutral-700;
  font-weight: 500;
}

/* Klinik Badge */
.history-klinik-badge {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: rgba($primary-500, 0.1);
  color: $primary-600;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}

/* Queue Badge */
.history-queue-badge {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: rgba($secondary-500, 0.1);
  color: $secondary-600;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}

/* Info Badge (Patient ID & Payment) */
.history-info-badge {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: $neutral-300;
  color: $neutral-700;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 500;
}

.border-top-history {
  border-top: 1px solid $neutral-400 !important;
  margin-top: 2px;
}



/* Gap utility untuk flex-wrap */
.gap-1 {
  gap: 4px;
}

.gap-2 {
  gap: 8px;
}

@media (min-width: 960px) {
  .checkin-left-col,
  .checkin-right-col {
    flex: 0 0 50% !important;
    max-width: 50% !important;
  }
}

@keyframes fadeIn {
  from { 
    opacity: 0; 
    transform: translateY(10px); 
  }
  to { 
    opacity: 1; 
    transform: translateY(0); 
  }
}

/* Status Header */
.status-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 16px;
  background: linear-gradient(135deg, #f5f7fa 0%, #e3f2fd 100%);
  border-radius: 12px;
  border: 1px solid rgba($primary-600, 0.1);
  text-align: center;
}

.status-icon-wrapper {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: $neutral-100;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  flex-shrink: 0;
  margin: 0 auto;
}

.status-text {
  width: 100%;
  text-align: center;
}

.status-title {
  font-size: 16px;
  font-weight: 600;
  color: #1a1a1a;
  margin: 0 0 4px;
  letter-spacing: -0.3px;
  text-align: center;
}

.status-subtitle {
  font-size: 13px;
  color: $neutral-700;
  margin: 0;
  line-height: 1.4;
  text-align: center;
}

/* QR Scanner Modern */
.qr-scanner-container {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 24px 0;
}

.qr-placeholder {
  width: 100%;
  max-width: 320px;
  height: 320px;
  background: linear-gradient(135deg, #f5f7fa 0%, #e3f2fd 100%);
  border-radius: 16px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: 2px dashed $primary-600;
  box-shadow: 0 4px 20px rgba(21, 101, 192, 0.1);
  margin: 0 auto;
}

.qr-reader-container {
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
  position: relative;
}

.qr-reader-wrapper {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
  background: #000;
  position: relative;
  max-width: 320px;
  max-height: 320px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid rgba(21, 101, 192, 0.2);
  margin: 0 auto;
}

.qr-reader-wrapper :deep(video) {
  width: 100% !important;
  height: 100% !important;
  border-radius: 16px;
  display: block !important;
  object-fit: cover;
  background: #000;
  aspect-ratio: 1 / 1;
  transform: scaleX(-1); /* Mirror effect */
  -webkit-transform: scaleX(-1); /* Safari support */
  /* Reduce brightness to prevent overexposure/bloom */
  filter: brightness(0.75) contrast(1.1);
  -webkit-filter: brightness(0.75) contrast(1.1);
}

.qr-reader-wrapper :deep(canvas) {
  display: none !important;
}

.qr-reader-wrapper :deep(#qr-reader__dashboard) {
  display: none !important;
}

.qr-reader-wrapper :deep(#qr-reader__scan_region) {
  border-radius: 16px;
  border: 3px solid rgba($primary-600, 0.8) !important;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.4) !important;
  position: relative;
}

.qr-reader-wrapper :deep(#qr-reader__scan_region::before) {
  content: '';
  position: absolute;
  top: -3px;
  left: -3px;
  right: -3px;
  bottom: -3px;
  border: 3px solid rgba(21, 101, 192, 0.8);
  border-radius: 16px;
  animation: pulse-border 2s ease-in-out infinite;
}

@keyframes pulse-border {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.7;
    transform: scale(1.02);
  }
}

.qr-reader-wrapper :deep(#qr-reader__scan_region video) {
  border-radius: 16px;
  width: 100% !important;
  height: 100% !important;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transform: scaleX(-1); /* Mirror effect */
  -webkit-transform: scaleX(-1); /* Safari support */
  /* Reduce brightness to prevent overexposure/bloom */
  filter: brightness(0.75) contrast(1.1);
  -webkit-filter: brightness(0.75) contrast(1.1);
}

.scanner-status {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 6px;
  font-size: 12px;
}

.scanner-instruction {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-top: 8px;
  padding: 6px 10px;
  background: linear-gradient(135deg, rgba($primary-600, 0.1) 0%, rgba($primary-700, 0.1) 100%);
  border-radius: 8px;
  color: $primary-600;
  font-weight: 500;
  font-size: 11px;
  line-height: 1.4;
  text-align: left;
  border: 1px solid rgba($primary-600, 0.2);
  max-width: 320px;
  margin-left: auto;
  margin-right: auto;
}

.scanner-instruction .v-icon {
  flex-shrink: 0;
  margin-right: 8px;
}

.scanner-loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 16px;
  z-index: 10;
}

.scanner-overlay {
  position: absolute;
  width: 80%;
  height: 80%;
}

.corner {
  position: absolute;
  width: 40px;
  height: 40px;
  border: 3px solid $primary-600;
}

.corner-tl {
  top: 0;
  left: 0;
  border-right: none;
  border-bottom: none;
  border-radius: 8px 0 0 0;
}

.corner-tr {
  top: 0;
  right: 0;
  border-left: none;
  border-bottom: none;
  border-radius: 0 8px 0 0;
}

.corner-bl {
  bottom: 0;
  left: 0;
  border-right: none;
  border-top: none;
  border-radius: 0 0 0 8px;
}

.corner-br {
  bottom: 0;
  right: 0;
  border-left: none;
  border-top: none;
  border-radius: 0 0 8px 0;
}

.scan-line {
  position: absolute;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, $primary-600, transparent);
  top: 0;
  animation: scan 2s linear infinite;
  box-shadow: 0 0 10px $primary-600;
}

@keyframes scan {
  0% { top: 0; }
  100% { top: 100%; }
}

.qr-icon {
  position: relative;
  z-index: 1;
  animation: breathe 2s ease-in-out infinite;
}

@keyframes breathe {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}

/* Modern Buttons */
.btn-primary-modern {
  background: linear-gradient(135deg, #1565C0 0%, #0D47A1 100%) !important;
  color: $neutral-100 !important;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.3px;
  border-radius: 12px !important;
  padding: 14px 28px !important;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 4px 16px rgba($primary-600, 0.3) !important;
}

.btn-primary-modern:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba($primary-600, 0.4) !important;
}

.btn-primary-modern:active {
  transform: translateY(0);
}

.btn-primary-modern:disabled {
  opacity: 0.5;
  transform: none !important;
}

.btn-stop-modern {
  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%) !important;
  color: $neutral-100 !important;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.3px;
  border-radius: 12px !important;
  padding: 14px 28px !important;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 4px 16px rgba($danger-500, 0.3) !important;
}

.btn-stop-modern:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba($danger-500, 0.4) !important;
}

.action-buttons {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.btn-centered {
  width: auto !important;
  min-width: 240px !important;
  max-width: 320px !important;
  margin: 0 auto !important;
  display: block !important;
}

.btn-centered-small {
  width: auto !important;
  min-width: 180px !important;
  margin: 0 auto;
  display: block;
}

.btn-test-camera {
  border-color: #1565C0 !important;
  color: #1565C0 !important;
}

.btn-test-camera :deep(.v-btn__content) {
  color: #1565C0 !important;
}

.btn-test-camera :deep(.v-icon) {
  color: #1565C0 !important;
  opacity: 1 !important;
}

/* Modern Inputs */
.input-modern :deep(.v-field) {
  border-radius: 12px;
  font-size: 15px;
  background: $neutral-300;
  border: 1.5px solid $neutral-400;
  transition: all 0.3s ease;
}

.input-modern :deep(.v-field--focused) {
  background: $neutral-100;
  border-color: $primary-600;
  box-shadow: 0 0 0 4px rgba(21, 101, 192, 0.1);
}

.input-modern :deep(.v-field__input) {
  padding-top: 12px;
  padding-bottom: 12px;
}

.input-modern :deep(.v-label) {
  font-weight: 500;
  color: $neutral-700;
}

.quick-actions {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #e5e7eb;
}

.info-card {
  display: flex;
  justify-content: center;
}

.info-alert-centered {
  width: 100%;
}

.info-alert-centered :deep(.v-alert__content) {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 100% !important;
}

.quick-actions .v-btn {
  transition: all 0.3s ease;
  border-radius: 12px !important;
  border: 1.5px solid #e5e7eb !important;
}

.quick-actions .v-btn:hover {
  transform: translateY(-2px);
  border-color: #1565C0 !important;
  box-shadow: 0 4px 12px rgba($primary-600, 0.15);
}

.quick-actions .v-btn :deep(.v-icon) {
  opacity: 1 !important;
  color: inherit !important;
}

.quick-actions .v-btn[color="primary"] {
  color: #1565C0 !important;
  border-color: #1565C0 !important;
}

.quick-actions .v-btn[color="primary"] :deep(.v-icon) {
  color: #1565C0 !important;
}

.qr-code-container {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 16px;
  background: $neutral-100;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.qr-code-container :deep(canvas) {
  border-radius: 8px;
}

.qr-display {
  animation: slideUp 0.5s ease-out;
}

.blur-dialog :deep(.v-overlay__scrim) {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.dialog-card {
  overflow: hidden;
  animation: popIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  border-radius: 16px !important;
}

@keyframes popIn {
  0% {
    opacity: 0;
    transform: scale(0.8) translateY(20px);
  }
  100% {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.dialog-header {
  position: relative;
  overflow: hidden;
  border-radius: 16px 16px 0 0;
}

.dialog-header::before {
  display: none;
}

.icon-wrapper {
  display: inline-block;
}

.dialog-icon {
  filter: drop-shadow(0 4px 12px rgba(0,0,0,0.3));
}

.success-header {
  background: linear-gradient(135deg, $success-400 0%, $success-600 100%);
}

.warning-header {
  background: linear-gradient(135deg, $secondary-400 0%, $secondary-500 100%);
}

.error-header {
  background: linear-gradient(135deg, $danger-400 0%, $danger-600 100%);
}

.icon-bg {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}

.icon-bg-success {
  background: linear-gradient(135deg, $success-400 0%, $success-600 100%);
}

.icon-bg-warning {
  background: linear-gradient(135deg, $secondary-400 0%, $secondary-500 100%);
}

.icon-bg-error {
  background: linear-gradient(135deg, $danger-400 0%, $danger-600 100%);
}

.instruction-box {
  border: 1px solid transparent;
}

.instruction-success {
  background: rgba($success-100, 0.5) !important;
  border-color: rgba($success-500, 0.2) !important;
}

.instruction-warning {
  background: rgba($secondary-100, 0.5) !important;
  border-color: rgba($secondary-500, 0.2) !important;
}

.dialog-button {
  text-transform: none;
  letter-spacing: 0.5px;
  font-weight: 600;
  transition: all 0.3s ease;
}

.dialog-button:hover {
  transform: translateY(-2px);
}

/* Patient Info Card Styling */
.patient-info-card {
  background: rgba($neutral-300, 0.8) !important;
  border-color: rgba(0, 0, 0, 0.08) !important;
}

.patient-info-label {
  color: $neutral-600 !important;
  font-weight: 500;
  opacity: 0.9;
}

.patient-info-value {
  color: $neutral-700 !important;
  font-weight: 500 !important;
  opacity: 0.85;
}

.patient-info-icon {
  opacity: 0.7;
}

/* Stats Footer Modern */
.stats-footer-modern {
  animation: slideUp 0.5s ease-out 0.3s both;
}

/* Layout with Sidebar */
.layout-with-sidebar {
  gap: 0;
}

@media (min-width: 1264px) {
  .layout-with-sidebar {
    gap: 16px;
  }
}

/* Stats Sidebar Discord-style (Right Side) */
.main-content-col {
  padding-right: 0;
}

@media (min-width: 1264px) {
  .main-content-col {
    padding-right: 20px;
  }
}

.stats-sidebar-right {
  padding-left: 0;
  min-width: 80px;
  display: none;
  align-items: flex-start;
  justify-content: flex-start;
  flex-shrink: 0;
}

@media (min-width: 1264px) {
  .stats-sidebar-right {
    display: flex !important;
  }
}

.stats-sidebar-discord {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 4px;
  width: 80px;
  height: fit-content;
  background: linear-gradient(180deg, #ffffff 0%, #f8f9fa 100%);
  border-radius: 16px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(0, 0, 0, 0.08);
}

@media (min-width: 1264px) {
  .stats-sidebar-discord {
    position: sticky;
    top: 12px;
  }
}

.stat-item-discord {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  width: 72px;
  margin: 0 auto;
  padding: 8px 0;
  border-radius: 12px;
}

.stat-item-discord::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 0;
  background: currentColor;
  border-radius: 0 3px 3px 0;
  transition: height 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  opacity: 0;
}

.stat-item-discord:hover::before {
  height: 40px;
  opacity: 1;
}

.stat-item-primary {
  color: #5865f2;
}

.stat-item-success {
  color: #57f287;
}

.stat-item-secondary {
  color: #faa61a;
}

.stat-item-discord:hover {
  background: rgba(0, 0, 0, 0.04);
  transform: translateX(2px);
}

.stat-icon-discord {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  background: $neutral-300;
  border: 2px solid rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.stat-icon-discord::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  padding: 2px;
  background: linear-gradient(135deg, currentColor, transparent);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 0.25s ease;
}

.stat-item-discord:hover .stat-icon-discord::after {
  opacity: 1;
}

.stat-icon-discord .v-icon {
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  z-index: 1;
}

.stat-item-primary .stat-icon-discord {
  background: rgba(88, 101, 242, 0.1);
  border-color: rgba(88, 101, 242, 0.3);
}

.stat-item-primary:hover .stat-icon-discord {
  background: #5865f2;
  border-color: #5865f2;
  border-radius: 18px;
  box-shadow: 0 4px 16px rgba(88, 101, 242, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.stat-item-primary:hover .stat-icon-discord .v-icon {
  color: $neutral-100 !important;
  transform: scale(1.1) rotate(5deg);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
}

.stat-item-success .stat-icon-discord {
  background: rgba(87, 242, 135, 0.1);
  border-color: rgba(87, 242, 135, 0.3);
}

.stat-item-success:hover .stat-icon-discord {
  background: #57f287;
  border-color: #57f287;
  border-radius: 18px;
  box-shadow: 0 4px 16px rgba(87, 242, 135, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.stat-item-success:hover .stat-icon-discord .v-icon {
  color: $neutral-100 !important;
  transform: scale(1.1) rotate(-5deg);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
}

.stat-item-secondary .stat-icon-discord {
  background: rgba(250, 166, 26, 0.1);
  border-color: rgba(250, 166, 26, 0.3);
}

.stat-item-secondary:hover .stat-icon-discord {
  background: #faa61a;
  border-color: #faa61a;
  border-radius: 18px;
  box-shadow: 0 4px 16px rgba(250, 166, 26, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.stat-item-secondary:hover .stat-icon-discord .v-icon {
  color: $neutral-100 !important;
  transform: scale(1.1) rotate(5deg);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
}

.stat-content-discord {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  margin-top: 8px;
  opacity: 0.8;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.stat-item-discord:hover .stat-content-discord {
  opacity: 1;
  transform: translateY(-1px);
}

.stat-value-discord {
  font-size: 15px;
  font-weight: 800;
  color: #1a1a1a;
  letter-spacing: -0.3px;
  line-height: 1.2;
}

.stat-label-discord {
  font-size: 9px;
  color: $neutral-700;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  line-height: 1.2;
  text-align: center;
}

@keyframes slideUp {
  from { 
    opacity: 0; 
    transform: translateY(10px); 
  }
  to { 
    opacity: 1; 
    transform: translateY(0); 
  }
}

.stat-card-modern {
  background: $neutral-100;
  border-radius: 12px;
  padding: 16px 12px;
  text-align: center;
  border: 1px solid #e5e7eb;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.stat-card-modern::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, $primary-600 0%, $primary-700 100%);
  transform: scaleX(0);
  transition: transform 0.3s ease;
}

.stat-card-modern:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
  border-color: $primary-600;
}

.stat-card-modern:hover::before {
  transform: scaleX(1);
}

.stat-icon-modern {
  margin-bottom: 12px;
  display: inline-flex;
  padding: 8px;
  background: $primary-100;
  border-radius: 10px;
}

.stat-value {
  font-size: 20px;
  font-weight: 700;
  color: #1a1a1a;
  margin-bottom: 4px;
  letter-spacing: -0.5px;
}

.stat-label {
  font-size: 11px;
  color: $neutral-700;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.custom-snackbar {
  margin-bottom: 16px;
  margin-right: 16px;
}

.custom-snackbar :deep(.v-snackbar__wrapper) {
  min-width: 300px;
}

/* History Dialog Styles */
.history-list {
  max-height: 500px;
  overflow-y: auto;
  padding-right: 8px;
}

.history-list::-webkit-scrollbar {
  width: 6px;
}

.history-list::-webkit-scrollbar-track {
  background: $neutral-300;
  border-radius: 10px;
}

.history-list::-webkit-scrollbar-thumb {
  background: $neutral-600;
  border-radius: 10px;
}

.history-list::-webkit-scrollbar-thumb:hover {
  background: $neutral-700;
}

.history-item {
  transition: all 0.3s ease;
  border-left: 4px solid transparent;
}

.history-item:hover {
  transform: translateX(4px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.history-success {
  border-left-color: $success-500;
  background: rgba($success-500, 0.05);
}

.history-failed {
  border-left-color: $danger-500;
  background: rgba($danger-500, 0.05);
}

.history-pending {
  border-left-color: $secondary-500;
  background: rgba($secondary-500, 0.05);
}

/* History Item Dialog Styling */
.history-item-dialog {
  transition: all 0.2s ease;
  position: relative;
  overflow: hidden;
  background: $neutral-100 !important;
  border: 1px solid $neutral-400 !important;
  border-radius: 10px !important;
  border-left: 3px solid transparent !important;
}

.history-item-dialog::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: transparent;
  z-index: 1;
  border-radius: 10px 0 0 10px;
}

.history-item-dialog:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
  border-color: $neutral-500 !important;
}

.history-item-dialog.history-success::before {
  background: $success-500 !important;
}

.history-item-dialog.history-success {
  background: rgba($success-100, 0.5) !important;
  border-left-color: $success-500 !important;
}

.history-item-dialog.history-failed::before {
  background: $danger-500 !important;
}

.history-item-dialog.history-failed {
  background: rgba($danger-100, 0.5) !important;
  border-left-color: $danger-500 !important;
}

.history-item-dialog.history-pending::before {
  background: $secondary-500 !important;
}

.history-item-dialog.history-pending {
  background: rgba($secondary-100, 0.5) !important;
  border-left-color: $secondary-500 !important;
}

.history-item-dialog.history-item-qr {
  border-left-color: $secondary-500 !important;
  background: rgba($secondary-100, 0.3) !important;
}

.history-item-dialog.history-item-qr::before {
  background: $secondary-500 !important;
}

/* Status Badge Dialog */
.history-status-badge-dialog {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.history-status-badge-dialog.status-success {
  background: rgba($success-500, 0.15);
  color: $success-600;
}

.history-status-badge-dialog.status-error,
.history-status-badge-dialog.status-warning {
  background: rgba($danger-500, 0.15);
  color: $danger-600;
}

.history-status-badge-dialog.status-warning {
  background: rgba($secondary-500, 0.15);
  color: $secondary-600;
}

.history-status-text-dialog {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  margin-bottom: 0;
}

.history-status-text-dialog.text-success {
  color: $success-600;
}

.history-status-text-dialog.text-error {
  color: $danger-600;
}

.history-status-text-dialog.text-warning {
  color: $secondary-600;
}

.history-method-text-dialog {
  font-size: 10px;
  color: $neutral-600;
  font-weight: 400;
}

/* Queue Badge Dialog */
.history-queue-badge-dialog {
  display: flex;
  align-items: center;
  padding: 3px 8px;
  background: rgba($secondary-500, 0.1);
  color: $secondary-600;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
}

/* Info Badge Dialog */
.history-info-badge-dialog {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: $neutral-300;
  color: $neutral-700;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}

.history-klinik-badge-dialog {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: rgba($primary-500, 0.1);
  color: $primary-600;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}

.history-payment-badge-dialog {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: rgba($primary-500, 0.1);
  color: $primary-600;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
}

.history-qr-badge-dialog {
  display: flex;
  align-items: center;
  padding: 3px 8px;
  background: rgba($primary-500, 0.1);
  color: $primary-600;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
}

/* Time Badge Dialog */
.history-time-badge-dialog {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  background: $neutral-300;
  border-radius: 4px;
  font-size: 10px;
  color: $neutral-700;
  font-weight: 500;
}

/* Action Buttons */
.history-delete-btn,
.history-action-btn {
  opacity: 0.7;
  transition: all 0.2s ease;
}

.history-item-dialog:hover .history-delete-btn,
.history-item-dialog:hover .history-action-btn {
  opacity: 1;
}

/* History Header Stats */
.history-header-stats {
  padding: 12px;
  background: $neutral-100;
  border-radius: 12px;
  border: 1px solid $neutral-400;
}

.history-header-title {
  padding-bottom: 6px;
  border-bottom: 1px solid $neutral-400;
}

.history-header-title h3 {
  color: $neutral-900;
  margin: 0;
}

.stat-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
  background: $neutral-100;
  border-radius: 8px;
  border: 1px solid $neutral-400;
  transition: all 0.2s ease;
  height: 100%;
}

.stat-card-header:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
}

.stat-icon-header {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.stat-icon-total {
  background: rgba($primary-500, 0.15);
  color: $primary-600;
}

.stat-icon-success {
  background: rgba($success-500, 0.15);
  color: $success-600;
}

.stat-icon-failed {
  background: rgba($danger-500, 0.15);
  color: $danger-600;
}

.stat-icon-filtered {
  background: rgba($secondary-500, 0.15);
  color: $secondary-600;
}

.stat-content-header {
  flex: 1;
  min-width: 0;
}

.stat-value-header {
  font-size: 16px;
  font-weight: 700;
  color: $neutral-900;
  line-height: 1.2;
  margin-bottom: 1px;
}

.stat-label-header {
  font-size: 10px;
  color: $neutral-600;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* Mobile Optimization */
@media (max-width: 600px) {
  .v-container.no-scroll-container {
    padding: 8px !important;
  }
  
  .main-card {
    border-radius: 16px !important;
  }
  
  .header-modern {
    padding: 6px 16px 4px !important;
  }
  
  .content-modern {
    padding: 16px !important;
    max-height: calc(100vh - 180px);
  }
  
  .header-content {
    flex-direction: column;
    text-align: center;
    gap: 12px;
  }
  
  .header-text {
    text-align: center;
  }
  
  .icon-circle {
    width: 40px;
    height: 40px;
  }
  
  .title-modern {
    font-size: 16px;
  }
  
  .subtitle-modern {
    font-size: 11px;
  }
  
  .content-modern {
    padding: 20px 16px !important;
  }
  
  .status-header {
    padding: 16px;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 12px;
  }
  
  .status-icon-wrapper {
    margin: 0 auto;
  }
  
  .status-text {
    text-align: center;
    width: 100%;
  }
  
  .status-title {
    font-size: 16px;
  }
  
  .status-subtitle {
    font-size: 13px;
  }
  
  .qr-placeholder {
    max-width: 100%;
    height: 250px;
  }
  
  .qr-reader-container {
    max-width: 100%;
  }
  
  .qr-reader-wrapper {
    min-height: 250px;
    max-height: 250px;
    max-width: 250px;
    border-radius: 16px;
  }
  
  .qr-reader-wrapper :deep(video) {
    max-height: 250px;
    object-fit: contain;
    transform: scaleX(-1); /* Mirror effect */
    -webkit-transform: scaleX(-1); /* Safari support */
    /* Reduce brightness to prevent overexposure/bloom */
    filter: brightness(0.75) contrast(1.1);
    -webkit-filter: brightness(0.75) contrast(1.1);
  }
  
  .scanner-instruction {
    font-size: 10px;
    padding: 6px 8px;
    margin-top: 6px;
    max-width: 100%;
  }
  
  .scanner-instruction .v-icon {
    font-size: 14px !important;
    margin-right: 6px !important;
  }
  
  .stats-footer-modern {
    margin-top: 8px;
  }
  
  .stat-card-modern {
    padding: 12px 8px;
  }
  
  .stat-value {
    font-size: 18px;
  }
  
  .stat-label {
    font-size: 10px;
  }
  
  .stat-icon-modern {
    margin-bottom: 8px;
    padding: 6px;
  }

  .tabs-modern :deep(.v-tab) {
    font-size: 12px;
    padding: 0 12px;
  }
  
  .tabs-modern :deep(.v-tab .v-icon) {
    font-size: 18px;
  }
  
  .btn-primary-modern,
  .btn-stop-modern {
    padding: 12px 24px !important;
    font-size: 14px;
    min-width: 200px !important;
  }
  
  .btn-centered {
    min-width: 200px !important;
    max-width: 280px !important;
  }
  
  .qr-placeholder {
    max-width: 100%;
    height: 220px;
  }
  
  .qr-reader-wrapper {
    min-height: 220px;
    max-height: 220px;
    max-width: 220px;
  }
  
  /* Hide stats sidebar on mobile */
  .stats-sidebar-right {
    display: none !important;
  }
  
  .main-content-col {
    padding-right: 0 !important;
  }
}

/* Stats Footer Horizontal - For Small Screens */
.stats-footer-horizontal {
  display: flex;
  width: 100%;
  gap: 8px;
  padding: 12px;
  background: linear-gradient(180deg, #ffffff 0%, #f8f9fa 100%);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  border: 1px solid rgba(0, 0, 0, 0.08);
}

.stat-item-footer {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8px 4px;
  border-radius: 10px;
  transition: all 0.2s ease;
  cursor: pointer;
  position: relative;
}

.stat-item-footer:hover {
  background: rgba(0, 0, 0, 0.03);
}

.stat-icon-footer {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  background: $neutral-300;
  border: 2px solid rgba(0, 0, 0, 0.08);
  margin-bottom: 6px;
}

.stat-item-footer-primary .stat-icon-footer {
  background: rgba(88, 101, 242, 0.1);
  border-color: rgba(88, 101, 242, 0.3);
}

.stat-item-footer-primary:hover .stat-icon-footer {
  background: #5865f2;
  border-color: #5865f2;
  transform: scale(1.1);
}

.stat-item-footer-primary:hover .stat-icon-footer .v-icon {
  color: $neutral-100 !important;
}

.stat-item-footer-success .stat-icon-footer {
  background: rgba(87, 242, 135, 0.1);
  border-color: rgba(87, 242, 135, 0.3);
}

.stat-item-footer-success:hover .stat-icon-footer {
  background: #57f287;
  border-color: #57f287;
  transform: scale(1.1);
}

.stat-item-footer-success:hover .stat-icon-footer .v-icon {
  color: $neutral-100 !important;
}

.stat-item-footer-secondary .stat-icon-footer {
  background: rgba(250, 166, 26, 0.1);
  border-color: rgba(250, 166, 26, 0.3);
}

.stat-item-footer-secondary:hover .stat-icon-footer {
  background: #faa61a;
  border-color: #faa61a;
  transform: scale(1.1);
}

.stat-item-footer-secondary:hover .stat-icon-footer .v-icon {
  color: $neutral-100 !important;
}

.stat-content-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.stat-value-footer {
  font-size: 14px;
  font-weight: 700;
  color: #1a1a1a;
  letter-spacing: -0.2px;
  line-height: 1.2;
}

.stat-label-footer {
  font-size: 8px;
  color: $neutral-700;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  line-height: 1.2;
  text-align: center;
}

@media (max-width: 960px) {
  .stat-icon-footer {
    width: 36px;
    height: 36px;
  }
  
  .stat-icon-footer .v-icon {
    font-size: 18px !important;
  }
  
  .stat-value-footer {
    font-size: 13px;
  }
  
  .stat-label-footer {
    font-size: 7px;
  }
}

@media (min-width: 1264px) {
  .stats-footer-horizontal {
    display: none !important;
  }
}

/* Mobile Landscape */
@media (max-width: 900px) and (orientation: landscape) {
  .qr-reader-wrapper {
    min-height: 250px;
    max-height: 250px;
    max-width: 250px;
  }
  
  .qr-reader-wrapper :deep(video) {
    max-height: 250px;
    transform: scaleX(-1); /* Mirror effect */
    -webkit-transform: scaleX(-1); /* Safari support */
    /* Reduce brightness to prevent overexposure/bloom */
    filter: brightness(0.75) contrast(1.1);
    -webkit-filter: brightness(0.75) contrast(1.1);
  }
}
</style>