<?php

namespace Tests;

use App\Actions\Applications\StartApplication;
use App\Models\Applicant;
use App\Models\Application;
use App\Models\Intake;
use App\Models\Role;
use App\Models\User;
use Database\Seeders\AcademicStructureSeeder;
use Database\Seeders\DocumentTypeSeeder;
use Database\Seeders\IntakeSeeder;
use Database\Seeders\RolePermissionSeeder;
use Database\Seeders\SettingsSeeder;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Hash;

abstract class TestCase extends BaseTestCase
{
    /**
     * Load the platform's own reference data so tests exercise the same
     * roles, permissions, settings and catalogue the application ships with.
     */
    protected function seedPlatform(): void
    {
        $this->seed([
            RolePermissionSeeder::class,
            SettingsSeeder::class,
            AcademicStructureSeeder::class,
            IntakeSeeder::class,
            DocumentTypeSeeder::class,
        ]);
    }

    protected function staff(string $roleSlug): User
    {
        $user = User::create([
            'name' => 'Staff '.$roleSlug,
            'email' => $roleSlug.'-'.uniqid().'@kcu.test',
            'password' => Hash::make('password'),
        ]);

        $user->forceFill(['status' => 'active', 'email_verified_at' => now()])->save();

        $role = Role::where('slug', $roleSlug)->firstOrFail();
        $user->roles()->attach($role);

        return $user->fresh('roles.permissions');
    }

    protected function applicant(array $attributes = []): Applicant
    {
        $user = User::create([
            'name' => 'Test Applicant',
            'email' => 'applicant-'.uniqid().'@kcu.test',
            'phone' => '0771234567',
            'password' => Hash::make('password'),
        ]);

        $user->forceFill(['status' => 'active', 'email_verified_at' => now()])->save();

        return Applicant::create(array_merge([
            'user_id' => $user->id,
            'first_name' => 'Test',
            'last_name' => 'Applicant',
            'phone' => '0771234567',
            'country' => 'Uganda',
        ], $attributes));
    }

    /** An applicant whose personal, contact and academic details are complete. */
    protected function completeApplicant(): Applicant
    {
        $applicant = $this->applicant([
            'date_of_birth' => now()->subYears(20)->toDateString(),
            'gender' => 'female',
            'nationality' => 'Ugandan',
            'national_id' => 'CM90123456ABCD',
            'district' => 'Kampala',
            'address' => 'Bunga Hill',
            'guardian_name' => 'Jane Doe',
            'guardian_relationship' => 'Parent',
            'guardian_phone' => '0700111222',
        ]);

        $qualification = $applicant->qualifications()->create([
            'qualification_type' => 'uace',
            'institution' => 'Kampala SS',
            'year' => now()->year - 1,
            'index_number' => 'U0123/501',
        ]);

        $qualification->subjects()->createMany([
            ['subject' => 'Biology', 'grade' => 'B', 'points' => 5],
            ['subject' => 'Chemistry', 'grade' => 'B', 'points' => 5],
            ['subject' => 'Mathematics', 'grade' => 'C', 'points' => 4],
        ]);

        return $applicant->fresh(['qualifications.subjects', 'user']);
    }

    protected function startApplication(Applicant $applicant, ?Intake $intake = null): Application
    {
        return app(StartApplication::class)->execute($applicant, $intake ?? Intake::current());
    }
}
