package router

import (
	"strings"
	"testing"

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

// --- CorsOrigins ---

func TestCorsOrigins_Debug(t *testing.T) {
	origins := CorsOrigins(true, nil)
	if len(origins) != 8 {
		t.Errorf("len = %d, want 8", len(origins))
	}
	found := false
	for _, o := range origins {
		if o == "http://localhost:3000" {
			found = true
		}
	}
	if !found {
		t.Error("expected localhost:3000 in debug origins")
	}
}

func TestCorsOrigins_ProductionConfigured(t *testing.T) {
	custom := []string{"https://example.com"}
	origins := CorsOrigins(false, custom)
	if len(origins) != 1 || origins[0] != "https://example.com" {
		t.Errorf("got %v, want [https://example.com]", origins)
	}
}

func TestCorsOrigins_ProductionDefault(t *testing.T) {
	origins := CorsOrigins(false, nil)
	if len(origins) != 3 {
		t.Errorf("len = %d, want 3", len(origins))
	}
	found := false
	for _, o := range origins {
		if o == "https://myhoneydue.com" {
			found = true
		}
	}
	if !found {
		t.Error("expected myhoneydue.com in default origins")
	}
}

// --- ShouldSkipTimeout ---

func TestShouldSkipTimeout_AdminHost_True(t *testing.T) {
	if !ShouldSkipTimeout("/some/path", "admin.example.com", "admin.example.com") {
		t.Error("expected true for admin host")
	}
}

func TestShouldSkipTimeout_NextPath_True(t *testing.T) {
	if !ShouldSkipTimeout("/_next/static/chunk.js", "app.example.com", "admin.example.com") {
		t.Error("expected true for _next path")
	}
}

func TestShouldSkipTimeout_WsPath_True(t *testing.T) {
	if !ShouldSkipTimeout("/api/events/ws", "app.example.com", "admin.example.com") {
		t.Error("expected true for /ws path")
	}
}

func TestShouldSkipTimeout_NormalPath_False(t *testing.T) {
	if ShouldSkipTimeout("/api/tasks/", "app.example.com", "admin.example.com") {
		t.Error("expected false for normal path")
	}
}

func TestShouldSkipTimeout_EmptyAdminHost_False(t *testing.T) {
	if ShouldSkipTimeout("/api/tasks/", "admin.example.com", "") {
		t.Error("expected false when admin host is empty")
	}
}

// --- ShouldSkipBodyLimit ---

func TestShouldSkipBodyLimit_Webhook_True(t *testing.T) {
	if !ShouldSkipBodyLimit("/api/subscription/webhook/apple/") {
		t.Error("expected true for webhook path")
	}
}

func TestShouldSkipBodyLimit_Normal_False(t *testing.T) {
	if ShouldSkipBodyLimit("/api/tasks/") {
		t.Error("expected false for normal path")
	}
}

// --- ShouldSkipGzip ---

func TestShouldSkipGzip_Media_True(t *testing.T) {
	if !ShouldSkipGzip("/api/media/document/123") {
		t.Error("expected true for media path")
	}
}

func TestShouldSkipGzip_Api_False(t *testing.T) {
	if ShouldSkipGzip("/api/tasks/") {
		t.Error("expected false for non-media path")
	}
}

// --- ParseEndpoint ---

func TestParseEndpoint_MethodAndPath(t *testing.T) {
	method, path := ParseEndpoint("GET /api/tasks/")
	if method != "GET" || path != "/api/tasks/" {
		t.Errorf("got (%q, %q), want (GET, /api/tasks/)", method, path)
	}
}

func TestParseEndpoint_NoSpace(t *testing.T) {
	method, path := ParseEndpoint("GET")
	if method != "GET" || path != "" {
		t.Errorf("got (%q, %q), want (GET, \"\")", method, path)
	}
}

// --- AllowedProxyHosts ---

func TestAllowedProxyHosts_WithAdmin(t *testing.T) {
	hosts := AllowedProxyHosts("admin.example.com")
	if len(hosts) != 5 {
		t.Errorf("len = %d, want 5", len(hosts))
	}
	if hosts[0] != "admin.example.com" {
		t.Errorf("first host = %q, want admin.example.com", hosts[0])
	}
}

func TestAllowedProxyHosts_WithoutAdmin(t *testing.T) {
	hosts := AllowedProxyHosts("")
	if len(hosts) != 4 {
		t.Errorf("len = %d, want 4", len(hosts))
	}
}

// --- DetermineAdminRoute ---

func TestDetermineAdminRoute_Admin_Redirect(t *testing.T) {
	got := DetermineAdminRoute("/admin/dashboard")
	if got != "redirect" {
		t.Errorf("got %q, want redirect", got)
	}
}

func TestDetermineAdminRoute_Api_Passthrough(t *testing.T) {
	got := DetermineAdminRoute("/api/tasks/")
	if got != "passthrough" {
		t.Errorf("got %q, want passthrough", got)
	}
}

func TestDetermineAdminRoute_Other_Proxy(t *testing.T) {
	got := DetermineAdminRoute("/dashboard")
	if got != "proxy" {
		t.Errorf("got %q, want proxy", got)
	}
}

// --- FormatPrometheusMetrics ---

func TestFormatPrometheusMetrics_Output(t *testing.T) {
	stats := monitoring.HTTPStats{
		RequestsTotal:     100,
		RequestsPerMinute: 10.5,
		ErrorRate:         0.05,
		ByStatusCode:      map[int]int64{200: 90, 500: 10},
		ByEndpoint: map[string]monitoring.EndpointStats{
			"GET /api/tasks/": {Count: 50, AvgLatencyMs: 12.5, P95LatencyMs: 45.0},
		},
	}

	output := FormatPrometheusMetrics(stats)

	// Check key sections exist
	checks := []string{
		"http_requests_total",
		"http_endpoint_requests_total",
		"http_request_duration_ms",
		"http_error_rate",
		"http_requests_per_minute",
		`method="GET"`,
		`path="/api/tasks/"`,
	}
	for _, check := range checks {
		if !strings.Contains(output, check) {
			t.Errorf("output missing %q", check)
		}
	}
}
