package services

import (
	"context"
	"time"

	"github.com/google/uuid"
	"github.com/kms/api-key-service/internal/domain"
)

// ApplicationService defines the interface for application business logic
type ApplicationService interface {
	// Create creates a new application
	Create(ctx context.Context, req *domain.CreateApplicationRequest, userID string) (*domain.Application, error)
	
	// GetByID retrieves an application by its ID
	GetByID(ctx context.Context, appID string) (*domain.Application, error)
	
	// List retrieves applications with pagination
	List(ctx context.Context, limit, offset int) ([]*domain.Application, error)
	
	// Update updates an existing application
	Update(ctx context.Context, appID string, updates *domain.UpdateApplicationRequest, userID string) (*domain.Application, error)
	
	// Delete deletes an application
	Delete(ctx context.Context, appID string, userID string) error
}

// TokenService defines the interface for token business logic
type TokenService interface {
	// CreateStaticToken creates a new static token
	CreateStaticToken(ctx context.Context, req *domain.CreateStaticTokenRequest, userID string) (*domain.CreateStaticTokenResponse, error)
	
	// ListByApp lists all tokens for an application
	ListByApp(ctx context.Context, appID string, limit, offset int) ([]*domain.StaticToken, error)
	
	// Delete deletes a token
	Delete(ctx context.Context, tokenID uuid.UUID, userID string) error
	
	// GenerateUserToken generates a user token
	GenerateUserToken(ctx context.Context, appID, userID string, permissions []string) (string, error)
	
	// VerifyToken verifies a token and returns verification response
	VerifyToken(ctx context.Context, req *domain.VerifyRequest) (*domain.VerifyResponse, error)
	
	// RenewUserToken renews a user token
	RenewUserToken(ctx context.Context, req *domain.RenewRequest) (*domain.RenewResponse, error)
}

// AuthenticationService defines the interface for authentication business logic
type AuthenticationService interface {
	// GetUserID extracts user ID from context
	GetUserID(ctx context.Context) (string, error)
	
	// ValidatePermissions checks if user has required permissions
	ValidatePermissions(ctx context.Context, userID string, appID string, requiredPermissions []string) error
	
	// GetUserClaims retrieves user claims
	GetUserClaims(ctx context.Context, userID string) (map[string]string, error)
	
	// ValidateJWTToken validates a JWT token and returns claims
	ValidateJWTToken(ctx context.Context, tokenString string) (*domain.AuthContext, error)
	
	// GenerateJWTToken generates a new JWT token for a user
	GenerateJWTToken(ctx context.Context, userToken *domain.UserToken) (string, error)
	
	// RefreshJWTToken refreshes an existing JWT token
	RefreshJWTToken(ctx context.Context, tokenString string, newExpiration time.Time) (string, error)
}

// SessionService defines the interface for session management business logic
type SessionService interface {
	// CreateSession creates a new user session
	CreateSession(ctx context.Context, req *domain.CreateSessionRequest) (*domain.UserSession, error)
	
	// GetSession retrieves a session by its ID
	GetSession(ctx context.Context, sessionID uuid.UUID) (*domain.UserSession, error)
	
	// GetUserSessions retrieves all sessions for a user
	GetUserSessions(ctx context.Context, userID string) ([]*domain.UserSession, error)
	
	// GetUserAppSessions retrieves sessions for a specific user and application
	GetUserAppSessions(ctx context.Context, userID, appID string) ([]*domain.UserSession, error)
	
	// GetActiveSessions retrieves all active sessions for a user
	GetActiveSessions(ctx context.Context, userID string) ([]*domain.UserSession, error)
	
	// ListSessions retrieves sessions with filtering and pagination
	ListSessions(ctx context.Context, req *domain.SessionListRequest) (*domain.SessionListResponse, error)
	
	// UpdateSession updates an existing session
	UpdateSession(ctx context.Context, sessionID uuid.UUID, updates *domain.UpdateSessionRequest) error
	
	// UpdateSessionActivity updates the last activity timestamp for a session
	UpdateSessionActivity(ctx context.Context, sessionID uuid.UUID) error
	
	// RevokeSession revokes a specific session
	RevokeSession(ctx context.Context, sessionID uuid.UUID, revokedBy string) error
	
	// RevokeUserSessions revokes all sessions for a user
	RevokeUserSessions(ctx context.Context, userID string, revokedBy string) error
	
	// RevokeUserAppSessions revokes all sessions for a user and application
	RevokeUserAppSessions(ctx context.Context, userID, appID string, revokedBy string) error
	
	// ValidateSession validates if a session is active and valid
	ValidateSession(ctx context.Context, sessionID uuid.UUID) (*domain.UserSession, error)
	
	// RefreshSession refreshes a session's expiration time
	RefreshSession(ctx context.Context, sessionID uuid.UUID, newExpiration time.Time) error
	
	// CleanupExpiredSessions marks expired sessions as expired and optionally deletes old ones
	CleanupExpiredSessions(ctx context.Context, deleteOlderThan *time.Duration) (expired int, deleted int, err error)
	
	// GetSessionStats returns session statistics for a user
	GetSessionStats(ctx context.Context, userID string) (total int, active int, err error)
	
	// CreateOAuth2Session creates a session from OAuth2 authentication flow
	CreateOAuth2Session(ctx context.Context, userID, appID string, tokenResponse *domain.TokenResponse, userInfo *domain.UserInfo, sessionType domain.SessionType, ipAddress, userAgent string) (*domain.UserSession, error)
}
