package domain

import (
	"time"

	"github.com/google/uuid"
)

// UserStatus represents the status of a user account
type UserStatus string

const (
	UserStatusActive    UserStatus = "active"
	UserStatusInactive  UserStatus = "inactive"
	UserStatusSuspended UserStatus = "suspended"
	UserStatusPending   UserStatus = "pending"
)

// UserRole represents the role of a user
type UserRole string

const (
	UserRoleAdmin     UserRole = "admin"
	UserRoleUser      UserRole = "user"
	UserRoleModerator UserRole = "moderator"
	UserRoleViewer    UserRole = "viewer"
)

// User represents a user in the system
type User struct {
	ID          uuid.UUID `json:"id" db:"id"`
	Email       string    `json:"email" validate:"required,email,max=255" db:"email"`
	FirstName   string    `json:"first_name" validate:"required,min=1,max=100" db:"first_name"`
	LastName    string    `json:"last_name" validate:"required,min=1,max=100" db:"last_name"`
	DisplayName string    `json:"display_name" validate:"omitempty,max=200" db:"display_name"`
	Avatar      string    `json:"avatar,omitempty" validate:"omitempty,url,max=500" db:"avatar"`
	Role        UserRole  `json:"role" validate:"required,oneof=admin user moderator viewer" db:"role"`
	Status      UserStatus `json:"status" validate:"required,oneof=active inactive suspended pending" db:"status"`
	LastLoginAt *time.Time `json:"last_login_at,omitempty" db:"last_login_at"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`
	CreatedBy   string    `json:"created_by" validate:"required" db:"created_by"`
	UpdatedBy   string    `json:"updated_by" validate:"required" db:"updated_by"`
}

// UserProfile represents extended user profile information
type UserProfile struct {
	UserID      uuid.UUID              `json:"user_id" db:"user_id"`
	Bio         string                 `json:"bio,omitempty" validate:"omitempty,max=1000" db:"bio"`
	Location    string                 `json:"location,omitempty" validate:"omitempty,max=200" db:"location"`
	Website     string                 `json:"website,omitempty" validate:"omitempty,url,max=500" db:"website"`
	Timezone    string                 `json:"timezone,omitempty" validate:"omitempty,max=50" db:"timezone"`
	Language    string                 `json:"language,omitempty" validate:"omitempty,max=10" db:"language"`
	Preferences map[string]interface{} `json:"preferences,omitempty" db:"preferences"`
	CreatedAt   time.Time              `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time              `json:"updated_at" db:"updated_at"`
}

// UserSession represents a user session
type UserSession struct {
	ID        uuid.UUID `json:"id" db:"id"`
	UserID    uuid.UUID `json:"user_id" validate:"required" db:"user_id"`
	Token     string    `json:"-" db:"token"` // Hidden from JSON
	IPAddress string    `json:"ip_address" validate:"required" db:"ip_address"`
	UserAgent string    `json:"user_agent" validate:"required" db:"user_agent"`
	ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
	LastUsedAt time.Time `json:"last_used_at" db:"last_used_at"`
}

// CreateUserRequest represents a request to create a new user
type CreateUserRequest struct {
	Email       string   `json:"email" validate:"required,email,max=255"`
	FirstName   string   `json:"first_name" validate:"required,min=1,max=100"`
	LastName    string   `json:"last_name" validate:"required,min=1,max=100"`
	DisplayName string   `json:"display_name,omitempty" validate:"omitempty,max=200"`
	Avatar      string   `json:"avatar,omitempty" validate:"omitempty,url,max=500"`
	Role        UserRole `json:"role" validate:"required,oneof=admin user moderator viewer"`
	Status      UserStatus `json:"status" validate:"omitempty,oneof=active inactive suspended pending"`
}

// UpdateUserRequest represents a request to update an existing user
type UpdateUserRequest struct {
	Email       *string     `json:"email,omitempty" validate:"omitempty,email,max=255"`
	FirstName   *string     `json:"first_name,omitempty" validate:"omitempty,min=1,max=100"`
	LastName    *string     `json:"last_name,omitempty" validate:"omitempty,min=1,max=100"`
	DisplayName *string     `json:"display_name,omitempty" validate:"omitempty,max=200"`
	Avatar      *string     `json:"avatar,omitempty" validate:"omitempty,url,max=500"`
	Role        *UserRole   `json:"role,omitempty" validate:"omitempty,oneof=admin user moderator viewer"`
	Status      *UserStatus `json:"status,omitempty" validate:"omitempty,oneof=active inactive suspended pending"`
}

// UpdateUserProfileRequest represents a request to update user profile
type UpdateUserProfileRequest struct {
	Bio         *string                 `json:"bio,omitempty" validate:"omitempty,max=1000"`
	Location    *string                 `json:"location,omitempty" validate:"omitempty,max=200"`
	Website     *string                 `json:"website,omitempty" validate:"omitempty,url,max=500"`
	Timezone    *string                 `json:"timezone,omitempty" validate:"omitempty,max=50"`
	Language    *string                 `json:"language,omitempty" validate:"omitempty,max=10"`
	Preferences *map[string]interface{} `json:"preferences,omitempty"`
}

// ListUsersRequest represents a request to list users with filters
type ListUsersRequest struct {
	Status   *UserStatus `json:"status,omitempty" validate:"omitempty,oneof=active inactive suspended pending"`
	Role     *UserRole   `json:"role,omitempty" validate:"omitempty,oneof=admin user moderator viewer"`
	Search   string      `json:"search,omitempty" validate:"omitempty,max=255"`
	Limit    int         `json:"limit,omitempty" validate:"omitempty,min=1,max=100"`
	Offset   int         `json:"offset,omitempty" validate:"omitempty,min=0"`
	OrderBy  string      `json:"order_by,omitempty" validate:"omitempty,oneof=created_at updated_at email first_name last_name"`
	OrderDir string      `json:"order_dir,omitempty" validate:"omitempty,oneof=asc desc"`
}

// ListUsersResponse represents a response for listing users
type ListUsersResponse struct {
	Users      []User `json:"users"`
	Total      int    `json:"total"`
	Limit      int    `json:"limit"`
	Offset     int    `json:"offset"`
	HasMore    bool   `json:"has_more"`
}

// AuthContext represents the authentication context for a request
type AuthContext struct {
	UserID      string            `json:"user_id"`
	Email       string            `json:"email"`
	Role        UserRole          `json:"role"`
	Permissions []string          `json:"permissions"`
	Claims      map[string]string `json:"claims"`
}