package handlers

import (
	"bufio"
	"fmt"
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/tapper/backend/services"
)

func MatchSSE(c *fiber.Ctx) error {
	matchID := c.Params("id")
	if matchID == "" {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": "Match ID is required",
		})
	}

	c.Set("Content-Type", "text/event-stream")
	c.Set("Cache-Control", "no-cache")
	c.Set("Connection", "keep-alive")
	c.Set("Transfer-Encoding", "chunked")
	c.Set("Access-Control-Allow-Origin", "*")

	client := &services.SSEClient{
		MatchID: matchID,
		Ch:      make(chan string, 64),
	}
	services.RegisterSSEClient(client)

	c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
		defer services.UnregisterSSEClient(client)

		fmt.Fprintf(w, "event: connected\ndata: {\"match_id\":\"%s\"}\n\n", matchID)
		w.Flush()

		keepAlive := time.NewTicker(30 * time.Second)
		defer keepAlive.Stop()

		for {
			select {
			case msg, ok := <-client.Ch:
				if !ok {
					return
				}
				fmt.Fprint(w, msg)
				if err := w.Flush(); err != nil {
					return
				}
			case <-keepAlive.C:
				fmt.Fprint(w, ": keepalive\n\n")
				if err := w.Flush(); err != nil {
					return
				}
			}
		}
	})

	return nil
}

func AdminStatsSSE(c *fiber.Ctx) error {
	c.Set("Content-Type", "text/event-stream")
	c.Set("Cache-Control", "no-cache")
	c.Set("Connection", "keep-alive")
	c.Set("Transfer-Encoding", "chunked")
	c.Set("Access-Control-Allow-Origin", "*")

	c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
		ticker := time.NewTicker(5 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				metrics := services.GetSystemMetrics()
				data := fmt.Sprintf(`{"goroutines":%d,"alloc_mb":%.1f,"sys_mb":%.1f,"num_gc":%d,"uptime":"%s"}`,
					metrics.GoRoutines, metrics.AllocMB, metrics.SysMB, metrics.NumGC, metrics.Uptime)
				fmt.Fprintf(w, "event: system_metrics\ndata: %s\n\n", data)
				if err := w.Flush(); err != nil {
					return
				}
			}
		}
	})

	return nil
}

func OwnerSystemSSE(c *fiber.Ctx) error {
	c.Set("Content-Type", "text/event-stream")
	c.Set("Cache-Control", "no-cache")
	c.Set("Connection", "keep-alive")
	c.Set("Transfer-Encoding", "chunked")
	c.Set("Access-Control-Allow-Origin", "*")

	c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
		ticker := time.NewTicker(2 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				metrics := services.GetSystemMetrics()
				data := fmt.Sprintf(`{"hostname":"%s","goroutines":%d,"alloc_mb":%.1f,"total_alloc_mb":%.1f,"sys_mb":%.1f,"num_gc":%d,"uptime":"%s","num_cpu":%d}`,
					metrics.Hostname, metrics.GoRoutines, metrics.AllocMB, metrics.TotalAllocMB, metrics.SysMB, metrics.NumGC, metrics.Uptime, metrics.NumCPU)
				fmt.Fprintf(w, "event: system_metrics\ndata: %s\n\n", data)
				if err := w.Flush(); err != nil {
					return
				}
			}
		}
	})

	return nil
}
