package api

import (
	"net/http"

	"github.com/pulse-lets-go/internal/models"
)

// handleRoute — GET /api/route — главный эндпоинт маршрутизации вызова.
func (a *API) handleRoute(w http.ResponseWriter, r *http.Request) {
	a.engine.IncrementRouteRequests()

	nodeID, score, fallback := a.engine.GetBestNode()

	// Нет зарегистрированных нод
	if nodeID == "" {
		writeJSON(w, http.StatusServiceUnavailable, models.RouteResponse{
			Error: "no_nodes_registered",
		})
		return
	}

	// Все ноды unhealthy — fallback
	if fallback || score < 0 {
		fallbackGW, _ := a.findFallbackGateway()
		nodes := a.getRouteNodeInfo()

		writeJSON(w, http.StatusOK, models.RouteResponse{
			Fallback:   true,
			SIPGateway:  fallbackGW,
			Reason:     "all_nodes_unhealthy",
			Nodes:      nodes,
		})
		return
	}

	// Нормальный маршрут
	gw, ok := a.findBalanceGateway(nodeID)
	if !ok {
		writeError(w, http.StatusInternalServerError, "gateway не найден для ноды")
		return
	}

	writeJSON(w, http.StatusOK, models.RouteResponse{
		NodeID:     nodeID,
		Score:      score,
		SIPGateway: gw,
	})
}

// findBalanceGateway ищет gateway для balance-транка, привязанного к nodeID.
func (a *API) findBalanceGateway(nodeID string) (string, bool) {
	trunks, err := a.configManager.ReadTrunks()
	if err != nil {
		return "", false
	}
	for _, t := range trunks {
		if t.Type == models.TrunkBalance && t.NodeID == nodeID && t.Enabled {
			return t.Gateway, true
		}
	}
	return "", false
}

// findFallbackGateway ищет gateway для fallback-транка.
func (a *API) findFallbackGateway() (string, bool) {
	trunks, err := a.configManager.ReadTrunks()
	if err != nil {
		return "", false
	}
	for _, t := range trunks {
		if t.Type == models.TrunkFallback && t.Enabled {
			return t.Gateway, true
		}
	}
	return "", false
}

// getRouteNodeInfo возвращает список нод с их скорами для ответа маршрутизации.
func (a *API) getRouteNodeInfo() []models.RouteNodeInfo {
	nodes := a.engine.GetAllNodes()
	result := make([]models.RouteNodeInfo, 0, len(nodes))
	for _, n := range nodes {
		info := models.RouteNodeInfo{
			ID:     n.NodeID,
			Score:  n.Score,
			Reason: n.LethalReason,
			Status: n.Status,
		}
		if n.Disabled {
			info.Status = "disabled"
		} else if n.IsStale {
			info.Status = "stale"
		} else if n.Score < 0 {
			info.Status = "unhealthy"
		} else {
			info.Status = "healthy"
		}
		result = append(result, info)
	}
	return result
}
