package tools

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

	"skraak/utils"
)

func TestPushCertaintyPromotesMatchingLabels(t *testing.T) {
	tempDir := t.TempDir()

	// File with two Kiwi segments: certainty=90 and certainty=70
	file1 := `[{"Operator": "test"}, [0, 10, 100, 1000, [{"species": "Kiwi", "certainty": 90}]], [10, 20, 100, 1000, [{"species": "Kiwi", "certainty": 70}]]]`
	file1Path := filepath.Join(tempDir, "file1.data")
	if err := os.WriteFile(file1Path, []byte(file1), 0644); err != nil {
		t.Fatal(err)
	}

	// File with one Tomtit at certainty=90 (must not be promoted when species=Kiwi)
	file2 := `[{"Operator": "test"}, [0, 10, 100, 1000, [{"species": "Tomtit", "certainty": 90}]]]`
	file2Path := filepath.Join(tempDir, "file2.data")
	if err := os.WriteFile(file2Path, []byte(file2), 0644); err != nil {
		t.Fatal(err)
	}

	result, err := PushCertainty(PushCertaintyConfig{
		Folder:   tempDir,
		Species:  "Kiwi",
		Reviewer: "TestReviewer",
	})
	if err != nil {
		t.Fatal(err)
	}

	if result.SegmentsUpdated != 1 {
		t.Errorf("expected 1 segment updated, got %d", result.SegmentsUpdated)
	}
	if result.FilesUpdated != 1 {
		t.Errorf("expected 1 file updated, got %d", result.FilesUpdated)
	}

	// Verify file1: certainty=90 Kiwi → 100, certainty=70 Kiwi → unchanged
	df, err := utils.ParseDataFile(file1Path)
	if err != nil {
		t.Fatal(err)
	}
	if df.Segments[0].Labels[0].Certainty != 100 {
		t.Errorf("expected certainty=100, got %d", df.Segments[0].Labels[0].Certainty)
	}
	if df.Segments[1].Labels[0].Certainty != 70 {
		t.Errorf("expected certainty=70 unchanged, got %d", df.Segments[1].Labels[0].Certainty)
	}
	if df.Meta.Reviewer != "TestReviewer" {
		t.Errorf("expected reviewer=TestReviewer, got %q", df.Meta.Reviewer)
	}

	// Verify Tomtit file was not modified
	df2, err := utils.ParseDataFile(file2Path)
	if err != nil {
		t.Fatal(err)
	}
	if df2.Segments[0].Labels[0].Certainty != 90 {
		t.Errorf("Tomtit certainty should be unchanged at 90, got %d", df2.Segments[0].Labels[0].Certainty)
	}
}

func TestPushCertaintyFilterScope(t *testing.T) {
	tempDir := t.TempDir()

	// Segment has two labels from different filters, both Kiwi certainty=90
	data := []any{
		map[string]any{"Operator": "test"},
		[]any{0.0, 10.0, 100.0, 1000.0, []any{
			map[string]any{"species": "Kiwi", "certainty": 90, "filter": "model-a"},
			map[string]any{"species": "Kiwi", "certainty": 90, "filter": "model-b"},
		}},
	}
	raw, _ := json.Marshal(data)
	filePath := filepath.Join(tempDir, "file1.data")
	if err := os.WriteFile(filePath, raw, 0644); err != nil {
		t.Fatal(err)
	}

	// Push only model-a
	result, err := PushCertainty(PushCertaintyConfig{
		Folder:   tempDir,
		Filter:   "model-a",
		Species:  "Kiwi",
		Reviewer: "TestReviewer",
	})
	if err != nil {
		t.Fatal(err)
	}
	if result.SegmentsUpdated != 1 {
		t.Errorf("expected 1 segment updated, got %d", result.SegmentsUpdated)
	}

	// Verify only model-a label was promoted; model-b stays at 90
	df, err := utils.ParseDataFile(filePath)
	if err != nil {
		t.Fatal(err)
	}
	for _, label := range df.Segments[0].Labels {
		if label.Filter == "model-a" && label.Certainty != 100 {
			t.Errorf("model-a label should be 100, got %d", label.Certainty)
		}
		if label.Filter == "model-b" && label.Certainty != 90 {
			t.Errorf("model-b label should be unchanged at 90, got %d", label.Certainty)
		}
	}
}