<?php

/** @noinspection PhpUnhandledExceptionInspection */

namespace DefStudio\GameEngine\Http\Livewire\Missions;

use Livewire\WithFileUploads;
use Illuminate\Contracts\View\View;
use Livewire\TemporaryUploadedFile;
use LivewireUI\Modal\ModalComponent;
use Illuminate\Validation\Rules\File;
use DefStudio\GameEngine\Models\Mission;
use Illuminate\Validation\ValidationException;
use DefStudio\GameEngine\Enums\MediaCollection;
use DefStudio\GameEngine\Actions\Tasks\DeleteTask;
use DefStudio\GameEngine\Actions\Missions\UpdateMission;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use DefStudio\GameEngine\Actions\Missions\StoreCoverImage;
use DefStudio\GameEngine\Actions\Missions\RemoveCoverImage;
use DefStudio\GameEngine\Http\Livewire\Concerns\ImprovedModal;
use DefStudio\GameEngine\Http\Livewire\Concerns\RedirectsBack;
use DefStudio\GameEngine\Actions\Livewire\Sortable\UpdateOrder;
use DefStudio\GameEngine\Actions\Missions\StorePlaceholderImage;
use DefStudio\GameEngine\Actions\Missions\RemovePlaceholderImage;
use DefStudio\GameEngine\Actions\Missions\StorePlaceholderImageActive;
use DefStudio\GameEngine\Actions\Missions\RemovePlaceholderImageActive;
use DefStudio\GameEngine\Actions\Missions\StorePlaceholderImageCompleted;
use DefStudio\GameEngine\Actions\Missions\RemovePlaceholderImageCompleted;

class Edit extends ModalComponent
{
    use ImprovedModal;
    use WithFileUploads;
    use AuthorizesRequests;
    use RedirectsBack;

    /** @var Mission */
    public $mission;

    /** @var TemporaryUploadedFile|null */
    public $cover_image = null;

    /** @var TemporaryUploadedFile|null */
    public $placeholder_image = null;

    /** @var TemporaryUploadedFile|null */
    public $placeholder_image_completed = null;

    /** @var TemporaryUploadedFile|null */
    public $placeholder_image_active = null;

    public array $rules = [
        'mission.title' => 'required|string|max:255',
        'mission.description' => 'nullable|string',
        'mission.configuration.randomize_tasks_order' => 'boolean|nullable',
        'mission.configuration.max_tasks_to_show' => 'integer|nullable',
        'mission.configuration.hide_when_not_active' => 'boolean|nullable',
        'mission.configuration.hide_when_completed' => 'boolean|nullable',
        'mission.configuration.complete_on_activation' => 'boolean|nullable',
    ];

    protected $listeners = [
        'task.saved' => 'refresh_tasks',
    ];

    public function mount(int $mission_id): void
    {
        $this->mission = game_engine()->missionQuery()->find($mission_id);
        $this->authorize('update', $this->mission);
    }

    public function render(): View
    {
        return view('game-engine::livewire.admin.missions.edit');
    }

    public function updatedCoverImage(): void
    {
        try {
            $this->validate(['cover_image' => File::image()]);
        } catch (ValidationException $validationException) {
            $this->cover_image = null;
            throw $validationException;
        }
    }

    public function remove_cover_image(): void
    {
        $this->cover_image = null;
        RemoveCoverImage::run($this->mission);
    }

    public function updatedPlaceholderImage(): void
    {
        try {
            $this->validate(['placeholder_image' => File::image()]);
        } catch (ValidationException $validationException) {
            $this->placeholder_image = null;
            throw $validationException;
        }
    }

    public function updatedPlaceholderImageActive(): void
    {
        try {
            $this->validate(['placeholder_image_active' => File::image()]);
        } catch (ValidationException $validationException) {
            $this->placeholder_image_active = null;
            throw $validationException;
        }
    }

    public function updatedPlaceholderImageCompleted(): void
    {
        try {
            $this->validate(['placeholder_image_completed' => File::image()]);
        } catch (ValidationException $validationException) {
            $this->placeholder_image_completed = null;
            throw $validationException;
        }
    }

    public function remove_placeholder_image(): void
    {
        $this->placeholder_image = null;
        RemovePlaceholderImage::run($this->mission);
    }

    public function remove_placeholder_image_active(): void
    {
        $this->placeholder_image_active = null;
        RemovePlaceholderImageActive::run($this->mission);
    }

    public function remove_placeholder_image_completed(): void
    {
        $this->placeholder_image_completed = null;
        RemovePlaceholderImageCompleted::run($this->mission);
    }

    public function save(): void
    {
        $this->validate();

        if (!$this->mission->exists || $this->mission->getFirstMedia(MediaCollection::placeholder) === null) {
            $this->validate(['placeholder_image' => 'required']);
        }

        UpdateMission::run($this->mission);

        if ($this->cover_image !== null) {

            StoreCoverImage::run($this->mission, $this->cover_image);
        }

        if ($this->placeholder_image !== null) {
            StorePlaceholderImage::run($this->mission, $this->placeholder_image);
        }

        if ($this->placeholder_image_active !== null) {
            StorePlaceholderImageActive::run($this->mission, $this->placeholder_image_active);
        }

        if ($this->placeholder_image_completed !== null) {
            StorePlaceholderImageCompleted::run($this->mission, $this->placeholder_image_completed);
        }

        $this->emit('mission.updated', $this->mission->id);

        if ($this->isModal) {
            $this->closeModal();

            return;
        }

        $this->redirect_back();
    }

    public function refresh_tasks(): void
    {
        $this->mission->unsetRelation('tasks');
    }

    public function delete_task(int $task_id): void
    {
        $task = $this->mission->tasks()->findOrFail($task_id);

        DeleteTask::run($task);
    }

    public function update_tasks_order(array $new_order): void
    {
        UpdateOrder::run($this->mission->tasks, $new_order);
    }
}
