package services

import (
	"context"
	"time"

	"veza-backend-api/internal/models"

	"github.com/google/uuid"
)

// PlaylistServiceInterface defines the interface for playlist service
// Moved from handlers to avoid cyclic dependency with PlaylistDuplicateService
type PlaylistServiceInterface interface {
	CreatePlaylist(ctx context.Context, userID uuid.UUID, title, description string, isPublic bool) (*models.Playlist, error)
	GetPlaylists(ctx context.Context, currentUserID *uuid.UUID, filterUserID *uuid.UUID, page, limit int) ([]*models.Playlist, int64, error)
	GetPlaylist(ctx context.Context, id uuid.UUID, currentUserID *uuid.UUID) (*models.Playlist, error)
	UpdatePlaylist(ctx context.Context, id uuid.UUID, userID uuid.UUID, title, description *string, isPublic *bool) (*models.Playlist, error)
	DeletePlaylist(ctx context.Context, id uuid.UUID, userID uuid.UUID) error
	AddTrack(ctx context.Context, playlistID, trackID, userID uuid.UUID) error
	RemoveTrack(ctx context.Context, playlistID, trackID, userID uuid.UUID) error
	ReorderTracks(ctx context.Context, playlistID, userID uuid.UUID, trackIDs []uuid.UUID) error
	AddCollaborator(ctx context.Context, playlistID, userID, collaboratorUserID uuid.UUID, permission models.PlaylistPermission) (*models.PlaylistCollaborator, error)
	RemoveCollaborator(ctx context.Context, playlistID, userID, collaboratorUserID uuid.UUID) error
	UpdateCollaboratorPermission(ctx context.Context, playlistID, userID, collaboratorUserID uuid.UUID, permission models.PlaylistPermission) error
	GetCollaborators(ctx context.Context, playlistID, userID uuid.UUID) ([]*models.PlaylistCollaborator, error)
	CreateShareLink(ctx context.Context, playlistID, userID uuid.UUID, expiresAt *time.Time) (*models.PlaylistShareLink, error)
	FollowPlaylist(ctx context.Context, playlistID, userID uuid.UUID) error
	UnfollowPlaylist(ctx context.Context, playlistID, userID uuid.UUID) error
	CheckPermission(ctx context.Context, playlistID, userID uuid.UUID, permission models.PlaylistPermission) (bool, error)
	SearchPlaylists(ctx context.Context, params SearchPlaylistsParams) ([]*models.Playlist, int64, error)
}

// EmailServiceInterface defines methods for sending emails
type EmailServiceInterface interface {
	SendVerificationEmail(email, token string) error
	SendVerificationEmailWithUserID(userID uuid.UUID, email string) error
	SendPasswordResetEmail(userID uuid.UUID, email string, token string) error
	SendWelcomeEmail(email, username string) error
	SendNotificationEmail(email, subject, message, notificationType string) error
}

// EmailVerificationServiceInterface defines methods for email verification
type EmailVerificationServiceInterface interface {
	GenerateToken() (string, error)
	StoreToken(userID uuid.UUID, email, token string) error
	VerifyToken(token string) (uuid.UUID, error)
	InvalidateOldTokens(userID uuid.UUID) error
	ResendVerificationEmail(userID uuid.UUID, email string) error
}

// PasswordResetServiceInterface defines methods for password reset
type PasswordResetServiceInterface interface {
	GenerateToken() (string, error)
	StoreToken(userID uuid.UUID, token string) error
	VerifyToken(token string) (uuid.UUID, error)
	MarkTokenAsUsed(token string) error
	InvalidateOldTokens(userID uuid.UUID) error
}

// PasswordServiceInterface defines methods for password management
type PasswordServiceInterface interface {
	ValidatePassword(password string) error
	UpdatePassword(userID uuid.UUID, newPassword string) error
	Hash(password string) (string, error)
	Compare(hashedPassword, password string) bool
}

// JWTServiceInterface defines methods for JWT management
type JWTServiceInterface interface {
	GenerateAccessToken(user *models.User) (string, error)
	GenerateRefreshToken(user *models.User) (string, error)
	GenerateTokenPair(user *models.User) (*models.TokenPair, error)
	ValidateToken(tokenString string) (*models.CustomClaims, error)
	ExtractUserID(tokenString string) (uuid.UUID, error)
	GetConfig() *models.JWTConfig
}

// RefreshTokenServiceInterface defines methods for refresh token management
type RefreshTokenServiceInterface interface {
	Store(userID uuid.UUID, token string, ttl time.Duration) error
	Validate(userID uuid.UUID, token string) error
	Rotate(userID uuid.UUID, oldToken, newToken string, ttl time.Duration) error
	Revoke(userID uuid.UUID, token string) error
	RevokeAll(userID uuid.UUID) error
}

// JobWorkerInterface defines methods for background jobs
type JobWorkerInterface interface {
	EnqueueEmailJobWithTemplate(to, subject, templateName string, templateData map[string]interface{})
}
