<?php

/** @noinspection PhpPossiblePolymorphicInvocationInspection */

/** @noinspection PhpUnhandledExceptionInspection */

namespace DefStudio\GameEngine\Http\Livewire\Awards;

use Livewire\Component;
use Illuminate\Contracts\View\View;
use DefStudio\GameEngine\Models\Award;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use DefStudio\GameEngine\Exceptions\AwardException;
use DefStudio\GameEngine\Actions\Awards\DeleteAward;
use DefStudio\GameEngine\Actions\Livewire\Sortable\UpdateOrder;

/**
 * @property-read Collection<int, Award> $awards
 */
class AwardList extends Component
{
    /** @var Model|null */
    public $parent = null;

    /** @var Model|null */
    public $scope = null;

    protected $listeners = [
        'award.saved' => '$refresh',
    ];

    public function mount(): void
    {
        if ($this->parent !== null) {
            $this->scope = null;
        }
    }

    public function render(): View
    {
        return view('game-engine::livewire.admin.awards.award-list');
    }

    /**
     * @return Collection<int, Award>
     */
    public function getAwardsProperty(): Collection
    {
        /** @var Collection<int, Award> $awards */
        $awards = game_engine()->awardQuery()
            ->where('parent_id', $this->parent?->id) //@phpstan-ignore-line
            ->when($this->scope !== null, fn(Builder $query) => $query->where('scope_type', $this->scope->getMorphClass())->where('scope_id', $this->scope->id)) //@phpstan-ignore-line
            ->orderBy('order')
            ->with('scope')
            ->get();

        return $awards;
    }

    public function delete($award_id): void
    {
        $award = $this->awards->find($award_id) ?? throw AwardException::not_found($award_id);
        DeleteAward::run($award);
    }

    public function update_order(array $new_order): void
    {
        UpdateOrder::run($this->awards, $new_order);
        $this->forgetComputed('awards');
    }
}
