package qso

import (
	"context"
	"path/filepath"
	"testing"

	"hamlog/internal/db"
)

// End-to-end proof that filtering a confirmation STATUS actually filters.
//
// Reported from the field: "QRZ.com received status = N" returned rows showing
// both N and Y. The SQL is a plain `col = ?`, so either the query is right and
// the fault is elsewhere (the UI keeping the previous rows on an error, say), or
// it is wrong here. Reading the code cannot tell those apart — running it can.
func TestFilterOnConfirmationStatus(t *testing.T) {
	conn, err := db.Open(filepath.Join(t.TempDir(), "logbook.db"))
	if err != nil {
		t.Fatalf("open: %v", err)
	}
	defer conn.Close()
	r := NewRepo(conn)
	ctx := context.Background()

	for _, c := range []struct{ call, status string }{
		{"W1AAA", "Y"},
		{"W1BBB", "N"},
		{"W1CCC", "Y"},
		{"W1DDD", "N"},
		{"W1EEE", ""}, // never touched by a download — NULL/empty, neither Y nor N
	} {
		q := QSO{Callsign: c.call, Band: "20m", Mode: "SSB", QRZComDownloadStatus: c.status}
		if _, err := r.Add(ctx, q); err != nil {
			t.Fatalf("insert %s: %v", c.call, err)
		}
	}

	got, err := r.ListFiltered(ctx, QueryFilter{
		Conditions: []Condition{{Field: "qrzcom_qso_download_status", Op: "eq", Value: "N"}},
		Match:      "AND",
	})
	if err != nil {
		t.Fatalf("ListFiltered: %v", err)
	}
	if len(got) != 2 {
		t.Fatalf("filter = N returned %d rows, want 2", len(got))
	}
	for _, q := range got {
		if q.QRZComDownloadStatus != "N" {
			t.Errorf("filter = N returned %s with status %q", q.Callsign, q.QRZComDownloadStatus)
		}
	}

	// A count that disagreed with the list would show "2 matches" above a grid of
	// five rows — the exact shape of the report.
	n, err := r.CountFiltered(ctx, QueryFilter{
		Conditions: []Condition{{Field: "qrzcom_qso_download_status", Op: "eq", Value: "N"}},
	})
	if err != nil {
		t.Fatalf("CountFiltered: %v", err)
	}
	if n != 2 {
		t.Errorf("CountFiltered = %d, want 2", n)
	}
}

// An unknown field must ERROR rather than be silently dropped: a dropped
// condition returns the whole logbook, which reads as "the filter did nothing".
func TestFilterRejectsUnknownField(t *testing.T) {
	if _, _, err := conditionSQL(Condition{Field: "not_a_column", Op: "eq", Value: "N"}); err == nil {
		t.Error("unknown filter field accepted — it would silently return every QSO")
	}
}
