<!-- pages/Anjungan/AntrianKlinikRuang/[kodeKlinik].vue -->
<template>
  <div class="antrian-display-container">
    <!-- Header -->
    <div class="display-header">
      <div class="header-left">
        <div class="logo-circle">
          <img 
            src="/Rumah_Sakit_Umum_Daerah_Dr._Saiful_Anwar.webp" 
            alt="RSUD Logo" 
            class="header-logo"
          >
        </div>
        <div class="header-text">
          <h1 class="hospital-name">ANTRIAN KLINIK RUANG</h1>
          <p class="display-subtitle">RSUD dr. Saiful Anwar Provinsi Jawa Timur</p>
          </div>
      </div>
      <div class="header-right">
        <div class="datetime-display">
          <div class="time-large">{{ currentTime }}</div>
          <div class="date-small">{{ currentDate }}</div>
        </div>
      </div>
    </div>

    <!-- Hero Call Section -->
    <div v-if="currentCalledQueue" class="hero-call-section">
      <div class="call-label">
        <v-icon size="32" color="white" class="mr-2">mdi-bullhorn</v-icon>
        NOMOR ANTRIAN YANG DIPANGGIL
      </div>
      <div class="call-number">{{ currentCalledQueue.noAntrian.split(' |')[0] }}</div>
      <div class="call-clinic">{{ currentCalledQueue.klinik }} - {{ currentCalledQueue.ruang }}</div>
    </div>

    <!-- Main Grid - Display Ruang -->
    <div class="clinics-grid">
      <div
        v-for="ruang in displayedRuang"
        :key="`${ruang.kodeKlinik}-${ruang.nomorRuang}`"
        class="clinic-box"
      >
        <!-- Clinic Header -->
        <div class="clinic-header-bar">
          <span class="clinic-title">{{ ruang.namaKlinik }} - {{ ruang.namaRuang }}</span>
          <v-chip size="small" class="clinic-count">
            <v-icon size="16" color="white" class="mr-1">mdi-account-multiple</v-icon>
            <span class="count-text">{{ ruang.totalQueues }}</span>
          </v-chip>
        </div>

        <!-- Queue Content -->
        <div class="clinic-content">
          <!-- Pemeriksaan Awal Section -->
          <div class="tipe-layanan-section">
            <div class="tipe-label">PEMERIKSAAN AWAL</div>
            <div v-if="ruang.pemeriksaanAwal.currentQueue" class="current-section">
              <div class="current-label">SEKARANG</div>
              <div class="current-number">
                {{ ruang.pemeriksaanAwal.currentQueue.noAntrian.split(' |')[0] }}
              </div>
            </div>
            <div v-if="!ruang.pemeriksaanAwal.currentQueue" class="empty-state-small">
              <v-icon size="24" color="grey-lighten-3">mdi-clock-outline</v-icon>
              <p class="empty-text-small">Tidak Ada Antrian</p>
            </div>
          </div>

          <!-- Divider -->
          <v-divider class="my-3" />

          <!-- Tindakan Section -->
          <div class="tipe-layanan-section">
            <div class="tipe-label">TINDAKAN</div>
            <div v-if="ruang.tindakan.currentQueue" class="current-section">
              <div class="current-label">SEKARANG</div>
              <div class="current-number">
                {{ ruang.tindakan.currentQueue.noAntrian.split(' |')[0] }}
              </div>
            </div>
            <div v-if="!ruang.tindakan.currentQueue" class="empty-state-small">
              <v-icon size="24" color="grey-lighten-3">mdi-clock-outline</v-icon>
              <p class="empty-text-small">Tidak Ada Antrian</p>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Footer Stats -->
    <div class="footer-stats-bar">
      <div class="stat-item">
        <div class="stat-icon stat-icon-total">
          <v-icon size="32" color="success-600">mdi-format-list-numbered</v-icon>
        </div>
        <div class="stat-info">
          <div class="stat-value">{{ statistics.total }}</div>
          <div class="stat-label">Total Antrian</div>
        </div>
      </div>

      <div class="stat-divider"></div>

      <div class="stat-item">
        <div class="stat-icon stat-icon-waiting">
          <v-icon size="32" color="success-600">mdi-clock-alert-outline</v-icon>
        </div>
        <div class="stat-info">
          <div class="stat-value">{{ statistics.waiting }}</div>
          <div class="stat-label">Menunggu</div>
        </div>
      </div>

      <div class="stat-divider"></div>

      <div class="stat-item">
        <div class="stat-icon stat-icon-active">
          <v-icon size="32" color="success-600">mdi-account-check</v-icon>
        </div>
        <div class="stat-info">
          <div class="stat-value">{{ statistics.active }}</div>
          <div class="stat-label">Sedang Dilayani</div>
        </div>
      </div>

      <div class="footer-message">
        <v-icon size="24" color="success-600" class="mr-2">mdi-information</v-icon>
        <span>Harap perhatikan nomor antrian Anda di layar</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useQueueStore } from '@/stores/queueStore'
