package systemUtils

import (
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"time"

	"server/internal/tsgenerator"

	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/fiber/v3/middleware/static"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

const spaDistPath = "http/static/spa"

// Typescript: interface
type MailDebugItem struct {
	Name    string `json:"name"`
	Content string `json:"content"`
}

// healthHandler returns a simple application health status.
func healthHandler(c fiber.Ctx) error {
	return c.JSON(fiber.Map{
		"data":  fiber.Map{"status": "ok", "ts": time.Now().UTC()},
		"error": nil,
	})
}

func RegisterSystemRoutes(app *fiber.App) {
	app.Get("/favicon.ico", func(c fiber.Ctx) error {
		return c.SendString("boo")
	})

	// Typescript: TSEndpoint= path=/health; name=health; method=GET; response=string
	app.Get("/health", healthHandler)

	// Typescript: TSEndpoint= path=/metrics;  name=metrics; method=GET; response=string
	app.Get("/metrics", promhttp.Handler())

	app.Get("/tsgenerate", func(c fiber.Ctx) error {
		ts, err := tsgenerator.TsGenerate()
		if err != nil {
			return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
		}
		c.Set(fiber.HeaderContentType, "text/plain")
		return c.SendString(ts)
	})

	// Typescript: TSEndpoint= path=/maildebug; name=mailDebug; method=GET; response=[]MailDebugItem
	app.Get("/maildebug", func(c fiber.Ctx) error {
		entries, err := os.ReadDir("data/mail-debug")
		if err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"data":  nil,
				"error": fmt.Sprintf("failed to read mail-debug directory: %v", err),
			})
		}

		items := make([]MailDebugItem, 0, len(entries))
		for _, entry := range entries {
			if entry.IsDir() {
				continue
			}

			name := entry.Name()
			path := filepath.Join("data/mail-debug", name)
			b, err := os.ReadFile(path)
			if err != nil {
				return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
					"data":  nil,
					"error": fmt.Sprintf("failed to read mail file %s: %v", name, err),
				})
			}

			items = append(items, MailDebugItem{
				Name:    name,
				Content: string(b),
			})
		}

		sort.Slice(items, func(i, j int) bool {
			return items[i].Name < items[j].Name
		})

		return c.JSON(fiber.Map{
			"data":  items,
			"error": nil,
		})
	})

	app.Get("/", func(c fiber.Ctx) error {
		return c.SendFile(filepath.Join(spaDistPath, "index.html"))
	})

	app.Use("/", static.New(spaDistPath))
}
