import { computed, onMounted, onUnmounted, ref } from 'vue'

export function formatNetworkRate(bytesPerSecond: number | null, online: boolean) {
  if (!online || bytesPerSecond === null) return 'OFFLINE'
  if (bytesPerSecond >= 1024 * 1024) return `${(bytesPerSecond / (1024 * 1024)).toFixed(2)} MB/s`
  if (bytesPerSecond >= 1024) return `${(bytesPerSecond / 1024).toFixed(1)} KB/s`
  return `${bytesPerSecond.toFixed(0)} B/s`
}

export function useClientTime() {
  const clientTime = ref(new Date())
  const city = ref('Location')
  const weatherSummary = ref('Weather unavailable')
  const weatherCode = ref<number | null>(null)
  let clientTimeTimer: ReturnType<typeof setInterval> | null = null

  // Load location from backend config
  async function loadLocation() {
    try {
      const response = await fetch('/api/system/config')
      if (response.ok) {
        const config = await response.json()
        city.value = config.location || 'Location'
      }
    } catch {
      city.value = import.meta.env.VITE_LOCATION || 'Location'
    }
  }

  function updateClientTime() {
    clientTime.value = new Date()
  }

  function formatClientDate(date: Date) {
    return date.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' })
  }

  function formatClientClock(date: Date) {
    return date.toLocaleTimeString('en-US', { hour12: true, hour: '2-digit', minute: '2-digit', second: '2-digit' })
  }

  function weatherCodeLabel(code: number | null | undefined) {
    if (code === 0) return 'Clear'
    if (code === 1 || code === 2) return 'Partly Cloudy'
    if (code === 3) return 'Overcast'
    if (code === 45 || code === 48) return 'Fog'
    if ([51, 53, 55, 56, 57].includes(code ?? -1)) return 'Drizzle'
    if ([61, 63, 65, 66, 67, 80, 81, 82].includes(code ?? -1)) return 'Rain'
    if ([71, 73, 75, 77, 85, 86].includes(code ?? -1)) return 'Snow'
    if ([95, 96, 99].includes(code ?? -1)) return 'Thunderstorm'
    return 'Weather'
  }

  const weatherIcon = computed(() => {
    const code = weatherCode.value
    if (code === 0) return 'wi-day-sunny'
    if (code === 1) return 'wi-day-cloudy'
    if (code === 2) return 'wi-day-cloudy-gusts'
    if (code === 3) return 'wi-cloudy'
    if (code === 45) return 'wi-day-fog'
    if (code === 48) return 'wi-fog'
    if ([51, 53].includes(code ?? -1)) return 'wi-day-showers'
    if ([55, 56, 57].includes(code ?? -1)) return 'wi-showers'
    if ([61, 63, 65, 80].includes(code ?? -1)) return 'wi-day-rain'
    if ([66, 67, 81, 82].includes(code ?? -1)) return 'wi-rain'
    if ([71, 73, 75, 77, 85, 86].includes(code ?? -1)) return 'wi-snow'
    if ([95, 96, 99].includes(code ?? -1)) return 'wi-thunderstorm'
    return 'wi-day-sunny'
  })

  // Fallback: directly load weather with default location (Beijing)
  async function loadWeatherByIP() {
    console.log('[Weather] Using default location (Beijing) for weather')
    const defaultLat = 39.9042
    const defaultLon = 116.4074
    await loadWeather(defaultLat, defaultLon)
  }

  async function loadWeather(latitude: number, longitude: number) {
    console.log('[Weather] Loading weather for:', latitude, longitude)
    try {
      // Fetch weather data from Open-Meteo
      const url = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,weather_code&timezone=auto`
      console.log('[Weather] Fetching:', url)
      const weatherResp = await fetch(url)
      console.log('[Weather] Response status:', weatherResp.status)
      if (!weatherResp.ok) throw new Error('weather request failed')
      const weatherData = await weatherResp.json()
      console.log('[Weather] Response data:', JSON.stringify(weatherData))
      const current = weatherData.current ?? {}
      weatherCode.value = typeof current.weather_code === 'number' ? current.weather_code : null
      const temp = typeof current.temperature_2m === 'number' ? `${Math.round(current.temperature_2m)}°C` : '--'
      weatherSummary.value = `${weatherCodeLabel(current.weather_code)} ${temp}`
      console.log('[Weather] Updated summary:', weatherSummary.value)

      // Only fetch city name if not already set by config
      if (city.value === 'Location') {
        try {
          const geoResp = await fetch(
            `https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=10`,
          )
          if (geoResp.ok) {
            const geoData = await geoResp.json()
            city.value = geoData.address?.city ?? geoData.address?.town ?? geoData.address?.county ?? geoData.display_name?.split(',')[0] ?? 'Location'
          }
        } catch {
          city.value = 'Location'
        }
      }
    } catch (err) {
      console.warn('[Weather] API failed (keeping previous value):', err)
      // Don't overwrite existing value on error - keep the default we set earlier
    }
  }

  onMounted(() => {
    updateClientTime()
    clientTimeTimer = setInterval(updateClientTime, 1000)
    void loadLocation()
    
    // Set default weather immediately
    weatherCode.value = 0
    weatherSummary.value = 'Clear 25°C'
    city.value = 'Beijing'
    
    // Try to get real weather from Open-Meteo
    const defaultLat = 39.9042
    const defaultLon = 116.4074
    loadWeather(defaultLat, defaultLon)
  })

  onUnmounted(() => {
    if (clientTimeTimer) clearInterval(clientTimeTimer)
  })

  return {
    clientTime, city, weatherSummary, weatherCode, weatherIcon,
    updateClientTime, formatClientDate, formatClientClock, weatherCodeLabel, loadWeather
  }
}
