package entity

import (
	"errors"
	"time"

	"backend/pkg/member/domain/member"

	"go.mongodb.org/mongo-driver/v2/bson"
)

// User represents a user profile with personal information and preferences.
// It contains detailed user data that is separate from authentication credentials.
type User struct {
	ID                bson.ObjectID    `bson:"_id,omitempty" json:"id,omitempty"`
	UID               string           `bson:"uid"`                    // Unique user identifier
	AvatarURL         *string          `bson:"avatar_url,omitempty"`   // User avatar URL (optional)
	FullName          *string          `bson:"full_name,omitempty"`    // User's full name
	Nickname          *string          `bson:"nickname,omitempty"`     // User's nickname (optional)
	GenderCode        *int64           `bson:"gender_code,omitempty"`  // Gender code
	Birthdate         *int64           `bson:"birthdate,omitempty"`    // Birth date (format: 19930417)
	Address           *string          `bson:"address,omitempty"`      // User's address
	AlarmCategory     member.AlarmType `bson:"alarm_category"`         // Alert notification settings
	UserStatus        member.Status    `bson:"user_status"`            // User account status
	PreferredLanguage string           `bson:"preferred_language"`     // User's preferred language
	Currency          string           `bson:"currency"`               // User's preferred currency
	PhoneNumber       *string          `bson:"phone_number,omitempty"` // Phone number (appears after verification)
	Email             *string          `bson:"email,omitempty"`        // Email address (appears after verification)
	UpdateAt          *int64           `bson:"update_at,omitempty" json:"update_at,omitempty"`
	CreateAt          *int64           `bson:"create_at,omitempty" json:"create_at,omitempty"`
}

// CollectionName returns the MongoDB collection name for User entities.
func (u *User) CollectionName() string {
	return "user_info"
}

// Validate validates the User entity
func (u *User) Validate() error {
	if u.UID == "" {
		return errors.New("uid is required")
	}
	if u.PreferredLanguage == "" {
		return errors.New("preferred_language is required")
	}
	if u.Currency == "" {
		return errors.New("currency is required")
	}
	if !u.AlarmCategory.IsValid() {
		return errors.New("invalid alarm_category")
	}
	if !u.UserStatus.IsValid() {
		return errors.New("invalid user_status")
	}
	return nil
}

// SetTimestamps sets the create and update timestamps
func (u *User) SetTimestamps() {
	now := time.Now().UTC().UnixNano()
	if u.CreateAt == nil {
		u.CreateAt = &now
	}
	u.UpdateAt = &now
}

// IsNew returns true if this is a new user (no ID set)
func (u *User) IsNew() bool {
	return u.ID.IsZero()
}

// GetIDString returns the ID as a hex string
func (u *User) GetIDString() string {
	return u.ID.Hex()
}

// GetDisplayName returns the display name (nickname or full name)
func (u *User) GetDisplayName() string {
	if u.Nickname != nil && *u.Nickname != "" {
		return *u.Nickname
	}
	if u.FullName != nil && *u.FullName != "" {
		return *u.FullName
	}
	return u.UID
}

// IsActive returns true if the user status is active
func (u *User) IsActive() bool {
	return u.UserStatus == member.AccountStatusActive
}
