package user

import (
	"context"
	"time"
)

// User represents a user in the system
type User struct {
	ID                 uint       `json:"id" gorm:"primaryKey"`
	CreatedAt          time.Time  `json:"created_at" gorm:"autoCreateTime"`
	UpdatedAt          time.Time  `json:"updated_at" gorm:"autoUpdateTime"`
	DeletedAt          *time.Time `json:"deleted_at,omitempty" gorm:"index"`
	Username           string     `json:"username" gorm:"unique;not null" validate:"required,min=3,max=50"`
	PasswordHash       string     `json:"-" gorm:"not null"`
	Description        *string    `json:"description,omitempty"`
	CurrentGoal        *string    `json:"current_goal,omitempty"`
	IsAdmin            bool       `json:"is_admin" gorm:"default:false"`
	AllowPasswordReset bool       `json:"allow_password_reset" gorm:"default:false"`
	LastLogin          *time.Time `json:"last_login,omitempty"`
}

// UserRepository defines the interface for user persistence
type UserRepository interface {
	CreateUser(ctx context.Context, user *User) error
	GetUserByUsername(ctx context.Context, username string) (*User, error)
	GetUserByID(ctx context.Context, id uint) (*User, error)
	UpdateUser(ctx context.Context, user *User) error
	DeleteUser(ctx context.Context, id uint) error
	AllowPasswordReset(ctx context.Context, username string) error
	CompletePasswordReset(ctx context.Context, username, newPassword string) error
	UserExists(ctx context.Context, username string) (bool, error)
	CheckDatabaseHealth(ctx context.Context) error
}

// AuthService defines interface for authentication operations
type AuthService interface {
	Authenticate(ctx context.Context, username, password string) (*User, error)
	GenerateJWT(ctx context.Context, user *User) (string, error)
	ValidateJWT(ctx context.Context, token string) (*User, error)
	AdminAuthenticate(ctx context.Context, masterPassword string) (*User, error)
}

// UserManager defines interface for user management operations
type UserManager interface {
	UserExists(ctx context.Context, username string) (bool, error)
	CreateUser(ctx context.Context, user *User) error
}

// PasswordService defines interface for password operations
type PasswordService interface {
	HashPassword(ctx context.Context, password string) (string, error)
	RequestPasswordReset(ctx context.Context, username string) error
	CompletePasswordReset(ctx context.Context, username, newPassword string) error
}

// UserService composes all user-related interfaces using Go's interface composition
// This is cleaner than aggregation and better for testing
type UserService interface {
	AuthService
	UserManager
	PasswordService
}

// PasswordResetService defines the interface for password reset workflow
type PasswordResetService interface {
	RequestPasswordReset(ctx context.Context, username string) error
	CompletePasswordReset(ctx context.Context, username, newPassword string) error
}
