package replay

import (
	"context"
	"testing"
	"time"

	"github.com/DATA-DOG/go-sqlmock"
)

func TestLoadCaptures_TimeWindow(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	since := time.Date(2026, 4, 24, 0, 0, 0, 0, time.UTC)
	until := time.Date(2026, 4, 24, 1, 0, 0, 0, time.UTC)

	rcv := since.Add(10 * time.Minute)
	rows := sqlmock.NewRows([]string{"RequestId", "ReceivedAt", "Method", "Path",
		"Query", "Headers", "Body", "ResponseStatus", "UserId", "Entrypoint"}).
		AddRow("req-1", rcv, "POST", "/services/data/v63.0/sobjects/Lead",
			"", "{}", `{"Name":"x"}`, 201, "005abc", "REST_API")

	mock.ExpectQuery("FROM _System_RequestCapture").
		WithArgs(since, until, 100).
		WillReturnRows(rows)

	got, err := LoadCaptures(context.Background(), db, CaptureFilter{Since: since, Until: until})
	if err != nil {
		t.Fatalf("LoadCaptures: %v", err)
	}
	if len(got) != 1 || got[0].RequestID != "req-1" {
		t.Fatalf("unexpected result: %+v", got)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("unmet expectations: %v", err)
	}
}

func TestLoadCaptures_RequestIDFilter(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	rows := sqlmock.NewRows([]string{"RequestId", "ReceivedAt", "Method", "Path",
		"Query", "Headers", "Body", "ResponseStatus", "UserId", "Entrypoint"}).
		AddRow("req-xyz", time.Now(), "PATCH", "/services/data/v63.0/sobjects/Lead/001",
			"", "{}", `{"Status":"Converted"}`, 204, "005abc", "REST_UI")

	mock.ExpectQuery("FROM _System_RequestCapture").
		WithArgs("req-xyz", 50).
		WillReturnRows(rows)

	got, err := LoadCaptures(context.Background(), db, CaptureFilter{RequestID: "req-xyz", Limit: 50})
	if err != nil {
		t.Fatalf("LoadCaptures: %v", err)
	}
	if len(got) != 1 || got[0].RequestID != "req-xyz" {
		t.Fatalf("unexpected: %+v", got)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("unmet: %v", err)
	}
}

func TestLoadAuditRowsForRequest(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	rows := sqlmock.NewRows([]string{"ObjectApiName", "RecordId", "FieldName",
		"Action", "OldValue", "NewValue", "Entrypoint"}).
		AddRow("Lead", "001", "__record__", "UPDATE", "", "", "REST_API").
		AddRow("Lead", "001", "Status", "UPDATE", "Open", "Converted", "REST_API")

	mock.ExpectQuery("FROM _System_AuditLog").
		WithArgs("req-1").
		WillReturnRows(rows)

	got, err := LoadAuditRowsForRequest(context.Background(), db, "req-1")
	if err != nil {
		t.Fatalf("LoadAuditRowsForRequest: %v", err)
	}
	if len(got) != 2 {
		t.Fatalf("expected 2 rows, got %d", len(got))
	}
	if got[1].FieldName != "Status" || got[1].NewValue != "Converted" {
		t.Errorf("unexpected row shape: %+v", got[1])
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("unmet: %v", err)
	}
}

func TestLoadAuditRowsForRequest_EmptyID(t *testing.T) {
	_, err := LoadAuditRowsForRequest(context.Background(), nil, "")
	if err == nil {
		t.Fatal("expected error on empty RequestId")
	}
}
