package repositories

import (
	"context"

	"github.com/google/uuid"
	"github.com/rwadurian/mpc-system/services/session-coordinator/domain/entities"
	"github.com/rwadurian/mpc-system/services/session-coordinator/domain/value_objects"
)

// SessionRepository defines the interface for session persistence
// This is a port in Hexagonal Architecture
type SessionRepository interface {
	// Save persists a new session
	Save(ctx context.Context, session *entities.MPCSession) error

	// FindByID retrieves a session by ID
	FindByID(ctx context.Context, id value_objects.SessionID) (*entities.MPCSession, error)

	// FindByUUID retrieves a session by UUID
	FindByUUID(ctx context.Context, id uuid.UUID) (*entities.MPCSession, error)

	// FindByStatus retrieves sessions by status
	FindByStatus(ctx context.Context, status value_objects.SessionStatus) ([]*entities.MPCSession, error)

	// FindExpired retrieves all expired sessions
	FindExpired(ctx context.Context) ([]*entities.MPCSession, error)

	// FindActive retrieves all active sessions (created or in_progress)
	FindActive(ctx context.Context) ([]*entities.MPCSession, error)

	// FindByCreator retrieves sessions created by a user
	FindByCreator(ctx context.Context, creatorID string) ([]*entities.MPCSession, error)

	// FindActiveByParticipant retrieves active sessions for a participant
	FindActiveByParticipant(ctx context.Context, partyID value_objects.PartyID) ([]*entities.MPCSession, error)

	// Update updates an existing session
	Update(ctx context.Context, session *entities.MPCSession) error

	// Delete removes a session
	Delete(ctx context.Context, id value_objects.SessionID) error

	// DeleteExpired removes all expired sessions
	DeleteExpired(ctx context.Context) (int64, error)

	// Count returns the total number of sessions
	Count(ctx context.Context) (int64, error)

	// CountByStatus returns the number of sessions by status
	CountByStatus(ctx context.Context, status value_objects.SessionStatus) (int64, error)
}

// SessionQueryOptions defines options for querying sessions
type SessionQueryOptions struct {
	Status      *value_objects.SessionStatus
	SessionType *entities.SessionType
	CreatedBy   string
	Limit       int
	Offset      int
	OrderBy     string
	OrderDesc   bool
}

// NewSessionQueryOptions creates default query options
func NewSessionQueryOptions() *SessionQueryOptions {
	return &SessionQueryOptions{
		Limit:     10,
		Offset:    0,
		OrderBy:   "created_at",
		OrderDesc: true,
	}
}

// WithStatus sets the status filter
func (o *SessionQueryOptions) WithStatus(status value_objects.SessionStatus) *SessionQueryOptions {
	o.Status = &status
	return o
}

// WithSessionType sets the session type filter
func (o *SessionQueryOptions) WithSessionType(sessionType entities.SessionType) *SessionQueryOptions {
	o.SessionType = &sessionType
	return o
}

// WithCreatedBy sets the creator filter
func (o *SessionQueryOptions) WithCreatedBy(createdBy string) *SessionQueryOptions {
	o.CreatedBy = createdBy
	return o
}

// WithPagination sets pagination options
func (o *SessionQueryOptions) WithPagination(limit, offset int) *SessionQueryOptions {
	o.Limit = limit
	o.Offset = offset
	return o
}

// WithOrder sets ordering options
func (o *SessionQueryOptions) WithOrder(orderBy string, desc bool) *SessionQueryOptions {
	o.OrderBy = orderBy
	o.OrderDesc = desc
	return o
}
