<?php

namespace Functional\Tracking\Database\Factories;

use Functional\Programs\Models\Program;
use Functional\Routines\Models\Routine;
use Functional\Tracking\Enums\WorkoutSessionStatus;
use Functional\Tracking\Models\WorkoutSession;
use Functional\Users\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends Factory<WorkoutSession>
 */
class WorkoutSessionFactory extends Factory
{
    protected $model = WorkoutSession::class;

    /**
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'user_id' => User::factory(),
            'routine_id' => null,
            'program_id' => null,
            'title' => null,
            'started_at' => fake()->dateTimeBetween('-2 months', 'now'),
            'ended_at' => null,
            'status' => WorkoutSessionStatus::Active,
            'notes' => null,
            'total_volume' => null,
        ];
    }

    /** Séance terminée normalement, avec un volume total calculé. */
    public function completed(): static
    {
        return $this->state(function (array $attributes) {
            $startedAt = $attributes['started_at'] ?? fake()->dateTimeBetween('-2 months', '-1 day');

            return [
                'started_at' => $startedAt,
                'ended_at' => fake()->dateTimeBetween($startedAt, 'now'),
                'status' => WorkoutSessionStatus::Completed,
                'total_volume' => fake()->randomFloat(2, 500, 8000),
            ];
        });
    }

    /** Séance interrompue avant la fin. */
    public function abandoned(): static
    {
        return $this->state(function (array $attributes) {
            $startedAt = $attributes['started_at'] ?? fake()->dateTimeBetween('-2 months', '-1 day');

            return [
                'started_at' => $startedAt,
                'ended_at' => fake()->dateTimeBetween($startedAt, 'now'),
                'status' => WorkoutSessionStatus::Abandoned,
            ];
        });
    }

    /** Rattache la séance à une routine existante. */
    public function forRoutine(Routine $routine): static
    {
        return $this->state(fn (array $attributes) => [
            'routine_id' => $routine->id,
        ]);
    }

    /** Rattache la séance à un programme existant. */
    public function forProgram(Program $program): static
    {
        return $this->state(fn (array $attributes) => [
            'program_id' => $program->id,
        ]);
    }
}
