package web

import (
	"strings"
	"testing"

	"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
	"gitea.dooplex.hu/admin/felhom-controller/internal/system"
)

// v0.126.0 Part B — infra stacks carry curated identity (name + description + Védett chip),
// and the guarded-wrong outcome: NO customer link for cloudflared/traefik (filebrowser is
// the ONLY Linked infra stack).
// COMPANION red-proof (recorded in REPORT): set Linked:true on cloudflared → the
// single-Megnyitás assertions below FAIL.

func infraStacksTestSet() []stacks.Stack {
	return []stacks.Stack{
		{Name: "cloudflared", Protected: true, State: stacks.StateRunning,
			Meta: stacks.Metadata{Slug: "cloudflared", DisplayName: "Cloudflared"}},
		{Name: "traefik", Protected: true, State: stacks.StateRunning,
			Meta: stacks.Metadata{Slug: "traefik", DisplayName: "Traefik"}},
		{Name: "filebrowser", Protected: true, State: stacks.StateRunning,
			Meta: stacks.Metadata{Slug: "filebrowser", DisplayName: "Filebrowser"}},
	}
}

func infraPageData(page string) map[string]interface{} {
	return map[string]interface{}{
		"Page": page, "Title": "t",
		"Stacks":          infraStacksTestSet(),
		"MissingStorage":  map[string]string{},
		"NetworkWarnings": map[string]string{},
		"NetworkStubs":    map[string]string{},
		"StorageLabels":   map[string]string{},
		"Subdomains":      map[string]string{"filebrowser": "files"},
		"RunningCount":    3, "StoppedCount": 0, "TotalCount": 3,
		"SystemInfo":    system.SystemInfo{},
		"BackupEnabled": false,
		"Domain":        "demo-felhom.eu",
	}
}

func assertInfraIdentity(t *testing.T, surface, html string) {
	t.Helper()
	for _, want := range []string{
		"Cloudflare Tunnel",
		"Biztonságos internetkapcsolat — a szerver portnyitás nélkül érhető el kívülről.",
		"Traefik",
		"Forgalomirányító (reverse proxy) — a kéréseket a megfelelő alkalmazáshoz irányítja.",
		"FileBrowser",
		"Fájlkezelő — a tárhely fájljainak böngészése a böngészőből.",
	} {
		if !strings.Contains(html, want) {
			t.Errorf("%s: infra identity %q missing", surface, want)
		}
	}
	if !strings.Contains(html, "Védett") {
		t.Errorf("%s: the Védett chip is missing", surface)
	}
	if !strings.Contains(html, `https://files.demo-felhom.eu`) {
		t.Errorf("%s: filebrowser must link files.<domain>", surface)
	}
	// The guarded WRONG outcome: exactly ONE customer link (filebrowser) — a second
	// https:// link would mean cloudflared/traefik got one.
	if n := strings.Count(html, `https://`); n != 1 {
		t.Errorf("%s: expected exactly 1 customer link (filebrowser), found %d https:// occurrences", surface, n)
	}
}

func TestInfraMeta_DashboardRows(t *testing.T) {
	html := renderBackupPage(t, "dashboard", infraPageData("dashboard"))
	assertInfraIdentity(t, "dashboard", html)
	if n := strings.Count(html, "Megnyitás"); n != 1 {
		t.Errorf("dashboard: expected exactly 1 Megnyitás (filebrowser), found %d", n)
	}
	if n := strings.Count(html, `data-fallback="/static/infra-logo.svg"`); n != 3 {
		t.Errorf("dashboard: all 3 infra rows must carry the generic-icon fallback, found %d", n)
	}
}

func TestInfraMeta_AppCards(t *testing.T) {
	html := renderBackupPage(t, "stacks", infraPageData("stacks"))
	assertInfraIdentity(t, "stacks", html)
	if !strings.Contains(html, "Védett rendszerkomponens") {
		t.Error("stacks: protected card chip missing")
	}
	if n := strings.Count(html, `data-fallback="/static/infra-logo.svg"`); n != 3 {
		t.Errorf("stacks: all 3 infra cards must carry the generic-icon fallback, found %d", n)
	}
}

func TestInfraMetaFor_RegularAppIsNil(t *testing.T) {
	if infraMetaFor("radarr") != nil {
		t.Error("regular apps must have no infra metadata")
	}
	if m := infraMetaFor("cloudflared"); m == nil || m.Linked {
		t.Error("cloudflared must exist and must NOT be Linked (no customer UI)")
	}
	if m := infraMetaFor("filebrowser"); m == nil || !m.Linked {
		t.Error("filebrowser must be the Linked infra stack")
	}
}
