<?php

/** @noinspection LaravelUnknownEloquentFactoryInspection */

namespace DefStudio\GameEngine\Models;

use Spatie\MediaLibrary\HasMedia;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use DefStudio\GameEngine\Enums\MediaCollection;
use DefStudio\GameEngine\Attributes\ParentScope;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use DefStudio\GameEngine\Models\Contracts\FitsInScope;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use DefStudio\GameEngine\Database\Factories\MapFactory;
use DefStudio\GameEngine\Models\Concerns\DefinesAwards;
use DefStudio\GameEngine\Models\Concerns\BelongsToScope;
use DefStudio\GameEngine\Models\Contracts\AwardsDefiner;
use DefStudio\GameEngine\Models\Concerns\HasStorytellings;
use DefStudio\GameEngine\Models\Contracts\WithStorytelling;
use function game_engine;

/**
 * @property int $id;
 * @property int $story_id;
 * @property string $title;
 * @property string $description;
 * @property-read Story $story,
 * @property-read Collection<Mission> $missions,
 *
 * @method static MapFactory factory(array|callable|int|null $count = null, array|callable $state = [])
 */
class Map extends Model implements HasMedia, WithStorytelling, FitsInScope, AwardsDefiner
{
    use HasFactory;
    use Concerns\HasMedia;
    use HasStorytellings;
    use BelongsToScope;
    use DefinesAwards;

    protected $fillable = [
        'title',
        'description',
        'order',
    ];

    protected $casts = [
        'order' => 'integer',
    ];

    protected array $media_collections = [
        MediaCollection::background,
    ];

    public function getTable()
    {
        return config('game-engine.maps.table', parent::getTable());
    }

    protected static function newFactory(): MapFactory
    {
        return MapFactory::new();
    }

    /**
     * @return BelongsTo<Story, Map>
     */
    #[ParentScope(Story::class)]
    public function story(): BelongsTo
    {
        return $this->belongsTo(game_engine()->storyClass());
    }

    /**
     * @return HasMany<Mission>
     */
    public function missions(): HasMany
    {
        return $this->hasMany(game_engine()->missionClass());
    }

    public function award_scope_label(): string
    {
        return __('Map: :map_title', ['map_title' => $this->title]);
    }
}