import { useMasterStore } from '@/stores/masterStore'
import { useRoute } from '#app'
import { useWebSocket } from '@/composables/useWebSocket'

definePageMeta({
  layout: false,
})

const route = useRoute()
const queueStore = useQueueStore()
const masterStore = useMasterStore()

const kodeKlinik = computed(() => {
  const kode = route.params.kodeKlinik
  // Handle both string and array cases
  return Array.isArray(kode) ? kode[0] : kode
})

const klinikData = computed(() => {
  const kode = kodeKlinik.value
  if (!kode) return null

  const fromGetter = masterStore.getAllRuangList?.value
  const fromState = masterStore.ruangData?.value || masterStore.ruangData || []

  let allRuang = Array.isArray(fromGetter) ? fromGetter : []
  if (allRuang.length === 0 && Array.isArray(fromState)) {
    fromState.forEach((r) => {
      (r?.ruangList || []).forEach((ru) => {
        allRuang.push({
          kodeKlinik: r.kodeKlinik,
          namaKlinik: r.namaKlinik,
          nomorRuang: ru.nomorRuang,
          namaRuang: ru.namaRuang,
          nomorScreen: ru.nomorScreen,
        })
      })
    })
  }

  const firstRuang = allRuang.find(r => r.kodeKlinik === kode)
  if (firstRuang) {
    return {
      kodeKlinik: firstRuang.kodeKlinik,
      namaKlinik: firstRuang.namaKlinik
    }
  }
  return null
})

const currentTime = ref('')
const currentDate = ref('')
let timeInterval = null

const klinikPatients = computed(() => {
  // Get patients from klinik-ruang stage (created from AdminKlinikRuang)
  // Filter out finished patients (status: 'processed' or 'selesai')
  return queueStore.allPatients.filter(p => 
    p.processStage === 'klinik-ruang' && 
    p.kodeKlinik === kodeKlinik.value &&
    p.status !== 'processed' &&
    p.status !== 'selesai'
  )
})

// Get ruang list for this specific klinik
const ruangListForKlinik = computed(() => {
  if (!kodeKlinik.value || !klinikData.value) return []

  const fromGetter = masterStore.getAllRuangList?.value
  const fromState = masterStore.ruangData?.value || masterStore.ruangData || []
  let allRuang = Array.isArray(fromGetter) ? fromGetter : []
  if (allRuang.length === 0 && Array.isArray(fromState)) {
    fromState.forEach((r) => {
      (r?.ruangList || []).forEach((ru) => {
        allRuang.push({
          kodeKlinik: r.kodeKlinik,
          namaKlinik: r.namaKlinik,
          nomorRuang: ru.nomorRuang,
          namaRuang: ru.namaRuang,
          nomorScreen: ru.nomorScreen,
        })
      })
    })
  }
  return allRuang
    .filter(r => r.kodeKlinik === kodeKlinik.value)
    .map(ruang => ({
      kodeKlinik: ruang.kodeKlinik,
      namaKlinik: ruang.namaKlinik,
      nomorRuang: ruang.nomorRuang,
      namaRuang: ruang.namaRuang,
      nomorScreen: ruang.nomorScreen
    }))
})

