<?php

namespace Tests\Feature\Api\V1\Promotions;

use App\Models\StudentPromotionRecord;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class ParentPromotionControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_overview_returns_actionable_records_for_parent(): void
    {
        $parent = $this->seedParent();
        $studentId = $this->seedStudent($parent->id);
        $this->seedPromotionRecord($studentId, $parent->id);

        Sanctum::actingAs($parent);
        $response = $this->getJson('/api/v1/parents/promotions');

        $response->assertOk();
        $response->assertJsonPath('ok', true);
        $response->assertJsonPath('records.0.parent_action_required', true);
        $response->assertJsonPath('records.0.promoted_level', 'Grade 4');
    }

    public function test_parent_completes_full_enrollment_flow(): void
    {
        $parent = $this->seedParent();
        $studentId = $this->seedStudent($parent->id);
        $promotionId = $this->seedPromotionRecord($studentId, $parent->id);

        Sanctum::actingAs($parent);

        // Start enrollment
        $start = $this->postJson('/api/v1/parents/promotions/' . $promotionId . '/start');
        $start->assertOk();
        $start->assertJsonPath('data.promotion_status', StudentPromotionRecord::STATUS_ENROLLMENT_STARTED);

        // Complete the checklist incrementally
        $update = $this->patchJson('/api/v1/parents/promotions/' . $promotionId . '/steps', [
            'info_confirmed' => true,
            'documents_uploaded' => true,
            'agreement_accepted' => true,
        ]);
        $update->assertOk();
        $update->assertJsonPath('data.promotion_status', StudentPromotionRecord::STATUS_ENROLLMENT_STARTED);

        // Final step finalises promotion
        $finish = $this->patchJson('/api/v1/parents/promotions/' . $promotionId . '/steps', [
            'payment_completed' => true,
        ]);
        $finish->assertOk();
        $finish->assertJsonPath('data.promotion_status', StudentPromotionRecord::STATUS_PROMOTED_AND_ENROLLED);

        $this->assertDatabaseHas('enrollments', [
            'student_id' => $studentId,
            'school_year' => '2026-2027',
            'enrollment_status' => 'enrolled',
        ]);
    }

    public function test_parent_cannot_view_other_parents_promotion(): void
    {
        $parentA = $this->seedParent('A', 'a@example.com');
        $parentB = $this->seedParent('B', 'b@example.com');
        $studentId = $this->seedStudent($parentB->id);
        $promotionId = $this->seedPromotionRecord($studentId, $parentB->id);

        Sanctum::actingAs($parentA);
        $response = $this->getJson('/api/v1/parents/promotions/' . $promotionId);
        $response->assertStatus(403);
    }

    public function test_unauthenticated_request_is_unauthorized(): void
    {
        $response = $this->getJson('/api/v1/parents/promotions');
        $response->assertStatus(401);
    }

    private function seedParent(string $name = 'Parent', string $email = 'parent@example.com'): User
    {
        DB::table('roles')->insertOrIgnore([
            ['id' => 2, 'name' => 'parent', 'slug' => 'parent', 'is_active' => 1],
        ]);

        $userId = DB::table('users')->insertGetId([
            'firstname' => $name,
            'lastname' => 'User',
            'cellphone' => '5550000000',
            'email' => $email,
            'address_street' => '1 Way',
            'city' => 'C',
            'state' => 'S',
            'zip' => '00000',
            'accept_school_policy' => 1,
            'password' => bcrypt('secret'),
            'user_type' => 'primary',
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'status' => 'Active',
        ]);

        DB::table('user_roles')->insert([
            'user_id' => $userId,
            'role_id' => 2,
        ]);

        return User::query()->findOrFail($userId);
    }

    private function seedStudent(int $parentId): int
    {
        return (int) DB::table('students')->insertGetId([
            'school_id' => 'S-1',
            'firstname' => 'Sara',
            'lastname' => 'Test',
            'parent_id' => $parentId,
            'year_of_registration' => '2025',
            'school_year' => '2025-2026',
            'semester' => 'Fall',
        ]);
    }

    private function seedPromotionRecord(int $studentId, int $parentId): int
    {
        $record = StudentPromotionRecord::query()->create([
            'student_id' => $studentId,
            'parent_id' => $parentId,
            'current_school_year' => '2025-2026',
            'next_school_year' => '2026-2027',
            'promotion_status' => StudentPromotionRecord::STATUS_AWAITING_PARENT,
            'enrollment_required' => true,
            'enrollment_status' => StudentPromotionRecord::ENROLLMENT_NOT_STARTED,
            'current_level_name' => 'Grade 3',
            'promoted_level_name' => 'Grade 4',
            'enrollment_deadline' => now()->addDays(30)->toDateString(),
        ]);
        return (int) $record->getKey();
    }
}
