package push

import (
	"context"
	"testing"
)

type fakeRepo struct {
	subs map[string]*Subscription
}

func newFakeRepo() *fakeRepo {
	return &fakeRepo{subs: make(map[string]*Subscription)}
}

func (f *fakeRepo) Save(ctx context.Context, sub *Subscription) error {
	sub.ID = int64(len(f.subs) + 1)
	f.subs[sub.Endpoint] = sub
	return nil
}

func (f *fakeRepo) Delete(ctx context.Context, userID int64, endpoint string) error {
	delete(f.subs, endpoint)
	return nil
}

func (f *fakeRepo) DeleteByEndpoint(ctx context.Context, endpoint string) error {
	delete(f.subs, endpoint)
	return nil
}

func (f *fakeRepo) FindByUser(ctx context.Context, userID int64) ([]Subscription, error) {
	var out []Subscription
	for _, s := range f.subs {
		if s.UserID == userID {
			out = append(out, *s)
		}
	}
	return out, nil
}

func (f *fakeRepo) FindByRoles(ctx context.Context, roles []string) ([]Subscription, error) {
	var out []Subscription
	for _, s := range f.subs {
		out = append(out, *s)
	}
	return out, nil
}

func (f *fakeRepo) FindAll(ctx context.Context) ([]Subscription, error) {
	var out []Subscription
	for _, s := range f.subs {
		out = append(out, *s)
	}
	return out, nil
}

func TestPushService_SubscribeAndUnsubscribe(t *testing.T) {
	repo := newFakeRepo()
	svc := NewService(repo)

	var in SubscribeInput
	in.Endpoint = "https://fcm.googleapis.com/fcm/send/test-endpoint"
	in.Keys.P256dh = "test-p256dh"
	in.Keys.Auth = "test-auth"
	in.App = "erp"

	sub, err := svc.Subscribe(context.Background(), 10, in, "TestBrowser/1.0")
	if err != nil {
		t.Fatalf("subscribe failed: %v", err)
	}
	if sub.UserID != 10 || sub.Endpoint != in.Endpoint {
		t.Errorf("unexpected sub: %+v", sub)
	}

	subs, _ := repo.FindByUser(context.Background(), 10)
	if len(subs) != 1 {
		t.Fatalf("expected 1 sub, got %d", len(subs))
	}

	if err := svc.Unsubscribe(context.Background(), 10, in.Endpoint); err != nil {
		t.Fatalf("unsubscribe failed: %v", err)
	}

	subsAfter, _ := repo.FindByUser(context.Background(), 10)
	if len(subsAfter) != 0 {
		t.Fatalf("expected 0 subs after delete, got %d", len(subsAfter))
	}
}
