// models/user.go
package models

import (
	"time"

	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

// models/user.go - добавить поле Avatar
type User struct {
	ID            uint           `json:"id" gorm:"primaryKey"`
	Email         string         `json:"email" gorm:"uniqueIndex;not null"`
	Password      string         `json:"-" gorm:"not null"`
	FirstName     string         `json:"first_name" gorm:"not null"`
	LastName      string         `json:"last_name" gorm:"not null"`
	Avatar        string         `json:"avatar"` // Путь к файлу аватара
	Phone         string         `json:"phone"`
	Experience    string         `json:"experience"`
	Goals         string         `json:"goals"`
	Newsletter    bool           `json:"newsletter"`
	Role          string         `json:"role" gorm:"default:user"`
	CreatedAt     time.Time      `json:"created_at"`
	UpdatedAt     time.Time      `json:"updated_at"`
	DeletedAt     gorm.DeletedAt `json:"-" gorm:"index"`
	EmailVerified bool           `json:"email_verified" gorm:"default:false"`
	VerifiedAt    time.Time      `json:"verified_at"`

	// Связи
	Workouts           []Workout           `json:"workouts,omitempty" gorm:"foreignKey:UserID"`
	PersonalBests      []PersonalBest      `json:"personal_bests,omitempty" gorm:"foreignKey:UserID"`
	Achievements       []Achievement       `json:"achievements,omitempty" gorm:"foreignKey:UserID"`
	TrainingPlans      []TrainingPlan      `json:"training_plans,omitempty" gorm:"foreignKey:UserID"`
	News               []News              `json:"news,omitempty" gorm:"foreignKey:AuthorID"`
	Comments           []Comment           `json:"comments,omitempty" gorm:"foreignKey:AuthorID"`
	Reviews            []Review            `json:"reviews,omitempty" gorm:"foreignKey:AuthorID"`
	Gallery            []Gallery           `json:"gallery,omitempty" gorm:"foreignKey:AuthorID"`
	EventRegistrations []EventRegistration `json:"event_registrations,omitempty" gorm:"foreignKey:UserID"`
}

type UserUpdate struct {
	ID         uint      `json:"id"`
	FirstName  string    `json:"first_name"`
	LastName   string    `json:"last_name"`
	Avatar     string    `json:"avatar"`
	Phone      string    `json:"phone"`
	Experience string    `json:"experience"`
	Goals      string    `json:"goals"`
	Newsletter bool      `json:"newsletter"`
	UpdatedAt  time.Time `json:"updated_at"`
}

// HashPassword хеширует пароль перед сохранением
func (u *User) HashPassword() error {
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}
	u.Password = string(hashedPassword)
	return nil
}

// CheckPassword проверяет пароль
func (u *User) CheckPassword(password string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
	return err == nil
}

// BeforeCreate hook для GORM
func (u *User) BeforeCreate(tx *gorm.DB) error {
	if u.CreatedAt.IsZero() {
		u.CreatedAt = time.Now()
	}
	if u.UpdatedAt.IsZero() {
		u.UpdatedAt = time.Now()
	}
	return u.HashPassword()
}

// BeforeUpdate hook для GORM
func (u *User) BeforeUpdate(tx *gorm.DB) error {
	u.UpdatedAt = time.Now()
	return nil
}

// DTO для обновления профиля
type UserUpdateRequest struct {
	FirstName  string `json:"first_name" validate:"required,min=2,max=100"`
	LastName   string `json:"last_name" validate:"required,min=2,max=100"`
	Phone      string `json:"phone" validate:"max=20"`
	Experience string `json:"experience" validate:"max=50"`
	Goals      string `json:"goals" validate:"max=100"`
	Newsletter bool   `json:"newsletter"`
}

// DTO для ответа с пользователем (без sensitive данных)
type UserResponse struct {
	ID         uint      `json:"id"`
	Email      string    `json:"email"`
	FirstName  string    `json:"first_name"`
	LastName   string    `json:"last_name"`
	Avatar     string    `json:"avatar"`
	Phone      string    `json:"phone"`
	Experience string    `json:"experience"`
	Goals      string    `json:"goals"`
	Newsletter bool      `json:"newsletter"`
	Role       string    `json:"role"`
	CreatedAt  time.Time `json:"created_at"`
}

// DTO для ответа с пользователем и статистикой
type UserWithStatsResponse struct {
	UserResponse
	Stats *UserStatsResponse `json:"stats,omitempty"`
}