const displayedRuang = computed(() => {
  if (!kodeKlinik.value || ruangListForKlinik.value.length === 0) {
    return []
  }

  return ruangListForKlinik.value.map(ruang => {
    // Get queues for this specific room
    const allQueues = klinikPatients.value
      .filter(p => p.nomorRuang === ruang.nomorRuang)
      .sort((a, b) => {
        const statusPriority = {
          'di-loket': 1,
          'waiting': 2,
          'terlambat': 3,
          'pending': 4
        }
        
        const priorityDiff = (statusPriority[a.status] || 99) - (statusPriority[b.status] || 99)
        if (priorityDiff !== 0) return priorityDiff
        
        // Sort by queue number
        const numA = parseInt(a.noAntrian.match(/\d+/)?.[0] || '999')
        const numB = parseInt(b.noAntrian.match(/\d+/)?.[0] || '999')
        return numA - numB
      })

    // Split by tipeLayanan berdasarkan tipeLayanan terakhir yang dipanggil
    // Pasien yang dipanggil akan muncul di kolom sesuai tipeLayanan terakhir yang dipanggil
    // Jika pasien dipanggil untuk Pemeriksaan Awal, muncul di kolom Pemeriksaan Awal
    // Jika pasien dipanggil untuk Tindakan, muncul di kolom Tindakan (dan hilang dari Pemeriksaan Awal)
    const pemeriksaanAwalQueues = allQueues.filter(q => {
      // Gunakan tipeLayanan (yang diupdate saat dipanggil) untuk menentukan kolom
      return q.tipeLayanan === 'Pemeriksaan Awal';
    });
    const tindakanQueues = allQueues.filter(q => {
      // Gunakan tipeLayanan (yang diupdate saat dipanggil) untuk menentukan kolom
      return q.tipeLayanan === 'Tindakan';
    })

    // Get current and next queues for each tipeLayanan
    // Current queue is the one with status 'di-loket' and matching tipeLayanan
    // Jika ada pasien baru yang dipanggil, akan menggantikan pasien sebelumnya di kolom tersebut
    const getCurrentAndNext = (queues, tipeLayanan) => {
      // Find current: pasien dengan status 'di-loket' dan tipeLayanan yang sesuai
      // Sort by lastCalledAt untuk mendapatkan yang terakhir dipanggil (yang baru dipanggil akan menggantikan yang lama)
      const currentCandidates = queues.filter(q => 
        q.status === 'di-loket' && q.tipeLayanan === tipeLayanan
      ).sort((a, b) => {
        const timeA = a.lastCalledAt ? new Date(a.lastCalledAt) : new Date(a.createdAt || 0)
        const timeB = b.lastCalledAt ? new Date(b.lastCalledAt) : new Date(b.createdAt || 0)
        return timeB - timeA // Yang terakhir dipanggil di atas
      })
      // Ambil yang terakhir dipanggil sebagai current (menggantikan yang sebelumnya)
      const current = currentCandidates.length > 0 ? currentCandidates[0] : null
      
      // Next queues: exclude current patient dan pasien dengan status 'di-loket' (yang sudah dipanggil)
      const next = queues.filter(q => 
        q.no !== current?.no && 
        q.status === 'waiting' // Hanya yang waiting (belum dipanggil)
      ).slice(0, 3) // Show max 3 next queues
      return { current, next }
    }

    const pemeriksaanAwal = getCurrentAndNext(pemeriksaanAwalQueues, 'Pemeriksaan Awal')
    const tindakan = getCurrentAndNext(tindakanQueues, 'Tindakan')

    return {
      kodeKlinik: ruang.kodeKlinik,
      namaKlinik: ruang.namaKlinik,
      nomorRuang: ruang.nomorRuang,
      namaRuang: ruang.namaRuang,
      nomorScreen: ruang.nomorScreen,
      pemeriksaanAwal: {
        currentQueue: pemeriksaanAwal.current,
        nextQueues: pemeriksaanAwal.next,
        totalQueues: pemeriksaanAwalQueues.length
      },
      tindakan: {
        currentQueue: tindakan.current,
        nextQueues: tindakan.next,
        totalQueues: tindakanQueues.length
      },
      totalQueues: allQueues.length
    }
  })
})

