package handlers

import (
	"context"
	"encoding/json"
	"net/http"
	"time"

	"crowdsec-dashy/internal/crowdsec"
)

// APIHandler serves the internal JSON API consumed by frontend JS.
type APIHandler struct {
	deps Deps
}

func NewAPIHandler(deps Deps) *APIHandler {
	return &APIHandler{deps: deps}
}

type statsResponse struct {
	Decisions int  `json:"decisions"`
	Alerts    int  `json:"alerts"`
	Bouncers  int  `json:"bouncers"`
	Machines  int  `json:"machines"`
	Healthy   bool `json:"healthy"`
}

type healthResponse struct {
	Healthy      bool `json:"healthy"`
	CLIAvailable bool `json:"cli_available"`
}

// Stats returns dashboard summary counts.
func (h *APIHandler) Stats(w http.ResponseWriter, r *http.Request) {
	ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second)
	defer cancel()

	decisions, _ := h.deps.LAPI.ListDecisions(ctx, crowdsec.DecisionFilter{Limit: 500})
	alerts, _ := h.deps.LAPI.ListAlerts(ctx, crowdsec.AlertFilter{Limit: 500})

	resp := statsResponse{
		Decisions: len(decisions),
		Alerts:    len(alerts),
		Healthy:   h.deps.LAPI.IsHealthy(ctx),
	}

	if h.deps.CLIAvailable {
		bouncers, _ := h.deps.CLI.ListBouncers(ctx)
		machines, _ := h.deps.CLI.ListMachines(ctx)
		resp.Bouncers = len(bouncers)
		resp.Machines = len(machines)
	}

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(resp); err != nil {
		http.Error(w, "internal error", http.StatusInternalServerError)
	}
}

// Health returns LAPI health and cscli availability.
func (h *APIHandler) Health(w http.ResponseWriter, r *http.Request) {
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(healthResponse{
		Healthy:      h.deps.LAPI.IsHealthy(ctx),
		CLIAvailable: h.deps.CLIAvailable,
	}); err != nil {
		http.Error(w, "internal error", http.StatusInternalServerError)
	}
}
