package router

import (
	"fmt"
	"strings"

	"github.com/treytartt/honeydue-api/internal/monitoring"
)

// CorsOrigins returns the CORS allowed origins based on debug mode.
func CorsOrigins(debug bool, configuredOrigins []string) []string {
	if debug {
		return []string{
			"http://localhost:3000",
			"http://localhost:3001",
			"http://localhost:8080",
			"http://localhost:8000",
			"http://127.0.0.1:3000",
			"http://127.0.0.1:3001",
			"http://127.0.0.1:8080",
			"http://127.0.0.1:8000",
		}
	}
	if len(configuredOrigins) > 0 {
		return configuredOrigins
	}
	return []string{
		"https://api.myhoneydue.com",
		"https://myhoneydue.com",
		"https://admin.myhoneydue.com",
	}
}

// ShouldSkipTimeout returns true for paths that should bypass timeout middleware.
func ShouldSkipTimeout(path, host, adminHost string) bool {
	return (adminHost != "" && host == adminHost) ||
		strings.HasPrefix(path, "/_next") ||
		strings.HasSuffix(path, "/ws")
}

// ShouldSkipBodyLimit returns true for webhook endpoints.
func ShouldSkipBodyLimit(path string) bool {
	return strings.HasPrefix(path, "/api/subscription/webhook")
}

// ShouldSkipGzip returns true for media endpoints.
func ShouldSkipGzip(path string) bool {
	return strings.HasPrefix(path, "/api/media/")
}

// ParseEndpoint splits "GET /api/foo" into method and path.
func ParseEndpoint(endpoint string) (method, path string) {
	parts := strings.SplitN(endpoint, " ", 2)
	if len(parts) == 2 {
		return parts[0], parts[1]
	}
	return endpoint, ""
}

// AllowedProxyHosts builds the list of hosts allowed for admin proxy.
func AllowedProxyHosts(adminHost string) []string {
	var hosts []string
	if adminHost != "" {
		hosts = append(hosts, adminHost)
	}
	hosts = append(hosts, "localhost:3001", "127.0.0.1:3001", "localhost:8000", "127.0.0.1:8000")
	return hosts
}

// DetermineAdminRoute decides how to route admin subdomain requests.
func DetermineAdminRoute(path string) string {
	if strings.HasPrefix(path, "/admin") {
		return "redirect"
	}
	if strings.HasPrefix(path, "/api/") {
		return "passthrough"
	}
	return "proxy"
}

// FormatPrometheusMetrics converts HTTP stats to Prometheus text format.
func FormatPrometheusMetrics(stats monitoring.HTTPStats) string {
	var b strings.Builder

	b.WriteString("# HELP http_requests_total Total number of HTTP requests.\n")
	b.WriteString("# TYPE http_requests_total counter\n")
	for statusCode, count := range stats.ByStatusCode {
		fmt.Fprintf(&b, "http_requests_total{status_code=\"%d\"} %d\n", statusCode, count)
	}

	b.WriteString("# HELP http_endpoint_requests_total Total requests per endpoint.\n")
	b.WriteString("# TYPE http_endpoint_requests_total counter\n")
	for endpoint, epStats := range stats.ByEndpoint {
		method, path := ParseEndpoint(endpoint)
		fmt.Fprintf(&b, "http_endpoint_requests_total{method=\"%s\",path=\"%s\"} %d\n", method, path, epStats.Count)
	}

	b.WriteString("# HELP http_request_duration_ms Average request duration in milliseconds per endpoint.\n")
	b.WriteString("# TYPE http_request_duration_ms gauge\n")
	for endpoint, epStats := range stats.ByEndpoint {
		method, path := ParseEndpoint(endpoint)
		fmt.Fprintf(&b, "http_request_duration_ms{method=\"%s\",path=\"%s\",quantile=\"avg\"} %.2f\n", method, path, epStats.AvgLatencyMs)
		fmt.Fprintf(&b, "http_request_duration_ms{method=\"%s\",path=\"%s\",quantile=\"p95\"} %.2f\n", method, path, epStats.P95LatencyMs)
	}

	b.WriteString("# HELP http_error_rate Overall error rate (4xx+5xx / total).\n")
	b.WriteString("# TYPE http_error_rate gauge\n")
	fmt.Fprintf(&b, "http_error_rate %.4f\n", stats.ErrorRate)

	b.WriteString("# HELP http_requests_per_minute Current request rate.\n")
	b.WriteString("# TYPE http_requests_per_minute gauge\n")
	fmt.Fprintf(&b, "http_requests_per_minute %.2f\n", stats.RequestsPerMinute)

	return b.String()
}
