package dashboard

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

	"hyapp-admin-server/internal/config"
)

func TestAslanHTTPDashboardSourceStatisticsOverview(t *testing.T) {
	requestedDates := map[string]bool{}
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Authorization") != "" {
			t.Fatalf("aslan dashboard request should not send authorization header")
		}
		if r.URL.Path != "/console/datav/aslan/region-country/statistics" {
			t.Fatalf("unexpected path: %s", r.URL.Path)
		}
		statDay := r.URL.Query().Get("date")
		requestedDates[statDay] = true
		w.Header().Set("Content-Type", "application/json")
		switch statDay {
		case "2026-06-30":
			_ = json.NewEncoder(w).Encode([]map[string]any{{
				"date":              "2026-06-30",
				"regionId":          "legacy-middle-east",
				"regionCode":        "MIDDLE_EAST",
				"regionName":        "中东区",
				"dailyRecharge":     "111.25",
				"dailyActive":       14,
				"dailyRegister":     4,
				"goldBalance":       1300,
				"hostSalaryBalance": "190.50",
				"countries": []map[string]any{
					{"countryCode": "SA", "countryName": "Saudi Arabia", "dailyRecharge": "100.25", "dailyActive": 12, "dailyRegister": 3, "goldBalance": 1000, "hostSalaryBalance": "150.50"},
					{"countryCode": "AE", "countryName": "United Arab Emirates", "dailyRecharge": "11.00", "dailyActive": 2, "dailyRegister": 1, "goldBalance": 300, "hostSalaryBalance": "40.00"},
				},
			}})
		case "2026-06-29":
			_ = json.NewEncoder(w).Encode(map[string]any{"data": []map[string]any{{
				"date":              "2026-06-29",
				"regionId":          "legacy-middle-east",
				"regionCode":        "MIDDLE_EAST",
				"regionName":        "中东区",
				"dailyRecharge":     "50.00",
				"dailyActive":       10,
				"dailyRegister":     2,
				"goldBalance":       800,
				"hostSalaryBalance": "100.00",
				"countries": []map[string]any{
					{"countryCode": "SA", "countryName": "Saudi Arabia", "dailyRecharge": "50.00", "dailyActive": 10, "dailyRegister": 2, "goldBalance": 800, "hostSalaryBalance": "100.00"},
				},
			}}})
		default:
			t.Fatalf("unexpected date: %s", statDay)
		}
	}))
	defer server.Close()

	source, err := NewAslanHTTPDashboardSource(config.DashboardExternalSourceConfig{
		Enabled:        true,
		SourceType:     "aslan_http",
		AppCode:        "aslan",
		AppName:        "Aslan",
		BaseURL:        server.URL,
		OverviewPath:   "/console/datav/aslan/region-country/statistics",
		StatTimezone:   "Asia/Shanghai",
		RequestTimeout: time.Second,
	}, staticDashboardRegionResolver{appCode: "aslan", regionID: 1001, countryCodes: []string{"SA"}})
	if err != nil {
		t.Fatalf("build source: %v", err)
	}
	shanghai, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		t.Fatalf("load location: %v", err)
	}
	start := time.Date(2026, 6, 30, 0, 0, 0, 0, shanghai)
	overview, err := source.StatisticsOverview(context.Background(), StatisticsQuery{
		AppCode:  "aslan",
		StatTZ:   "Asia/Shanghai",
		StartMS:  start.UnixMilli(),
		EndMS:    start.AddDate(0, 0, 1).UnixMilli(),
		RegionID: 1001,
	})
	if err != nil {
		t.Fatalf("StatisticsOverview: %v", err)
	}
	if !requestedDates["2026-06-30"] || !requestedDates["2026-06-29"] {
		t.Fatalf("date requests mismatch: %#v", requestedDates)
	}
	assertEqual(t, overview["app_code"], "aslan")
	assertEqual(t, overview["stat_tz"], "Asia/Shanghai")
	assertInt64(t, overview["recharge_usd_minor"], 10_025)
	assertInt64(t, overview["active_users"], 12)
	assertInt64(t, overview["new_users"], 3)
	assertInt64(t, overview["registered_users"], 3)
	assertInt64(t, overview["coin_total"], 1_000)
	assertInt64(t, overview["salary_usd_minor"], 15_050)
	assertInt64(t, overview["arpu_usd_minor"], 835)
	if overview["paid_users"] != nil || overview["recharge_users"] != nil || overview["arppu_usd_minor"] != nil {
		t.Fatalf("aslan payer fields should be nil when the remote API does not return payer counts: %#v", overview)
	}

	countries, ok := overview["country_breakdown"].([]map[string]any)
	if !ok || len(countries) != 1 {
		t.Fatalf("country_breakdown mismatch: %#v", overview["country_breakdown"])
	}
	assertEqual(t, countries[0]["country_code"], "SA")
	assertEqual(t, countries[0]["region_id"], int64(1001))
	assertInt64(t, countries[0]["recharge_usd_minor"], 10_025)

	sources, ok := overview["report_metric_sources"].([]map[string]any)
	if !ok {
		t.Fatalf("report_metric_sources mismatch: %#v", overview["report_metric_sources"])
	}
	assertMetricSourceUnavailable(t, sources, "arppu_usd_minor")
	assertMetricSourceUnavailable(t, sources, "paid_users")
	assertMetricSourceUnavailable(t, sources, "recharge_users")
	assertMetricSourceUnavailable(t, sources, "game_turnover")
	assertMetricSourceUnavailable(t, sources, "retention.day1_rate")
}
