package web

import (
	"net/http/httptest"
	"net/url"
	"strings"
	"testing"

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

// R-100 — an ordinary settings save must not erase the staleness anchor.
//
// offboxConfigHandler builds a FRESH OffboxTarget from the form and copies runtime status across from
// the previous one, field by field. Every field omitted from that copy is silently zeroed. LastSuccess
// is the hub's staleness anchor, so omitting it would reset an established tier to "never succeeded"
// every time the customer edited the host or the path — and the reset would be invisible until the
// hub's verdict changed days later.
//
// This is the "seam built but never wired" shape: the field exists, the writer sets it, and a routine
// unrelated code path throws it away.
//
// RED-PROOF: remove `tgt.LastSuccess = prev.LastSuccess` from offboxConfigHandler → this fails with
// "a settings save erased LastSuccess".
func TestOffboxEdit_PreservesLastSuccess(t *testing.T) {
	s, sett, _ := newOffboxWebServer(t)
	const anchor = "2026-07-26T02:15:00Z"
	if err := sett.SetOffboxTarget(&settings.OffboxTarget{
		Enabled: true, Host: "nas.local", User: "felhom", RepoPath: "/srv/repo",
		EscrowState: "escrowed",
		LastRun:     "2026-07-27T02:15:00Z", // a later FAILED attempt
		LastStatus:  "error",
		LastSuccess: anchor,
	}); err != nil {
		t.Fatal(err)
	}

	// The customer edits the repo path — nothing to do with run history.
	form := url.Values{
		"enabled": {"on"}, "host": {"nas.local"}, "user": {"felhom"},
		"repo_path": {"/srv/repo-moved"}, "port": {"22"},
		// First-setup guard: the handler requires both secrets when none are on disk yet.
		"ssh_key":     {"-----BEGIN OPENSSH PRIVATE KEY-----\nZmFrZQ==\n-----END OPENSSH PRIVATE KEY-----\n"},
		"known_hosts": {"nas.local ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFAKEFAKEFAKEFAKEFAKEFAKEFAKEFAKEFAKEFAKEFAK"},
	}
	req := httptest.NewRequest("POST", "/backup/offbox/config", strings.NewReader(form.Encode()))
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	rec := httptest.NewRecorder()
	s.offboxConfigHandler(rec, req)
	// NOTE: the redirect carries a flash about escrow STAGING failing — there is no agent in this
	// fixture. The target itself is persisted before that step, which is what this test is about, and
	// the repo_path assertion below is the real precondition.

	got := sett.GetOffboxTarget()
	if got == nil {
		t.Fatal("target vanished after the save")
	}
	if got.RepoPath != "/srv/repo-moved" {
		t.Fatalf("precondition: the edit did not apply (repo_path = %q)", got.RepoPath)
	}
	if got.LastSuccess != anchor {
		t.Errorf("a settings save erased LastSuccess (got %q, want %q) — the tier would read as never-succeeded",
			got.LastSuccess, anchor)
	}
	// and the attempt clock is preserved too, as it already was
	if got.LastRun != "2026-07-27T02:15:00Z" {
		t.Errorf("the save also lost LastRun (got %q)", got.LastRun)
	}
}
