"use client"

import { useEffect, useState } from "react"
import { resolveApiUrl, withAuthHeaders } from "@/shared/api/http-client"

export interface TrafficLiveSample {
  rxMbps: number
  txMbps: number
  at: string
}

function parseSseBlock(block: string): { event: string; data: string } {
  let event = "message"
  const dataLines: string[] = []
  for (const line of block.split("\n")) {
    if (line.startsWith("event:")) event = line.slice(6).trim()
    else if (line.startsWith("data:")) dataLines.push(line.slice(5).trim())
  }
  return { event, data: dataLines.join("\n") }
}

export function useTrafficLive(opts: {
  enabled: boolean
  backendUrl: string
  serverId: string
  iface: string
}): { sample: TrafficLiveSample | null; error: string | null } {
  const [sample, setSample] = useState<TrafficLiveSample | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    if (!opts.enabled || !opts.serverId) {
      setSample(null)
      setError(null)
      return
    }

    const ac = new AbortController()
    setSample(null)
    setError(null)
    const ifaceQ =
      opts.iface && opts.iface !== "__all__"
        ? `?iface=${encodeURIComponent(opts.iface)}`
        : ""
    const path = `/api/traffic/servers/${encodeURIComponent(opts.serverId)}/live${ifaceQ}`
    const url = resolveApiUrl(opts.backendUrl, path)

    let buf = ""
    setError(null)

    void (async () => {
      try {
        const res = await fetch(url, {
          headers: withAuthHeaders({ Accept: "text/event-stream" }),
          signal: ac.signal,
          credentials: "include",
        })
        if (!res.ok || !res.body) {
          setError(`live HTTP ${res.status}`)
          return
        }
        const reader = res.body.getReader()
        const decoder = new TextDecoder()
        while (!ac.signal.aborted) {
          const { done, value } = await reader.read()
          if (done) break
          buf += decoder.decode(value, { stream: true })
          const parts = buf.split("\n\n")
          buf = parts.pop() ?? ""
          for (const raw of parts) {
            if (!raw.trim() || raw.trim().startsWith(":")) continue
            const ev = parseSseBlock(raw)
            if (ev.event === "sample" && ev.data) {
              const parsed = JSON.parse(ev.data) as TrafficLiveSample
              setSample(parsed)
              setError(null)
            } else if (ev.event === "error" && ev.data) {
              const parsed = JSON.parse(ev.data) as { error?: string }
              setError(parsed.error ?? "live error")
            }
          }
        }
      } catch (e) {
        if (ac.signal.aborted) return
        setError(e instanceof Error ? e.message : "live error")
      }
    })()

    return () => ac.abort()
  }, [opts.enabled, opts.backendUrl, opts.serverId, opts.iface])

  return { sample, error }
}
