<?php

namespace App\Domain\Training\Models;

use App\Domain\Expenses\Models\Vendor;
use App\Domain\Training\Enums\ProgramStatus;
use App\Support\Concerns\HasUuid;
use App\Support\Money\Money;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

/** A training or orientation session (§22). */
class TrainingProgram extends Model
{
    use HasUuid, SoftDeletes;

    protected $guarded = ['id', 'uuid'];

    protected function casts(): array
    {
        return [
            'status' => ProgramStatus::class,
            'starts_on' => 'date',
            'ends_on' => 'date',
            'capacity' => 'integer',
            'enrolled_count' => 'integer',
            'fee_amount' => 'integer',
            'certificate_required' => 'boolean',
        ];
    }

    public function participants(): HasMany
    {
        return $this->hasMany(TrainingParticipant::class);
    }

    public function vendor(): BelongsTo
    {
        return $this->belongsTo(Vendor::class);
    }

    public function fee(): Money
    {
        return Money::of((int) $this->fee_amount, $this->currency);
    }

    /** Zero capacity means the programme is not capped. */
    public function hasRoom(): bool
    {
        return $this->capacity === 0 || $this->enrolled_count < $this->capacity;
    }

    public function seatsLeft(): ?int
    {
        return $this->capacity === 0 ? null : max(0, $this->capacity - $this->enrolled_count);
    }

    public function scopeUpcoming(Builder $query): Builder
    {
        return $query->whereIn('status', [ProgramStatus::Scheduled->value, ProgramStatus::Running->value])
            ->orderBy('starts_on');
    }
}
