package value_objects

import (
	"errors"
)

var ErrInvalidSessionStatus = errors.New("invalid session status")

// SessionStatus represents the status of an MPC session
type SessionStatus string

const (
	SessionStatusCreated    SessionStatus = "created"
	SessionStatusInProgress SessionStatus = "in_progress"
	SessionStatusCompleted  SessionStatus = "completed"
	SessionStatusFailed     SessionStatus = "failed"
	SessionStatusExpired    SessionStatus = "expired"
)

// ValidSessionStatuses contains all valid session statuses
var ValidSessionStatuses = []SessionStatus{
	SessionStatusCreated,
	SessionStatusInProgress,
	SessionStatusCompleted,
	SessionStatusFailed,
	SessionStatusExpired,
}

// NewSessionStatus creates a new SessionStatus from string
func NewSessionStatus(s string) (SessionStatus, error) {
	status := SessionStatus(s)
	if !status.IsValid() {
		return "", ErrInvalidSessionStatus
	}
	return status, nil
}

// String returns the string representation
func (s SessionStatus) String() string {
	return string(s)
}

// IsValid checks if the status is valid
func (s SessionStatus) IsValid() bool {
	for _, valid := range ValidSessionStatuses {
		if s == valid {
			return true
		}
	}
	return false
}

// CanTransitionTo checks if the status can transition to another
func (s SessionStatus) CanTransitionTo(target SessionStatus) bool {
	transitions := map[SessionStatus][]SessionStatus{
		SessionStatusCreated:    {SessionStatusInProgress, SessionStatusFailed, SessionStatusExpired},
		SessionStatusInProgress: {SessionStatusCompleted, SessionStatusFailed, SessionStatusExpired},
		SessionStatusCompleted:  {},
		SessionStatusFailed:     {},
		SessionStatusExpired:    {},
	}

	allowed, ok := transitions[s]
	if !ok {
		return false
	}

	for _, status := range allowed {
		if status == target {
			return true
		}
	}
	return false
}

// IsTerminal checks if the status is terminal (cannot transition)
func (s SessionStatus) IsTerminal() bool {
	return s == SessionStatusCompleted || s == SessionStatusFailed || s == SessionStatusExpired
}

// IsActive checks if the session is active
func (s SessionStatus) IsActive() bool {
	return s == SessionStatusCreated || s == SessionStatusInProgress
}

// ParticipantStatus represents the status of a participant
type ParticipantStatus string

const (
	ParticipantStatusInvited   ParticipantStatus = "invited"
	ParticipantStatusJoined    ParticipantStatus = "joined"
	ParticipantStatusReady     ParticipantStatus = "ready"
	ParticipantStatusCompleted ParticipantStatus = "completed"
	ParticipantStatusFailed    ParticipantStatus = "failed"
)

// ValidParticipantStatuses contains all valid participant statuses
var ValidParticipantStatuses = []ParticipantStatus{
	ParticipantStatusInvited,
	ParticipantStatusJoined,
	ParticipantStatusReady,
	ParticipantStatusCompleted,
	ParticipantStatusFailed,
}

// String returns the string representation
func (s ParticipantStatus) String() string {
	return string(s)
}

// IsValid checks if the status is valid
func (s ParticipantStatus) IsValid() bool {
	for _, valid := range ValidParticipantStatuses {
		if s == valid {
			return true
		}
	}
	return false
}

// CanTransitionTo checks if the status can transition to another
func (s ParticipantStatus) CanTransitionTo(target ParticipantStatus) bool {
	transitions := map[ParticipantStatus][]ParticipantStatus{
		ParticipantStatusInvited:   {ParticipantStatusJoined, ParticipantStatusFailed},
		ParticipantStatusJoined:    {ParticipantStatusReady, ParticipantStatusFailed},
		ParticipantStatusReady:     {ParticipantStatusCompleted, ParticipantStatusFailed},
		ParticipantStatusCompleted: {},
		ParticipantStatusFailed:    {},
	}

	allowed, ok := transitions[s]
	if !ok {
		return false
	}

	for _, status := range allowed {
		if status == target {
			return true
		}
	}
	return false
}