const currentCalledQueue = computed(() => {
  if (!kodeKlinik.value || !klinikData.value) return null
  
  // Get most recently called patient (status di-loket)
  // Sort by lastCalledAt if available, otherwise by createdAt
  const calledQueues = klinikPatients.value
    .filter(p => p.status === 'di-loket')
    .sort((a, b) => {
      const timeA = a.lastCalledAt ? new Date(a.lastCalledAt) : new Date(a.createdAt || 0)
      const timeB = b.lastCalledAt ? new Date(b.lastCalledAt) : new Date(b.createdAt || 0)
      return timeB - timeA
    })
  
  if (calledQueues.length > 0) {
    const patient = calledQueues[0]
    return {
      ...patient,
      ruang: patient.ruang || patient.namaRuang || 'Ruang 1'
    }
  }
  
  return null
})

const statistics = computed(() => {
  if (!kodeKlinik.value || !klinikData.value) {
    return { total: 0, waiting: 0, active: 0 }
  }
  
  const all = klinikPatients.value
  return {
    total: all.length,
    waiting: all.filter(p => p.status === 'waiting').length,
    active: all.filter(p => p.status === 'di-loket').length
  }
})

const updateTime = () => {
  const now = new Date()
  // Format jam dengan titik dua (HH:MM:SS)
  const timeString = now.toLocaleTimeString('id-ID', { 
    hour: '2-digit', 
    minute: '2-digit',
    second: '2-digit'
  })
  currentTime.value = timeString.replace(/\./g, ':')
  currentDate.value = now.toLocaleDateString('id-ID', {
    weekday: 'long',
    day: 'numeric',
    month: 'long',
    year: 'numeric'
  })
}

// WebSocket configuration for Anjungan
const config = useRuntimeConfig()
const wsBaseUrl = config.public?.wsBaseUrl || 'ws://10.10.150.100:8084/api/v1/ws'

// WebSocket client ID for anjungan (you can make this dynamic based on screen number)
const anjunganClientId = computed(() => {
  if (!kodeKlinik.value) return ''
  
  // Priority 1: Try to get screen number from URL query params
  const screenParam = route.query.screen
  if (screenParam) {
    const clientId = `anjungan-klinik-ruang-${kodeKlinik.value}-screen-${screenParam}`
    console.log('🆔 Using client ID from URL query screen param:', clientId)
    return clientId
  }
  
  // Priority 2: Try to get screen number from ruangList (ambil nomorScreen dari ruang pertama yang ada)
  if (ruangListForKlinik.value && ruangListForKlinik.value.length > 0) {
    // Ambil nomorScreen dari ruang pertama yang memiliki nomorScreen
    const firstRuangWithScreen = ruangListForKlinik.value.find(r => r.nomorScreen)
    if (firstRuangWithScreen && firstRuangWithScreen.nomorScreen) {
      const clientId = `anjungan-klinik-ruang-${kodeKlinik.value}-screen-${firstRuangWithScreen.nomorScreen}`
      console.log('🆔 Using client ID from ruangList nomorScreen:', clientId)
      return clientId
    }
  }
  
  // Priority 3: Fallback to client ID without screen number (broadcast)
  const clientId = `anjungan-klinik-ruang-${kodeKlinik.value}`
  console.log('🆔 Using default client ID (no screen number):', clientId)
  return clientId
})

// WebSocket instance
let wsInstance = null
const isConnected = ref(false)

