package repository

import (
	"context"
	"time"

	"backend/pkg/permission/domain/entity"

	"github.com/stretchr/testify/mock"
)

// MockTokenRepository is a mock implementation of TokenRepository
type MockTokenRepository struct {
	mock.Mock
}

// NewMockTokenRepository creates a new mock instance
func NewMockTokenRepository(t interface {
	mock.TestingT
	Cleanup(func())
}) *MockTokenRepository {
	mock := &MockTokenRepository{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}

// Create provides a mock function with given fields: ctx, token
func (m *MockTokenRepository) Create(ctx context.Context, token entity.Token) error {
	ret := m.Called(ctx, token)
	return ret.Error(0)
}

// CreateOneTimeToken provides a mock function with given fields: ctx, key, ticket, dt
func (m *MockTokenRepository) CreateOneTimeToken(ctx context.Context, key string, ticket entity.Ticket, dt time.Duration) error {
	ret := m.Called(ctx, key, ticket, dt)
	return ret.Error(0)
}

// GetAccessTokenByOneTimeToken provides a mock function with given fields: ctx, oneTimeToken
func (m *MockTokenRepository) GetAccessTokenByOneTimeToken(ctx context.Context, oneTimeToken string) (entity.Token, error) {
	ret := m.Called(ctx, oneTimeToken)
	return ret.Get(0).(entity.Token), ret.Error(1)
}

// GetAccessTokenByID provides a mock function with given fields: ctx, id
func (m *MockTokenRepository) GetAccessTokenByID(ctx context.Context, id string) (entity.Token, error) {
	ret := m.Called(ctx, id)
	return ret.Get(0).(entity.Token), ret.Error(1)
}

// GetAccessTokensByUID provides a mock function with given fields: ctx, uid
func (m *MockTokenRepository) GetAccessTokensByUID(ctx context.Context, uid string) ([]entity.Token, error) {
	ret := m.Called(ctx, uid)
	return ret.Get(0).([]entity.Token), ret.Error(1)
}

// GetAccessTokenCountByUID provides a mock function with given fields: ctx, uid
func (m *MockTokenRepository) GetAccessTokenCountByUID(ctx context.Context, uid string) (int, error) {
	ret := m.Called(ctx, uid)
	return ret.Int(0), ret.Error(1)
}

// GetAccessTokensByDeviceID provides a mock function with given fields: ctx, deviceID
func (m *MockTokenRepository) GetAccessTokensByDeviceID(ctx context.Context, deviceID string) ([]entity.Token, error) {
	ret := m.Called(ctx, deviceID)
	return ret.Get(0).([]entity.Token), ret.Error(1)
}

// GetAccessTokenCountByDeviceID provides a mock function with given fields: ctx, deviceID
func (m *MockTokenRepository) GetAccessTokenCountByDeviceID(ctx context.Context, deviceID string) (int, error) {
	ret := m.Called(ctx, deviceID)
	return ret.Int(0), ret.Error(1)
}

// Delete provides a mock function with given fields: ctx, token
func (m *MockTokenRepository) Delete(ctx context.Context, token entity.Token) error {
	ret := m.Called(ctx, token)
	return ret.Error(0)
}

// DeleteOneTimeToken provides a mock function with given fields: ctx, ids, tokens
func (m *MockTokenRepository) DeleteOneTimeToken(ctx context.Context, ids []string, tokens []entity.Token) error {
	ret := m.Called(ctx, ids, tokens)
	return ret.Error(0)
}

// DeleteAccessTokenByID provides a mock function with given fields: ctx, ids
func (m *MockTokenRepository) DeleteAccessTokenByID(ctx context.Context, ids []string) error {
	ret := m.Called(ctx, ids)
	return ret.Error(0)
}

// DeleteAccessTokensByUID provides a mock function with given fields: ctx, uid
func (m *MockTokenRepository) DeleteAccessTokensByUID(ctx context.Context, uid string) error {
	ret := m.Called(ctx, uid)
	return ret.Error(0)
}

// DeleteAccessTokensByDeviceID provides a mock function with given fields: ctx, deviceID
func (m *MockTokenRepository) DeleteAccessTokensByDeviceID(ctx context.Context, deviceID string) error {
	ret := m.Called(ctx, deviceID)
	return ret.Error(0)
}

// AddToBlacklist provides a mock function with given fields: ctx, entry, ttl
func (m *MockTokenRepository) AddToBlacklist(ctx context.Context, entry *entity.BlacklistEntry, ttl time.Duration) error {
	ret := m.Called(ctx, entry, ttl)
	return ret.Error(0)
}

// IsBlacklisted provides a mock function with given fields: ctx, jti
func (m *MockTokenRepository) IsBlacklisted(ctx context.Context, jti string) (bool, error) {
	ret := m.Called(ctx, jti)
	return ret.Bool(0), ret.Error(1)
}

// RemoveFromBlacklist provides a mock function with given fields: ctx, jti
func (m *MockTokenRepository) RemoveFromBlacklist(ctx context.Context, jti string) error {
	ret := m.Called(ctx, jti)
	return ret.Error(0)
}

// GetBlacklistedTokensByUID provides a mock function with given fields: ctx, uid
func (m *MockTokenRepository) GetBlacklistedTokensByUID(ctx context.Context, uid string) ([]*entity.BlacklistEntry, error) {
	ret := m.Called(ctx, uid)
	return ret.Get(0).([]*entity.BlacklistEntry), ret.Error(1)
}