package web

import (
	"strings"
	"testing"
	"time"

	"gitea.dooplex.hu/admin/felhom-hub/internal/monitor"
	"gitea.dooplex.hu/admin/felhom-hub/internal/store"
)

const gib = int64(1) << 30

// Not configured (no HETZNER_TOKEN) → honest "not configured", never an error or fake zeros.
// (Uses renderOffsite from offsite_test.go — the real handler via httptest.)
func TestOffsiteBoxPanel_NotConfigured(t *testing.T) {
	s, _ := newRenderServer(t)
	// s.offsiteBox left nil
	body := renderOffsite(t, s)
	if !strings.Contains(body, "Offsite pool metrics not configured") {
		t.Fatalf("unconfigured panel must say 'not configured':\n%s", body)
	}
	if strings.Contains(body, "0.0 GB") {
		t.Fatal("unconfigured panel must not render fake zeros")
	}
}

// With data + per-customer rows: the panel renders capacity/fill/ratio; a shared customer with a report
// shows usage, a customer with NO report shows 'no usage reported yet' (never an asserted 0 GB).
func TestOffsiteBoxPanel_WithData(t *testing.T) {
	s, st := newRenderServer(t)
	s.SetOffsiteBox(func() (monitor.BoxSnapshot, bool) {
		return monitor.BoxSnapshot{
			CapacityBytes: 1 << 40, UsedBytes: 300 * gib, DataBytes: 300 * gib,
			FillPercent: 27, FillBand: "ok", SumQuotaGB: 1200, Ratio: 1.17, OversubBand: "ok",
			BoxType: "bx11", FetchedAt: time.Now().UTC(),
		}, true
	})
	// "acme": shared, enabled, 500 GB, WITH a report (200 GiB used). "newbie": shared, enabled, no report.
	saveCfg(t, st, "acme", `{"offsite":{"enabled":true,"type":"shared","quota_gb":500}}`)
	saveCfg(t, st, "newbie", `{"offsite":{"enabled":true,"type":"shared","quota_gb":300}}`)
	if err := st.SaveReport("acme", []byte(`{"customer_id":"acme","offsite":{"enabled":true,"repo_size_bytes":`+itoa(200*gib)+`}}`)); err != nil {
		t.Fatal(err)
	}

	body := renderOffsite(t, s)
	for _, want := range []string{"Offsite pool box", "1.00 TB", "1.17×", "acme", "newbie", "no usage reported yet"} {
		if !strings.Contains(body, want) {
			t.Fatalf("panel missing %q:\n%s", want, body)
		}
	}
	// The RESTIC panel is configured — its specific not-configured message must be absent. (The PBS DR
	// panel legitimately shows its own "not configured" here since s.pbsdrBox is unset.)
	if strings.Contains(body, "Offsite pool metrics not configured") {
		t.Fatal("a configured restic panel must not show the not-configured message")
	}
}

func saveCfg(t *testing.T, st *store.Store, id, cfgJSON string) {
	t.Helper()
	if err := st.SaveCustomerConfig(&store.CustomerConfig{CustomerID: id, CustomerName: id, APIKey: "k-" + id, RetrievalPassword: "p", ConfigJSON: cfgJSON}); err != nil {
		t.Fatalf("save config %s: %v", id, err)
	}
}

// itoa avoids importing strconv just for the report body.
func itoa(v int64) string {
	if v == 0 {
		return "0"
	}
	neg := v < 0
	if neg {
		v = -v
	}
	var b [20]byte
	i := len(b)
	for v > 0 {
		i--
		b[i] = byte('0' + v%10)
		v /= 10
	}
	if neg {
		i--
		b[i] = '-'
	}
	return string(b[i:])
}
