<?php

namespace App\Livewire\Applicant\Concerns;

use App\Enums\ApplicationStep;
use App\Models\Application;

/**
 * Shared behaviour for every step of the application wizard (PRD 13).
 *
 * Guarantees three things each step would otherwise have to repeat: the
 * signed-in applicant owns this application, the application is still
 * editable, and completing a step records progress and moves forward.
 */
trait WizardStep
{
    public Application $application;

    abstract protected function step(): ApplicationStep;

    public function mountWizardStep(Application $application): void
    {
        abort_unless(
            $application->applicant_id === auth()->user()->applicant?->id,
            403,
            'You do not have access to this application.',
        );

        abort_unless($application->isEditable(), 403, 'This application can no longer be edited.');

        $this->application = $application;
    }

    /** Record this step as done and send the applicant to the next one. */
    protected function completeStep(?ApplicationStep $next = null): void
    {
        $this->application->markStepCompleted($this->step());

        $next ??= $this->step()->next();

        if ($next) {
            $this->application->current_step = $next;
        }

        $this->application->save();

        $this->redirectRoute(
            'applicant.applications.wizard',
            [$this->application, ($next ?? $this->step())->value],
            navigate: true,
        );
    }

    /** Save without advancing, for an explicit "save and finish later". */
    protected function saveProgress(): void
    {
        $this->application->save();

        $this->dispatch('saved');
    }

    public function previousStep(): void
    {
        $previous = $this->step()->previous();

        if (! $previous) {
            return;
        }

        $this->redirectRoute(
            'applicant.applications.wizard',
            [$this->application, $previous->value],
            navigate: true,
        );
    }
}
