package web

import (
	"io"
	"log"
	"net/http/httptest"
	"net/url"
	"path/filepath"
	"strings"
	"testing"

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

// Group D (Scenario D): with the seam unset (hub reporting off / nil trigger), the helper
// is a strict nil-safe no-op — a handler calling it must never panic.
func TestReportTriggerNow_NilSeamIsNoOp(t *testing.T) {
	s := &Server{}
	s.reportTriggerNow() // must not panic with reportTriggerFn == nil
}

// The wired seam fires on a SUCCESSFUL local commit and does NOT fire on the error path
// (§Part 3: after the successful local commit — never before, never on error). Exercised
// through a real handler (offbox per-app toggle) so deleting the call site fails this test.
func TestReportTriggerNow_FiresAfterSuccessfulCommitOnly(t *testing.T) {
	tmp := t.TempDir()
	lg := log.New(io.Discard, "", 0)
	sett, err := settings.Load(filepath.Join(tmp, "settings.json"), lg)
	if err != nil {
		t.Fatal(err)
	}
	fired := 0
	s := &Server{settings: sett, logger: lg}
	s.SetReportTrigger(func() { fired++ })

	// Error path: missing app param → refused, trigger must NOT fire.
	w := httptest.NewRecorder()
	req := httptest.NewRequest("POST", "/backup/offbox/toggle", strings.NewReader(url.Values{"enabled": {"on"}}.Encode()))
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	s.offboxToggleHandler(w, req)
	if fired != 0 {
		t.Fatalf("trigger fired %d time(s) on the refused save, want 0 (never on the error path)", fired)
	}

	// Success path: the setting commits → the trigger fires exactly once.
	w2 := httptest.NewRecorder()
	req2 := httptest.NewRequest("POST", "/backup/offbox/toggle", strings.NewReader(url.Values{"app": {"immich"}, "enabled": {"on"}}.Encode()))
	req2.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	s.offboxToggleHandler(w2, req2)
	if !sett.IsAppOffbox("immich") {
		t.Fatal("toggle did not commit — precondition for the trigger assertion")
	}
	if fired != 1 {
		t.Fatalf("trigger fired %d time(s) after the successful save, want exactly 1", fired)
	}
}
