package walletnotice

import (
	"context"
	"regexp"
	"testing"

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

func TestLoadWalletOutboxMessageRejectsEmptyAppInsteadOfDefaultingToLalu(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("create sqlmock: %v", err)
	}
	defer db.Close()
	repository := &MySQLRepository{db: db, walletOutboxTable: "`hyapp_wallet`.`wallet_outbox`"}
	if _, err := repository.LoadWalletOutboxMessage(context.Background(), " ", "evt-1"); err == nil {
		t.Fatal("empty app_code must be rejected before owner table access")
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("empty key unexpectedly queried wallet owner table: %v", err)
	}
}

func TestLoadWalletOutboxMessageUsesExactImmutablePrivateFact(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("create sqlmock: %v", err)
	}
	defer db.Close()
	repository := &MySQLRepository{db: db, walletOutboxTable: "`hyapp_wallet`.`wallet_outbox`"}
	mock.ExpectQuery(regexp.QuoteMeta(`
		SELECT app_code, event_id, event_type, transaction_id, command_id, user_id,
		       asset_type, available_delta, frozen_delta,
		       COALESCE(CAST(payload AS CHAR), '{}'), created_at_ms
		FROM `+"`hyapp_wallet`.`wallet_outbox`"+`
		WHERE app_code = ? AND event_id = ?
		  AND event_type IN (?, ?) AND asset_type <> ?`)).
		WithArgs("fami", "wallet:evt-1", eventWalletBalance, eventVIPActivated, robotCoinAssetType).
		WillReturnRows(sqlmock.NewRows([]string{
			"app_code", "event_id", "event_type", "transaction_id", "command_id", "user_id",
			"asset_type", "available_delta", "frozen_delta", "payload", "created_at_ms",
		}).AddRow("fami", "wallet:evt-1", eventWalletBalance, "tx-1", "cmd-1", int64(42), "COIN", int64(100), int64(0), `{"balance_after":100}`, int64(1700000000000)))

	message, err := repository.LoadWalletOutboxMessage(context.Background(), " FAMI ", "wallet:evt-1")
	if err != nil {
		t.Fatalf("load exact wallet owner fact: %v", err)
	}
	if message.AppCode != "fami" || message.EventID != "wallet:evt-1" || message.UserID != 42 || message.PayloadJSON != `{"balance_after":100}` {
		t.Fatalf("wallet owner snapshot mismatch: %+v", message)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("wallet replay query mismatch: %v", err)
	}
}
