package httpapi

import (
	"encoding/json"
	"os"
	"path/filepath"
	"testing"
)

func TestFilePlayerStatusStorePersistsOnSave(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "status.json")

	s, err := newFilePlayerStatusStore(path)
	if err != nil {
		t.Fatalf("newFilePlayerStatusStore() error = %v", err)
	}

	s.Save(playerStatusRecord{ScreenID: "screen-a", Timestamp: "2026-03-22T16:00:00Z", Status: "running"})

	data, err := os.ReadFile(path)
	if err != nil {
		t.Fatalf("ReadFile() error = %v", err)
	}

	var records []playerStatusRecord
	if err := json.Unmarshal(data, &records); err != nil {
		t.Fatalf("Unmarshal() error = %v", err)
	}

	if got, want := len(records), 1; got != want {
		t.Fatalf("len(records) = %d, want %d", got, want)
	}
	if got, want := records[0].ScreenID, "screen-a"; got != want {
		t.Fatalf("ScreenID = %q, want %q", got, want)
	}
}

func TestFilePlayerStatusStorePersistsOnDelete(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "status.json")

	s, err := newFilePlayerStatusStore(path)
	if err != nil {
		t.Fatalf("newFilePlayerStatusStore() error = %v", err)
	}

	s.Save(playerStatusRecord{ScreenID: "screen-a", Timestamp: "2026-03-22T16:00:00Z", Status: "running"})
	s.Save(playerStatusRecord{ScreenID: "screen-b", Timestamp: "2026-03-22T16:00:00Z", Status: "running"})

	if ok := s.Delete("screen-a"); !ok {
		t.Fatal("Delete() = false, want true")
	}

	data, err := os.ReadFile(path)
	if err != nil {
		t.Fatalf("ReadFile() error = %v", err)
	}

	var records []playerStatusRecord
	if err := json.Unmarshal(data, &records); err != nil {
		t.Fatalf("Unmarshal() error = %v", err)
	}

	if got, want := len(records), 1; got != want {
		t.Fatalf("len(records) = %d, want %d", got, want)
	}
	if got, want := records[0].ScreenID, "screen-b"; got != want {
		t.Fatalf("ScreenID = %q, want %q", got, want)
	}
}

func TestFilePlayerStatusStoreLoadsExistingData(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "status.json")

	existing := []playerStatusRecord{
		{ScreenID: "screen-x", Timestamp: "2026-03-22T16:00:00Z", Status: "running"},
	}
	data, _ := json.Marshal(existing)
	if err := os.WriteFile(path, data, 0o644); err != nil {
		t.Fatalf("WriteFile() error = %v", err)
	}

	s, err := newFilePlayerStatusStore(path)
	if err != nil {
		t.Fatalf("newFilePlayerStatusStore() error = %v", err)
	}

	rec, ok := s.Get("screen-x")
	if !ok {
		t.Fatal("Get() = false, want true")
	}
	if got, want := rec.ScreenID, "screen-x"; got != want {
		t.Fatalf("ScreenID = %q, want %q", got, want)
	}
}

func TestFilePlayerStatusStoreMissingFileIsOK(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "nonexistent.json")

	s, err := newFilePlayerStatusStore(path)
	if err != nil {
		t.Fatalf("newFilePlayerStatusStore() with missing file error = %v", err)
	}

	if got, want := len(s.List()), 0; got != want {
		t.Fatalf("len(List()) = %d, want %d", got, want)
	}
}

func TestNewStoreFromConfigInMemoryWhenNoPath(t *testing.T) {
	store, err := NewStoreFromConfig("")
	if err != nil {
		t.Fatalf("NewStoreFromConfig(\"\") error = %v", err)
	}
	store.Save(playerStatusRecord{ScreenID: "s1", Timestamp: "2026-03-22T16:00:00Z", Status: "running"})
	if _, ok := store.Get("s1"); !ok {
		t.Fatal("Get() = false after Save()")
	}
}
