package roomnotice

import (
	"context"
	"regexp"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"google.golang.org/protobuf/proto"
	roomeventsv1 "hyapp.local/api/proto/events/room/v1"
)

func TestLoadRoomOutboxEnvelopeRejectsEmptyAppInsteadOfDefaultingToLalu(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("create sqlmock: %v", err)
	}
	defer db.Close()
	repository := &MySQLRepository{db: db, roomOutboxTable: "`hyapp_room`.`room_outbox`"}
	if _, err := repository.LoadRoomOutboxEnvelope(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 room owner table: %v", err)
	}
}

func TestLoadRoomOutboxEnvelopeUsesExactImmutableOwnerEnvelope(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("create sqlmock: %v", err)
	}
	defer db.Close()
	body, err := proto.Marshal(&roomeventsv1.RoomUserKicked{ActorUserId: 7, TargetUserId: 42})
	if err != nil {
		t.Fatalf("marshal room kick body: %v", err)
	}
	envelopeBytes, err := proto.Marshal(&roomeventsv1.EventEnvelope{
		AppCode:      "huwaa",
		EventId:      "room:kick:evt-1",
		EventType:    eventRoomUserKicked,
		RoomId:       "room-1",
		RoomVersion:  9,
		OccurredAtMs: 1700000000000,
		Body:         body,
	})
	if err != nil {
		t.Fatalf("marshal room envelope: %v", err)
	}
	repository := &MySQLRepository{db: db, roomOutboxTable: "`hyapp_room`.`room_outbox`"}
	mock.ExpectQuery(regexp.QuoteMeta(`
		SELECT room_id, envelope
		FROM `+"`hyapp_room`.`room_outbox`"+`
		WHERE app_code = ? AND event_id = ? AND event_type = ?`)).
		WithArgs("huwaa", "room:kick:evt-1", eventRoomUserKicked).
		WillReturnRows(sqlmock.NewRows([]string{"room_id", "envelope"}).AddRow("room-1", envelopeBytes))

	envelope, err := repository.LoadRoomOutboxEnvelope(context.Background(), " HUWAA ", "room:kick:evt-1")
	if err != nil {
		t.Fatalf("load exact room owner envelope: %v", err)
	}
	if envelope.GetAppCode() != "huwaa" || envelope.GetEventId() != "room:kick:evt-1" || envelope.GetRoomId() != "room-1" {
		t.Fatalf("room owner snapshot mismatch: %+v", envelope)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("room replay query mismatch: %v", err)
	}
}