// Initialize WebSocket connection
const initWebSocket = () => {
  if (!kodeKlinik.value || !anjunganClientId.value) {
    console.warn('Cannot initialize WebSocket: missing kodeKlinik or clientId')
    return null
  }

  console.log('🔌 Initializing WebSocket connection...')
  console.log('📍 URL:', wsBaseUrl)
  console.log('🆔 Client ID:', anjunganClientId.value)

    wsInstance = useWebSocket({
    url: wsBaseUrl,
    clientId: anjunganClientId.value,
    onMessage: (data) => {
      console.log('📨 WebSocket raw message received:', data)
      console.log('📨 Message type:', typeof data)
      
      // Backend mengirim data langsung atau dalam wrapper
      // Handle both cases
      let messageData = data
      
      // Jika data ada dalam property 'data', ambil itu
      if (data && typeof data === 'object' && data.data) {
        messageData = data.data
        console.log('📦 Extracted data from wrapper:', messageData)
      }
      
      // Handle patient called message - format: { noantrian: "AA001", tipeLayanan: "Pemeriksaan Awal" }
      if (messageData && messageData.noantrian) {
        const nomorAntrian = messageData.noantrian
        const tipeLayanan = messageData.tipeLayanan || null // "Pemeriksaan Awal" atau "Tindakan"
        console.log('✅ Processing patient call for nomor antrian:', nomorAntrian, 'tipeLayanan:', tipeLayanan)
        
        // Find patient by nomor antrian (check both noAntrian and barcode)
        const patientIndex = queueStore.allPatients.findIndex(p => {
          const pNoAntrian = p.noAntrian?.split(" |")[0] || p.noAntrian
          return (pNoAntrian === nomorAntrian || p.barcode === nomorAntrian) &&
                 p.kodeKlinik === kodeKlinik.value &&
                 p.processStage === 'klinik-ruang'
        })
        
        if (patientIndex !== -1) {
          // Update patient status to 'di-loket' (called) dan update tipeLayanan serta tracking flags
          const oldPatient = { ...queueStore.allPatients[patientIndex] }
          const updateData = {
            ...queueStore.allPatients[patientIndex],
            status: 'di-loket',
            lastCalledAt: new Date().toISOString(),
            lastCalledTipeLayanan: tipeLayanan,
          }
          
          // Update tipeLayanan agar pasien muncul di kolom yang sesuai
          if (tipeLayanan) {
            updateData.tipeLayanan = tipeLayanan
          }
          
          // Update tracking flags berdasarkan tipeLayanan
          if (tipeLayanan === 'Pemeriksaan Awal') {
            updateData.calledPemeriksaanAwal = true
          } else if (tipeLayanan === 'Tindakan') {
            updateData.calledTindakan = true
          }
          
          queueStore.allPatients[patientIndex] = updateData
          
          console.log('✅ Patient data updated in store based on nomor antrian:', nomorAntrian)
          console.log('📊 Old:', { status: oldPatient.status, tipeLayanan: oldPatient.tipeLayanan })
          console.log('📊 New:', { 
            status: updateData.status, 
            tipeLayanan: updateData.tipeLayanan,
            calledPemeriksaanAwal: updateData.calledPemeriksaanAwal,
            calledTindakan: updateData.calledTindakan
          })
        } else {
          // If patient doesn't exist, log warning
          console.warn('⚠️ Patient not found in store with nomor antrian:', nomorAntrian)
          console.log('📋 Available patients:', klinikPatients.value.map(p => ({
            noAntrian: p.noAntrian?.split(" |")[0],
            barcode: p.barcode,
            kodeKlinik: p.kodeKlinik
          })))
        }
      } else {
        console.log('ℹ️ Message format is invalid or missing noantrian:', messageData)
      }
    },
    onOpen: () => {
      console.log('✅ Anjungan WebSocket connected successfully!')
      console.log('🆔 Connected as:', anjunganClientId.value)
      isConnected.value = true
    },
    onClose: () => {
      console.log('⚠️ Anjungan WebSocket closed')
      isConnected.value = false
    },
    onError: (error) => {
      console.error('❌ Anjungan WebSocket error:', error)
      isConnected.value = false
    },
    reconnectInterval: 3000,
    maxReconnectAttempts: 10,
  })

  // Watch connection status
  if (wsInstance.isConnected) {
    watch(wsInstance.isConnected, (connected) => {
      isConnected.value = connected
    })
  }

  return wsInstance
}

// Responsive scaling function
const updateScale = () => {
  const container = document.querySelector('.antrian-display-container')
  if (!container) return
  
  const viewportWidth = window.innerWidth
  const viewportHeight = window.innerHeight
  const baseWidth = 1920
  const baseHeight = 1080
  
  // Calculate scale factors
  const scaleX = viewportWidth / baseWidth
  const scaleY = viewportHeight / baseHeight
  
  // Use smaller scale to fit both dimensions
  const scale = Math.min(scaleX, scaleY)
  
  // Apply scale using CSS variable
  container.style.setProperty('--scale-factor', scale.toString())
  
  // Adjust container dimensions for smaller screens
  if (viewportWidth < baseWidth || viewportHeight < baseHeight) {
    container.style.width = `${baseWidth}px`
    container.style.height = `${baseHeight}px`
  }
}

