package rest_test

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/prometheus/client_golang/prometheus/testutil"

	"github.com/pingcap/agent-git-service/internal/metrics"
	"github.com/pingcap/agent-git-service/internal/rest"
	"github.com/pingcap/agent-git-service/internal/tenant"
)

const analyticsTenantID tenant.ID = "tenant-a"

func analyticsTenantRequest(req *http.Request) *http.Request {
	return req.WithContext(tenant.WithInfo(req.Context(), tenant.Info{
		ID:               analyticsTenantID,
		CanonicalBaseURL: "https://tenant-a.example.test",
	}))
}

func TestCreateAnalyticsEvents_RecordsPrometheusMetric(t *testing.T) {
	metrics.Init()
	deps := &rest.Deps{}

	body := map[string]any{
		"event_name":      "install_command_copied",
		"source":          "landing_page",
		"path":            "/",
		"button_id":       "hero-claude-install-flow",
		"success":         true,
		"utm_source":      "twitter",
		"referrer_domain": "x.com",
	}
	payload, _ := json.Marshal(body)

	counter := metrics.DefaultPrometheus().FrontendEventsTotal.WithLabelValues(
		string(analyticsTenantID),
		"install_copy",
		"landing_page",
		"home",
		"claude_code",
		"hero",
		"true",
		"twitter",
	)
	before := testutil.ToFloat64(counter)

	req := analyticsTenantRequest(httptest.NewRequest(http.MethodPost, "/api/ext/v1/analytics/events", bytes.NewReader(payload)))
	w := httptest.NewRecorder()

	deps.CreateAnalyticsEvents(w, req)

	if w.Code != http.StatusAccepted {
		t.Fatalf("expected 202, got %d: %s", w.Code, w.Body.String())
	}
	after := testutil.ToFloat64(counter)
	if after != before+1 {
		t.Fatalf("expected frontend event counter to increase by 1, before=%v after=%v", before, after)
	}
}

func TestCreateAnalyticsEvents_BatchRecordsBlogPageView(t *testing.T) {
	metrics.Init()
	deps := &rest.Deps{}

	body := map[string]any{
		"events": []map[string]any{
			{
				"event_name":      "page_view",
				"path":            "/blog/introducing-clawmem/",
				"referrer_domain": "google.com",
			},
		},
	}
	payload, _ := json.Marshal(body)

	counter := metrics.DefaultPrometheus().FrontendEventsTotal.WithLabelValues(
		string(analyticsTenantID),
		"page_view",
		"blog",
		"blog_introducing_clawmem",
		"unknown",
		"unknown",
		"unknown",
		"organic",
	)
	before := testutil.ToFloat64(counter)

	req := analyticsTenantRequest(httptest.NewRequest(http.MethodPost, "/api/ext/v1/analytics/events", bytes.NewReader(payload)))
	w := httptest.NewRecorder()

	deps.CreateAnalyticsEvents(w, req)

	if w.Code != http.StatusAccepted {
		t.Fatalf("expected 202, got %d: %s", w.Code, w.Body.String())
	}
	after := testutil.ToFloat64(counter)
	if after != before+1 {
		t.Fatalf("expected blog page view counter to increase by 1, before=%v after=%v", before, after)
	}
}

func TestCreateAnalyticsEvents_RejectsMissingEventName(t *testing.T) {
	deps := &rest.Deps{}
	req := analyticsTenantRequest(httptest.NewRequest(http.MethodPost, "/api/ext/v1/analytics/events", bytes.NewReader([]byte(`{"path":"/"}`))))
	w := httptest.NewRecorder()

	deps.CreateAnalyticsEvents(w, req)

	if w.Code != http.StatusUnprocessableEntity {
		t.Fatalf("expected 422, got %d: %s", w.Code, w.Body.String())
	}
}
