package integration

import (
	"bytes"
	"context"
	"io"
	"net/http"
	"testing"
	"time"

	roomeventsv1 "hyapp.local/api/proto/events/room/v1"
	"hyapp/pkg/tencentim"
	"hyapp/services/room-service/internal/room/outbox"
)

func TestRoomEventFromEnvelopeSkipsNonIMEvents(t *testing.T) {
	record, err := outbox.Build("room-noop", "RoomCreated", 1, time.Now(), &roomeventsv1.RoomCreated{
		OwnerUserId: 1,
		SeatCount:   4,
		Mode:        "social",
	})
	if err != nil {
		t.Fatalf("Build RoomCreated envelope failed: %v", err)
	}

	event, publish, err := roomEventFromEnvelope(record.Envelope)
	if err != nil {
		t.Fatalf("RoomCreated should be a no-op success: %v", err)
	}
	if publish {
		t.Fatalf("RoomCreated must not publish Tencent IM message: %+v", event)
	}
}

func TestTencentIMPublisherRemovesGroupMemberBeforeKickMessage(t *testing.T) {
	paths := make([]string, 0, 2)
	client, err := tencentim.NewRESTClient(tencentim.RESTConfig{
		SDKAppID:        1400000000,
		SecretKey:       "secret",
		AdminIdentifier: "administrator",
		AdminUserSigTTL: time.Hour,
		HTTPClient: &http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) {
			paths = append(paths, request.URL.Path)
			return &http.Response{
				StatusCode: http.StatusOK,
				Body:       io.NopCloser(bytes.NewReader([]byte(`{"ActionStatus":"OK","ErrorCode":0,"ErrorInfo":""}`))),
				Header:     make(http.Header),
			}, nil
		})},
	})
	if err != nil {
		t.Fatalf("NewRESTClient failed: %v", err)
	}

	record, err := outbox.Build("room-kick", "RoomUserKicked", 3, time.Now(), &roomeventsv1.RoomUserKicked{
		ActorUserId:  1,
		TargetUserId: 2,
	})
	if err != nil {
		t.Fatalf("Build RoomUserKicked envelope failed: %v", err)
	}
	publisher := NewTencentIMPublisher(client)
	if err := publisher.PublishOutboxEvent(context.Background(), record.Envelope); err != nil {
		t.Fatalf("PublishOutboxEvent failed: %v", err)
	}

	if len(paths) != 2 || paths[0] != "/v4/group_open_http_svc/delete_group_member" || paths[1] != "/v4/group_open_http_svc/send_group_msg" {
		t.Fatalf("kick outbox should delete member before system message, paths=%+v", paths)
	}
}

type roundTripFunc func(*http.Request) (*http.Response, error)

func (f roundTripFunc) RoundTrip(request *http.Request) (*http.Response, error) {
	return f(request)
}