onMounted(() => {
  // Redirect to index if klinik not found
  if (!klinikData.value) {
    navigateTo('/anjungan/antrianklinikruang')
    return
  }
  
  updateTime()
  timeInterval = setInterval(updateTime, 1000)
  
  // Initialize and connect WebSocket
  if (kodeKlinik.value) {
    wsInstance = initWebSocket()
    if (wsInstance) {
      wsInstance.connect()
      console.log('🚀 WebSocket connection initiated')
    }
  }
  
  // Setup responsive scaling
  updateScale()
  window.addEventListener('resize', updateScale)
})

onUnmounted(() => {
  if (timeInterval) clearInterval(timeInterval)
  if (wsInstance) {
    wsInstance.disconnect()
    console.log('🔌 WebSocket disconnected')
  }
  window.removeEventListener('resize', updateScale)
})

// Watch for clientId changes and reconnect if needed
watch(anjunganClientId, (newClientId, oldClientId) => {
  if (newClientId && newClientId !== oldClientId && wsInstance) {
    console.log('🔄 Client ID changed, reconnecting...')
    wsInstance.disconnect()
    wsInstance = initWebSocket()
    if (wsInstance) {
      wsInstance.connect()
    }
  }
})
</script>

<style scoped lang="scss">
.antrian-display-container {
  background: var(--color-neutral-300);
  width: 1920px;
  height: 1080px;
  padding: 24px;
  font-family: 'Inter', 'Roboto', sans-serif;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  margin: 0 auto;
  box-sizing: border-box;
  
  /* Responsive scaling menggunakan CSS variables dan JavaScript */
  transform-origin: top center;
  --scale-factor: 1;
  transform: scale(var(--scale-factor));
}

/* ========== HEADER ========== */
.display-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(135deg, var(--color-success-600) 0%, var(--color-success-700) 100%);
  border-radius: 16px;
  padding: 24px 40px;
  margin-bottom: 20px;
  box-shadow: 0 8px 24px rgba(0, 146, 98, 0.3);
}

.header-left {
  display: flex;
  align-items: center;
  gap: 24px;
}

