// repositories/training_plan_repository.go
package repository

import (
	"api_bb/internal/models"
	"time"

	"gorm.io/gorm"
)

type TrainingPlanRepository struct {
	db *gorm.DB
}

func NewTrainingPlanRepository(db *gorm.DB) *TrainingPlanRepository {
	return &TrainingPlanRepository{db: db}
}

// Create создает новый план тренировок
func (r *TrainingPlanRepository) Create(plan *models.TrainingPlan) error {
	return r.db.Create(plan).Error
}

// GetByID возвращает план тренировок по ID
func (r *TrainingPlanRepository) GetByID(id uint) (*models.TrainingPlan, error) {
	var plan models.TrainingPlan
	err := r.db.Preload("Workouts").First(&plan, id).Error
	if err != nil {
		return nil, err
	}
	return &plan, nil
}

// GetByUserID возвращает все планы тренировок пользователя
func (r *TrainingPlanRepository) GetByUserID(userID uint) ([]models.TrainingPlan, error) {
	var plans []models.TrainingPlan
	err := r.db.Preload("Workouts").Where("user_id = ?", userID).Find(&plans).Error
	if err != nil {
		return nil, err
	}
	return plans, nil
}

// Update обновляет план тренировок
func (r *TrainingPlanRepository) Update(plan *models.TrainingPlan) error {
	return r.db.Save(plan).Error
}

// Delete удаляет план тренировок
func (r *TrainingPlanRepository) Delete(id uint) error {
	return r.db.Delete(&models.TrainingPlan{}, id).Error
}

// UpdateCurrentWeek обновляет текущую неделю плана тренировок
func (r *TrainingPlanRepository) UpdateCurrentWeek(id uint, currentWeek int) error {
	return r.db.Model(&models.TrainingPlan{}).Where("id = ?", id).Update("current_week", currentWeek).Error
}

// MarkAsCompleted помечает план тренировок как завершенный
func (r *TrainingPlanRepository) MarkAsCompleted(id uint) error {
	return r.db.Model(&models.TrainingPlan{}).Where("id = ?", id).Update("completed", true).Error
}

// GetActivePlan возвращает активный (не завершенный) план тренировок пользователя
func (r *TrainingPlanRepository) GetActivePlan(userID uint) (*models.TrainingPlan, error) {
	var plan models.TrainingPlan
	err := r.db.Preload("Workouts").Where("user_id = ? AND completed = ?", userID, false).First(&plan).Error
	if err != nil {
		return nil, err
	}
	return &plan, nil
}

// CreateWorkout создает тренировку в плане
func (r *TrainingPlanRepository) CreateWorkout(workout *models.TrainingWorkout) error {
	return r.db.Create(workout).Error
}

// GetWorkoutByID возвращает тренировку по ID
func (r *TrainingPlanRepository) GetWorkoutByID(id uint) (*models.TrainingWorkout, error) {
	var workout models.TrainingWorkout
	err := r.db.First(&workout, id).Error
	if err != nil {
		return nil, err
	}
	return &workout, nil
}

// GetWorkoutsByPlanID возвращает все тренировки плана
func (r *TrainingPlanRepository) GetWorkoutsByPlanID(planID uint) ([]models.TrainingWorkout, error) {
	var workouts []models.TrainingWorkout
	err := r.db.Where("plan_id = ?", planID).Find(&workouts).Error
	if err != nil {
		return nil, err
	}
	return workouts, nil
}

// UpdateWorkout обновляет тренировку
func (r *TrainingPlanRepository) UpdateWorkout(workout *models.TrainingWorkout) error {
	return r.db.Save(workout).Error
}

// DeleteWorkout удаляет тренировку
func (r *TrainingPlanRepository) DeleteWorkout(id uint) error {
	return r.db.Delete(&models.TrainingWorkout{}, id).Error
}

// MarkWorkoutAsCompleted помечает тренировку как завершенную
func (r *TrainingPlanRepository) MarkWorkoutAsCompleted(id uint) error {
	now := time.Now()
	return r.db.Model(&models.TrainingWorkout{}).Where("id = ?", id).Updates(map[string]interface{}{
		"completed":    true,
		"completed_at": now,
	}).Error
}

// GetWorkoutsByWeek возвращает тренировки для определенной недели плана
func (r *TrainingPlanRepository) GetWorkoutsByWeek(planID uint, week int) ([]models.TrainingWorkout, error) {
	var workouts []models.TrainingWorkout
	err := r.db.Where("plan_id = ? AND week = ?", planID, week).Find(&workouts).Error
	if err != nil {
		return nil, err
	}
	return workouts, nil
}

// GetCompletedWorkouts возвращает завершенные тренировки плана
func (r *TrainingPlanRepository) GetCompletedWorkouts(planID uint) ([]models.TrainingWorkout, error) {
	var workouts []models.TrainingWorkout
	err := r.db.Where("plan_id = ? AND completed = ?", planID, true).Find(&workouts).Error
	if err != nil {
		return nil, err
	}
	return workouts, nil
}