<?php

namespace App\Livewire\Applicant;

use App\Actions\Applications\ApplicationValidator;
use App\Actions\Applications\SubmitApplication;
use App\Enums\ApplicationStep;
use App\Livewire\Applicant\Concerns\WizardStep;
use App\Models\Application;
use Illuminate\Validation\ValidationException;
use Livewire\Component;

/**
 * Final review and submission (PRD 20).
 *
 * The checklist shown here is the same one SubmitApplication enforces, so an
 * applicant is never told they are ready and then refused.
 */
class ReviewAndSubmit extends Component
{
    use WizardStep;

    public bool $confirmed = false;

    protected function step(): ApplicationStep
    {
        return ApplicationStep::Review;
    }

    public function mount(Application $application): void
    {
        $this->mountWizardStep($application);
    }

    public function submit(SubmitApplication $action): void
    {
        if (! $this->confirmed) {
            $this->addError('confirmed', 'Please confirm you have reviewed your application.');

            return;
        }

        try {
            $action->execute($this->application);
        } catch (ValidationException $e) {
            foreach ((array) $e->errors()['application'] ?? [] as $message) {
                $this->addError('submission', $message);
            }

            return;
        }

        session()->flash('status', 'Your application has been submitted. We have emailed your confirmation.');

        $this->redirectRoute('applicant.applications.show', $this->application, navigate: true);
    }

    public function render()
    {
        $application = $this->application->load([
            'applicant.qualifications.subjects',
            'choices.programme.school',
            'documents',
            'payments',
            'intake',
        ]);

        return view('livewire.applicant.review-and-submit', [
            'checklist' => app(ApplicationValidator::class)->checklist($application),
            'ready' => app(ApplicationValidator::class)->isReady($application),
        ]);
    }
}
