<template>
  <div class="app-layout">
    <SidebarNav />
    
    <div class="main-content">
      <header class="main-header">
        <h1 class="page-title">📊 대시보드</h1>
        <div class="header-info">
          <span class="current-time">{{ currentTime }}</span>
          <ThemeToggle />
        </div>
      </header>
      
      <main class="main-body">
        <DashboardControl
          :interval="interval"
          :auto-refresh="autoRefresh"
          :last-fetch-time="lastFetchTime"
          :fetch-state="fetchState"
          @update:interval="updateInterval"
          @update:auto-refresh="updateAutoRefresh"
          @fetch-at="fetchAt"
          @refresh="refresh"
        />
        
        <div class="dashboard-layout">
          <!-- 서버 현황 (좌측 90%) -->
          <div class="server-section">
            <ServerPortlet
              v-if="serverDashboard"
              :servers="serverDashboard.servers"
              :summary="serverDashboard.summary"
              @navigate="navigateTo"
            />
          </div>
          
          <!-- 네트워크 상태 (우측 10%) -->
          <div class="network-section">
            <NetworkPortlet
              type="pubnet"
              title="Public"
              icon="🌐"
              :status="pubnetStatus"
            />
            <NetworkPortlet
              type="privnet"
              title="Private"
              icon="🔒"
              :status="privnetStatus"
            />
            <LocationStatsPortlet
              :locations="locationStats"
            />
          </div>
        </div>
      </main>
    </div>
    
    <div class="connection-status" :class="{ connected: wsConnected }">
      {{ wsConnected ? '🟢 연결됨' : '🔴 연결 끊김' }}
    </div>
  </div>
</template>

<script setup lang="ts">
const router = useRouter()

// 초기값 상수
const DEFAULT_INTERVAL = 1
const DEFAULT_AUTO_REFRESH = true
const MIN_LOADING_TIME = 500
const SUCCESS_DISPLAY_TIME = 800

// 상태
const interval = ref(DEFAULT_INTERVAL)
const autoRefresh = ref(DEFAULT_AUTO_REFRESH)
const wsConnected = ref(false)
const currentTime = ref('')
const lastFetchTime = ref<Date | null>(null)
const fetchState = ref<'idle' | 'loading' | 'success'>('idle')

// 로딩 타이밍 관리
let loadingStartTime = 0

// 데이터
const pubnetStatus = ref<any>(null)
const privnetStatus = ref<any>(null)
const serverDashboard = ref<any>(null)
const locationStats = ref<any[]>([])

// WebSocket
let ws: WebSocket | null = null
let timeInterval: ReturnType<typeof window.setInterval> | null = null

async function fetchLocationStats() {
  try {
    const data = await $fetch('/api/server/location-stats')
    locationStats.value = data as any[]
  } catch (err) {
    console.error('Failed to fetch location stats:', err)
  }
}

function formatTime(date: Date): string {
  const y = date.getFullYear()
  const m = String(date.getMonth() + 1).padStart(2, '0')
  const d = String(date.getDate()).padStart(2, '0')
  const h = String(date.getHours()).padStart(2, '0')
  const min = String(date.getMinutes()).padStart(2, '0')
  const s = String(date.getSeconds()).padStart(2, '0')
  return `${y}-${m}-${d} ${h}:${min}:${s}`
}

function updateCurrentTime() {
  currentTime.value = formatTime(new Date())
}

function sendMessage(msg: object) {
  if (ws && ws.readyState === WebSocket.OPEN) {
    console.log('[WS] Sending:', JSON.stringify(msg))
    ws.send(JSON.stringify(msg))
  }
}

function handleDataReceived(data: any) {
  lastFetchTime.value = new Date()
  
  if (data.pubnet) {
    pubnetStatus.value = data.pubnet.status
  }
  
  if (data.privnet) {
    privnetStatus.value = data.privnet.status
  }
}

function finishLoading() {
  fetchState.value = 'success'
  setTimeout(() => {
    fetchState.value = 'idle'
  }, SUCCESS_DISPLAY_TIME)
}

function connectWebSocket() {
  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
  const wsUrl = `${protocol}//${window.location.host}/_ws`
  
  ws = new WebSocket(wsUrl)
  
  ws.onopen = () => {
    console.log('[WS] Connected')
    wsConnected.value = true
    
    ws!.send(JSON.stringify({ type: 'set_interval', interval: DEFAULT_INTERVAL }))
    ws!.send(JSON.stringify({ type: 'set_auto_refresh', enabled: DEFAULT_AUTO_REFRESH }))
    ws!.send(JSON.stringify({ type: 'refresh' }))
  }
  
  ws.onmessage = (event) => {
    try {
      const msg = JSON.parse(event.data)
      
      if (msg.type === 'status' || msg.type === 'historical') {
        handleDataReceived(msg.data)
        
        if (fetchState.value === 'loading') {
          const elapsed = Date.now() - loadingStartTime
          const remaining = Math.max(0, MIN_LOADING_TIME - elapsed)
          
          setTimeout(() => {
            finishLoading()
          }, remaining)
        }
      }
      
      if (msg.type === 'server') {
        serverDashboard.value = msg.data
        fetchLocationStats()
      }
    } catch (err) {
      console.error('[WS] Parse error:', err)
      fetchState.value = 'idle'
    }
  }
  
  ws.onclose = () => {
    console.log('[WS] Disconnected')
    wsConnected.value = false
    fetchState.value = 'idle'
    
    setTimeout(() => {
      if (autoRefresh.value) {
        connectWebSocket()
      }
    }, 3000)
  }
  
  ws.onerror = (error) => {
    console.error('[WS] Error:', error)
    fetchState.value = 'idle'
  }
}

function updateInterval(min: number) {
  interval.value = min
  sendMessage({ type: 'set_interval', interval: min })
}

function updateAutoRefresh(enabled: boolean) {
  autoRefresh.value = enabled
  sendMessage({ type: 'set_auto_refresh', enabled })
}

function refresh() {
  sendMessage({ type: 'refresh' })
}

function fetchAt(datetime: string) {
  fetchState.value = 'loading'
  loadingStartTime = Date.now()
  sendMessage({ type: 'fetch_at', datetime })
}

function navigateTo(path: string) {
  router.push(path)
}

onMounted(() => {
  connectWebSocket()
  updateCurrentTime()
  fetchLocationStats()
  timeInterval = window.setInterval(updateCurrentTime, 1000)
})

onUnmounted(() => {
  if (ws) {
    ws.close()
  }
  if (timeInterval) {
    window.clearInterval(timeInterval)
  }
})
</script>


<style scoped>
.app-layout { display: flex; height: 100vh; background: var(--bg-primary); }
.main-content { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.main-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 24px; border-bottom: 1px solid var(--border-color); background: var(--bg-secondary); }
.page-title { margin: 0; font-size: 20px; font-weight: 600; color: var(--text-primary); }
.header-info { display: flex; align-items: center; gap: 16px; }
.current-time { font-size: 14px; color: var(--text-muted); font-family: monospace; }
.main-body { flex: 1; padding: 20px 24px; overflow-y: auto; }

.dashboard-layout { display: flex; gap: 16px; height: 100%; }
.server-section { flex: 9; min-width: 0; }
.network-section { flex: 1; min-width: 150px; max-width: 200px; display: flex; flex-direction: column; gap: 8px; }

.connection-status { position: fixed; bottom: 16px; right: 16px; padding: 8px 12px; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 8px; font-size: 12px; color: var(--text-muted); }
.connection-status.connected { color: #16a34a; }
</style>
