package store

import (
	"database/sql"
	"fmt"
	"krafttrainer/internal/model"
)

// ListExercises gibt alle nicht-gelöschten Übungen zurück, optional gefiltert.
func (s *Store) ListExercises(muscleGroup, query string) ([]model.Exercise, error) {
	rows, err := s.db.Query(`
		SELECT id, name, description, muscle_group, weight_step_kg, created_at, updated_at
		FROM exercises
		WHERE deleted_at IS NULL
		  AND (muscle_group = ? OR ? = '')
		  AND (name LIKE '%' || ? || '%' OR ? = '')
		ORDER BY name`,
		muscleGroup, muscleGroup, query, query,
	)
	if err != nil {
		return nil, fmt.Errorf("Übungen abfragen: %w", err)
	}
	defer rows.Close()

	var exercises []model.Exercise
	for rows.Next() {
		var e model.Exercise
		if err := rows.Scan(&e.ID, &e.Name, &e.Description, &e.MuscleGroup, &e.WeightStepKg, &e.CreatedAt, &e.UpdatedAt); err != nil {
			return nil, fmt.Errorf("Übung scannen: %w", err)
		}
		exercises = append(exercises, e)
	}
	if exercises == nil {
		exercises = []model.Exercise{}
	}
	return exercises, rows.Err()
}

// GetExercise gibt eine einzelne Übung zurück.
func (s *Store) GetExercise(id int64) (*model.Exercise, error) {
	var e model.Exercise
	err := s.db.QueryRow(`
		SELECT id, name, description, muscle_group, weight_step_kg, created_at, updated_at, deleted_at
		FROM exercises WHERE id = ?`, id,
	).Scan(&e.ID, &e.Name, &e.Description, &e.MuscleGroup, &e.WeightStepKg, &e.CreatedAt, &e.UpdatedAt, &e.DeletedAt)
	if err == sql.ErrNoRows {
		return nil, nil
	}
	if err != nil {
		return nil, fmt.Errorf("Übung abfragen: %w", err)
	}
	return &e, nil
}

// CreateExercise legt eine neue Übung an und gibt sie zurück.
func (s *Store) CreateExercise(req *model.CreateExerciseRequest) (*model.Exercise, error) {
	result, err := s.db.Exec(`
		INSERT INTO exercises (name, description, muscle_group, weight_step_kg)
		VALUES (?, ?, ?, ?)`,
		req.Name, req.Description, req.MuscleGroup, *req.WeightStepKg,
	)
	if err != nil {
		return nil, fmt.Errorf("Übung erstellen: %w", err)
	}

	id, _ := result.LastInsertId()
	return s.GetExercise(id)
}

// UpdateExercise aktualisiert eine Übung und gibt sie zurück.
func (s *Store) UpdateExercise(id int64, req *model.CreateExerciseRequest) (*model.Exercise, error) {
	result, err := s.db.Exec(`
		UPDATE exercises
		SET name = ?, description = ?, muscle_group = ?, weight_step_kg = ?,
		    updated_at = CURRENT_TIMESTAMP
		WHERE id = ? AND deleted_at IS NULL`,
		req.Name, req.Description, req.MuscleGroup, *req.WeightStepKg, id,
	)
	if err != nil {
		return nil, fmt.Errorf("Übung aktualisieren: %w", err)
	}

	rows, _ := result.RowsAffected()
	if rows == 0 {
		return nil, nil
	}
	return s.GetExercise(id)
}

// SoftDeleteExercise markiert eine Übung als gelöscht.
func (s *Store) SoftDeleteExercise(id int64) error {
	result, err := s.db.Exec(`
		UPDATE exercises SET deleted_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
		WHERE id = ? AND deleted_at IS NULL`, id,
	)
	if err != nil {
		return fmt.Errorf("Übung löschen: %w", err)
	}

	rows, _ := result.RowsAffected()
	if rows == 0 {
		return sql.ErrNoRows
	}
	return nil
}
