<?php

namespace App\Domain\Training\Models;

use App\Domain\Shared\Traits\BelongsToAcademy;
use App\Domain\Shared\Traits\HasUuid;
use App\Domain\Training\Services\SessionGeneratorService;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Domain\Shared\Traits\ScopedThroughBranch;

class TrainingSchedule extends Model
{
    use BelongsToAcademy, HasUuid, ScopedThroughBranch;

    /**
     * The parent whose branch this row inherits. A line item has no
     * branch of its own and must not grow one — a denormalised copy
     * here is a second source of truth that drifts the first time the
     * parent moves.
     */
    protected static string $branchScopeRelation = 'group';

    protected static function booted(): void
    {
        static::saved(function (TrainingSchedule $schedule) {
            if ($schedule->is_active && $schedule->group) {
                app(SessionGeneratorService::class)->generate(
                    $schedule->group,
                    Carbon::today(),
                    Carbon::today()->addDays(7),
                );
            }
        });
    }

    protected $fillable = [
        'academy_id', 'training_group_id', 'facility_id',
        'day_of_week', 'start_time', 'end_time',
        'trainer_id', 'assistant_trainer_id',
        'space_reservation_template', 'effective_from', 'effective_until',
        'is_active', 'notes',
    ];

    protected $casts = [
        'day_of_week' => 'integer',
        'space_reservation_template' => 'array',
        'effective_from' => 'date',
        'effective_until' => 'date',
        'is_active' => 'boolean',
    ];

    public function group(): BelongsTo
    {
        return $this->belongsTo(TrainingGroup::class, 'training_group_id');
    }

    public function trainer(): BelongsTo
    {
        return $this->belongsTo(User::class, 'trainer_id');
    }

    public function assistantTrainer(): BelongsTo
    {
        return $this->belongsTo(User::class, 'assistant_trainer_id');
    }

    public function facility(): BelongsTo
    {
        return $this->belongsTo(\App\Domain\Facility\Models\Facility::class);
    }

    public function sessions(): HasMany
    {
        return $this->hasMany(TrainingSession::class, 'schedule_id');
    }

    public function getDayNameAttribute(): string
    {
        $days = ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'];
        return $days[$this->day_of_week] ?? '';
    }

    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    public function scopeEffectiveOn($query, $date)
    {
        return $query->where('effective_from', '<=', $date)
            ->where(function ($q) use ($date) {
                $q->whereNull('effective_until')
                  ->orWhere('effective_until', '>=', $date);
            });
    }
}