.logo-circle {
  background: rgba(255, 255, 255, 0.95);
  width: 80px;
  height: 80px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(10px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.header-logo {
  width: 64px;
  height: 64px;
  object-fit: contain;
  padding: 4px;
}

.hospital-name {
  font-size: 48px;
  font-weight: 800;
  color: var(--color-neutral-100);
  margin: 0;
  letter-spacing: 2px;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  line-height: 1;
}

.display-subtitle {
  font-size: 20px;
  font-weight: 600;
  color: var(--color-neutral-100);
  margin: 6px 0 0 0;
  opacity: 0.95;
}

.klinik-info {
  font-size: 16px;
  font-weight: 500;
  color: var(--color-neutral-100);
  margin: 4px 0 0 0;
  opacity: 0.85;
}

.datetime-display {
  text-align: right;
}

.time-large {
  font-size: 56px;
  font-weight: 900;
  color: var(--color-neutral-100);
  letter-spacing: 2px;
  line-height: 1;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.date-small {
  font-size: 18px;
  color: var(--color-neutral-100);
  margin-top: 8px;
  font-weight: 500;
  opacity: 0.95;
}

/* ========== HERO CALL SECTION ========== */
.hero-call-section {
  background: linear-gradient(135deg, var(--color-danger-600) 0%, var(--color-danger-700) 100%);
  border-radius: 20px;
  padding: 32px;
  margin-bottom: 20px;
  text-align: center;
  box-shadow: 0 12px 32px rgba(224, 21, 7, 0.35);
}

.call-label {
  font-size: 28px;
  font-weight: 700;
  color: var(--color-neutral-100);
  letter-spacing: 2px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-transform: uppercase;
}

.call-number {
  font-size: 140px;
  font-weight: 900;
  color: var(--color-neutral-100);
  margin: 16px 0;
  letter-spacing: 8px;
  line-height: 1;
  text-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

.call-clinic {
  font-size: 36px;
  font-weight: 700;
  color: var(--color-neutral-100);
  letter-spacing: 1px;
}

/* ========== CLINICS GRID ========== */
.clinics-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 20px;
  flex: 1;
}

.clinic-box {
  background: var(--color-neutral-100);
  border: 2px solid var(--color-success-200);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 146, 98, 0.12);
  min-height: 240px;
  display: flex;
  flex-direction: column;
}

.clinic-header-bar {
  background: linear-gradient(135deg, var(--color-success-600) 0%, var(--color-success-700) 100%);
  padding: 16px 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.clinic-title {
  font-size: 22px;
  font-weight: 800;
  color: var(--color-neutral-100);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  line-height: 1.2;
  flex: 1;
}

.clinic-count {
  background: rgba(255, 255, 255, 0.2) !important;
  color: var(--color-neutral-100) !important;
  font-weight: 700;
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  gap: 4px;
}

.count-text {
  font-size: 18px;
  font-weight: 800;
}

.clinic-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 20px;
  background: var(--color-success-100);
}

.tipe-layanan-section {
  margin-bottom: 8px;
}

.tipe-label {
  font-size: 20px;
  font-weight: 700;
  color: var(--color-success-700);
  margin-bottom: 12px;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 8px 12px;
  background: var(--color-success-200);
  border-radius: 8px;
  display: inline-block;
}

.empty-state-small {
  text-align: center;
  padding: 16px 0;
}

.empty-text-small {
  font-size: 12px;
  color: var(--color-neutral-600);
  margin-top: 8px;
  font-weight: 500;
}

.current-section {
  text-align: center;
  margin-bottom: 12px;
}

.current-label {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-success-600);
  margin-bottom: 8px;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.current-number {
  font-size: 80px;
  font-weight: 900;
  color: var(--color-neutral-900);
  letter-spacing: 4px;
  line-height: 1;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.next-section {
  text-align: center;
  margin-top: 8px;
}

.next-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--color-neutral-700);
  margin-bottom: 8px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

.next-numbers {
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
}

.next-item {
  background: var(--color-success-600);
  color: var(--color-neutral-100);
  padding: 8px 16px;
  border-radius: 12px;
  font-size: 22px;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(0, 146, 98, 0.25);
  letter-spacing: 1px;
  min-width: 60px;
  text-align: center;
}

// Empty state removed - only show in individual columns

/* ========== FOOTER STATS ========== */
.footer-stats-bar {
  background: var(--color-neutral-100);
  border: 2px solid var(--color-success-200);
  border-radius: 16px;
  padding: 20px 40px;
  display: flex;
  align-items: center;
  gap: 32px;
  box-shadow: 0 4px 12px rgba(0, 146, 98, 0.12);
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 16px;
}

.stat-icon {
  width: 64px;
  height: 64px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.stat-icon-total,
.stat-icon-waiting {
  background: var(--color-success-200);
}

.stat-icon-active {
  background: var(--color-success-200);
}

.stat-info {
  text-align: left;
}

.stat-value {
  font-size: 40px;
  font-weight: 900;
  color: var(--color-neutral-900);
  line-height: 1;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.stat-label {
  font-size: 14px;
  color: var(--color-neutral-700);
  font-weight: 600;
  margin-top: 4px;
  opacity: 0.95;
}

.stat-divider {
  width: 2px;
  height: 60px;
  background: var(--color-success-200);
}

.footer-message {
  flex: 1;
  text-align: right;
  font-size: 20px;
  font-weight: 600;
  color: var(--color-neutral-800);
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.ws-status-indicator {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  margin-left: 16px;
}

.ws-status-indicator.ws-connected {
  background: rgba(76, 175, 80, 0.1);
  color: #4caf50;
}

.ws-status-indicator.ws-disconnected {
  background: rgba(244, 67, 54, 0.1);
  color: #f44336;
}

.ws-status-text {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* ========== RESPONSIVE ========== */
// Base responsive rules untuk komponen individual
@media (max-width: 1919px) or (max-height: 1079px) {
  // Adjust font sizes and spacing secara proporsional
  .display-header {
    padding: clamp(12px, 1.25vw, 24px) clamp(20px, 2.08vw, 40px);
    margin-bottom: clamp(12px, 1.85vw, 20px);
  }
  
  .logo-circle {
    width: clamp(48px, 4.17vw, 80px);
    height: clamp(48px, 4.17vw, 80px);
  }
  
  .hospital-name {
    font-size: clamp(28px, 2.5vw, 48px);
  }
  
  .display-subtitle {
    font-size: clamp(14px, 1.04vw, 20px);
  }
  
  .time-large {
    font-size: clamp(36px, 2.92vw, 56px);
  }
  
  .date-small {
    font-size: clamp(12px, 0.94vw, 18px);
  }
  
  .hero-call-section {
    padding: clamp(16px, 1.67vw, 32px);
    margin-bottom: clamp(12px, 1.85vw, 20px);
  }
  
  .call-label {
    font-size: clamp(20px, 1.46vw, 28px);
  }
  
  .call-number {
    font-size: clamp(80px, 7.29vw, 140px);
  }
  
  .call-clinic {
    font-size: clamp(24px, 1.88vw, 36px);
  }
  
  .clinics-grid {
    gap: clamp(8px, 0.83vw, 16px);
    margin-bottom: clamp(12px, 1.85vw, 20px);
  }
  
  .clinic-header-bar {
    padding: clamp(10px, 1.04vw, 16px) clamp(12px, 1.04vw, 20px);
  }
  
  .clinic-title {
    font-size: clamp(16px, 1.15vw, 22px);
  }
  
  .clinic-content {
    padding: clamp(12px, 1.04vw, 20px);
  }
  
  .current-number {
    font-size: clamp(56px, 4.17vw, 80px);
  }
  
  .tipe-label {
    font-size: clamp(16px, 1.04vw, 20px);
    padding: clamp(6px, 0.42vw, 8px) clamp(10px, 0.63vw, 12px);
  }
  
  .footer-stats-bar {
    padding: clamp(12px, 1.04vw, 20px) clamp(24px, 2.08vw, 40px);
    gap: clamp(16px, 1.67vw, 32px);
  }
  
  .stat-value {
    font-size: clamp(28px, 2.08vw, 40px);
  }
  
  .stat-label {
    font-size: clamp(11px, 0.73vw, 14px);
  }
}

@media (max-width: 1366px) {
  .antrian-display-container {
    padding: 16px;
  }

  .display-header {
    padding: 16px 24px;
  }

  .logo-circle {
    width: 64px;
    height: 64px;
  }

  .logo-circle .v-icon {
    font-size: 40px !important;
  }

  .hospital-name {
    font-size: 36px;
  }

  .display-subtitle {
    font-size: 16px;
  }

  .time-large {
    font-size: 48px;
  }

  .date-small {
    font-size: 14px;
  }

  .hero-call-section {
    padding: 24px;
  }

  .call-label {
    font-size: 24px;
  }

  .call-number {
    font-size: 100px;
  }

  .call-clinic {
    font-size: 28px;
  }

  .clinics-grid {
    gap: 12px;
  }

  .clinic-box {
    min-height: 220px;
    padding: 0;
  }

  .clinic-header-bar {
    padding: 14px 16px;
  }

  .clinic-title {
    font-size: 20px;
  }

  .clinic-content {
    padding: 16px;
  }

  .current-number {
    font-size: 72px;
  }

  .tipe-label {
    font-size: 18px;
    padding: 6px 10px;
  }

  .next-item {
    font-size: 20px;
    padding: 6px 14px;
  }

  .footer-stats-bar {
    padding: 16px 32px;
  }

  .stat-icon {
    width: 56px;
    height: 56px;
  }

  .stat-icon .v-icon {
    font-size: 28px !important;
  }

  .stat-value {
    font-size: 36px;
  }

  .stat-label {
    font-size: 13px;
  }

  .stat-divider {
    height: 50px;
  }

  .footer-message {
    font-size: 18px;
  }
}

@media (max-width: 1024px) {
  .display-header {
    flex-direction: column;
    gap: 16px;
    text-align: center;
  }

  .header-left {
    flex-direction: column;
    gap: 12px;
  }

  .datetime-display {
    text-align: center;
  }

  .clinics-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .footer-stats-bar {
    flex-direction: column;
    gap: 16px;
  }

  .stat-divider {
    display: none;
  }

  .footer-message {
    text-align: center;
    justify-content: center;
  }
}

@media (max-width: 768px) {
  .clinics-grid {
    grid-template-columns: 1fr;
  }

  .hospital-name {
    font-size: 28px;
  }

  .time-large {
    font-size: 36px;
  }

  .call-number {
    font-size: 80px;
  }

  .current-number {
    font-size: 60px;
  }
}

/* Prevent text selection */
* {
  user-select: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
</style>

