package server

import (
	"fmt"
	"net/http"
	"os"
	"time"

	"gophergate/internal/db"

	"github.com/gin-gonic/gin"

	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/disk"
	"github.com/shirou/gopsutil/v3/load"
	"github.com/shirou/gopsutil/v3/mem"
	"github.com/shirou/gopsutil/v3/process"
)

func (s *Server) handleSystemHealth(c *gin.Context) {
	c.JSON(http.StatusOK, SuccessResponse(gin.H{
		"status": "ok",
		"components": gin.H{
			"database": "online",
			"proxy":    "online",
		},
	}))
}

func (s *Server) handleSystemMetrics(c *gin.Context) {
	v, _ := mem.VirtualMemory()
	c_usage, _ := cpu.Percent(time.Second, false)
	d, _ := disk.Usage("/")
	l, _ := load.Avg()
	p, _ := process.NewProcess(int32(os.Getpid()))
	rss, _ := p.MemoryInfo()

	cpuPercent := 0.0
	if len(c_usage) > 0 {
		cpuPercent = c_usage[0]
	}

	c.JSON(http.StatusOK, SuccessResponse(gin.H{
		"cpu": gin.H{
			"usage_percent": fmt.Sprintf("%.1f", cpuPercent),
			"load_average":  []float64{l.Load1, l.Load5, l.Load15},
		},
		"memory": gin.H{
			"used_mb":        v.Used / 1024 / 1024,
			"total_mb":       v.Total / 1024 / 1024,
			"usage_percent":  fmt.Sprintf("%.1f", v.UsedPercent),
			"process_rss_mb": rss.RSS / 1024 / 1024,
		},
		"disk": gin.H{
			"used_gb":       float64(d.Used) / 1024 / 1024 / 1024,
			"total_gb":      float64(d.Total) / 1024 / 1024 / 1024,
			"usage_percent": fmt.Sprintf("%.1f", d.UsedPercent),
		},
		"connections": gin.H{
			"db_active":           s.database.Stats().OpenConnections,
			"websocket_listeners": s.hub.GetClientCount(),
		},
	}))
}

func (s *Server) handleGetSettings(c *gin.Context) {
	providerCount := 0
	modelCount := 0
	s.registryMu.RLock()
	if s.registry != nil {
		providerCount = len(s.registry.Providers)
		for _, p := range s.registry.Providers {
			modelCount += len(p.Models)
		}
	}

	c.JSON(http.StatusOK, SuccessResponse(gin.H{
		"server": gin.H{
			"version":     "1.0.0-go",
			"auth_tokens": s.cfg.Server.AuthTokens,
		},
		"database": gin.H{
			"type": "sqlite",
			"path": s.cfg.Database.Path,
		},
		"registry": gin.H{
			"provider_count": providerCount,
			"model_count":    modelCount,
		},
	}))
}

func (s *Server) handleCreateBackup(c *gin.Context) {
	// Simplified backup response
	c.JSON(http.StatusOK, SuccessResponse(gin.H{
		"backup_id": fmt.Sprintf("backup-%d.db", time.Now().Unix()),
		"status":    "created",
	}))
}

func (s *Server) handleGetLogs(c *gin.Context) {
	var logs []db.LLMRequest
	err := s.database.Select(&logs, "SELECT * FROM llm_requests ORDER BY timestamp DESC LIMIT 100")
	if err != nil {
		c.JSON(http.StatusInternalServerError, ErrorResponse(err.Error()))
		return
	}

	// Format for UI
	type UILog struct {
		Timestamp string `json:"timestamp"`
		ClientID  string `json:"client_id"`
		Provider  string `json:"provider"`
		Model     string `json:"model"`
		Tokens    int    `json:"tokens"`
		Status    string `json:"status"`
		Duration  int    `json:"duration"`
	}

	uiLogs := make([]UILog, len(logs))
	for i, l := range logs {
		clientID := "unknown"
		if l.ClientID != nil {
			clientID = *l.ClientID
		}
		provider := "unknown"
		if l.Provider != nil {
			provider = *l.Provider
		}
		model := "unknown"
		if l.Model != nil {
			model = *l.Model
		}
		tokens := 0
		if l.TotalTokens != nil {
			tokens = *l.TotalTokens
		}
		duration := 0
		if l.DurationMS != nil {
			duration = *l.DurationMS
		}

		uiLogs[i] = UILog{
			Timestamp: l.Timestamp.Format(time.RFC3339),
			ClientID:  clientID,
			Provider:  provider,
			Model:     model,
			Tokens:    tokens,
			Status:    l.Status,
			Duration:  duration,
		}
	}

	c.JSON(http.StatusOK, SuccessResponse(uiLogs))
}
