<?php

namespace Tests\Unit\Models;

use App\Models\StageResponse;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\Feature\Concerns\BuildsFeatureData;
use Tests\TestCase;

class ApplicationModelTest extends TestCase
{
    use BuildsFeatureData;
    use DatabaseTransactions;

    public function test_document_paths_support_json_and_legacy_string_values(): void
    {
        $applicant = $this->createApplicant();
        $job = $this->createJob();

        $applicationJson = $this->createJobApplication($applicant, $job, [
            'cv_path' => json_encode(['documents/cv.pdf', 'documents/portfolio.pdf']),
        ]);

        $this->assertSame(['documents/cv.pdf', 'documents/portfolio.pdf'], $applicationJson->document_paths);
        $this->assertSame('documents/cv.pdf', $applicationJson->effective_cv_path);
        $this->assertTrue($applicationJson->hasDocuments());
        $this->assertTrue($applicationJson->hasCv());

        $applicationLegacy = $this->createJobApplication($applicant, $job, [
            'cv_path' => 'documents/legacy-cv.pdf',
        ]);

        $this->assertSame(['documents/legacy-cv.pdf'], $applicationLegacy->document_paths);
        $this->assertSame('documents/legacy-cv.pdf', $applicationLegacy->effective_cv_path);

        $applicationEmpty = $this->createJobApplication($applicant, $job, [
            'cv_path' => null,
        ]);

        $this->assertSame([], $applicationEmpty->document_paths);
        $this->assertNull($applicationEmpty->effective_cv_path);
        $this->assertFalse($applicationEmpty->hasDocuments());
    }

    public function test_can_detect_filled_stage_and_fetch_stage_response(): void
    {
        $applicant = $this->createApplicant();
        $job = $this->createJob();
        $stage = $this->createStage($job, [
            'stage_number' => 1,
            'name' => 'Tahap Screening',
            'sort_order' => 1,
        ]);

        $application = $this->createJobApplication($applicant, $job, [
            'status' => 'stage1_passed',
            'current_stage' => 1,
        ]);

        $this->assertFalse($application->hasFilledStage($stage->id));
        $this->assertNull($application->getResponseForStage($stage->id));

        StageResponse::create([
            'application_id' => $application->id,
            'job_stage_id' => $stage->id,
            'responses' => ['motivasi' => ['value' => 'Saya siap']],
            'submitted_at' => now(),
        ]);

        $application->refresh();

        $this->assertTrue($application->hasFilledStage($stage->id));
        $this->assertNotNull($application->getResponseForStage($stage->id));

        $application->load('stageResponses');
        $this->assertTrue($application->hasFilledStage($stage->id));
    }

    public function test_get_next_form_stage_follows_current_passed_status(): void
    {
        $applicant = $this->createApplicant();
        $job = $this->createJob();
        $stage1 = $this->createStage($job, [
            'stage_number' => 1,
            'name' => 'Tahap 1',
            'sort_order' => 1,
        ]);
        $stage2 = $this->createStage($job, [
            'stage_number' => 2,
            'name' => 'Tahap 2',
            'sort_order' => 2,
        ]);

        $application = $this->createJobApplication($applicant, $job, [
            'status' => 'stage1_passed',
            'current_stage' => 1,
        ]);

        $nextStage = $application->getNextFormStage();
        $this->assertNotNull($nextStage);
        $this->assertSame($stage1->id, $nextStage->id);

        StageResponse::create([
            'application_id' => $application->id,
            'job_stage_id' => $stage1->id,
            'responses' => ['jawaban' => ['value' => 'ok']],
            'submitted_at' => now(),
        ]);

        $application->refresh();
        $this->assertNull($application->getNextFormStage());

        $applicationStage2 = $this->createJobApplication($applicant, $job, [
            'status' => 'stage2_passed',
            'current_stage' => 2,
        ]);

        $nextStage2 = $applicationStage2->getNextFormStage();
        $this->assertNotNull($nextStage2);
        $this->assertSame($stage2->id, $nextStage2->id);
    }

    public function test_status_helpers_and_progress_are_computed_correctly(): void
    {
        $applicant = $this->createApplicant();
        $job = $this->createJob();
        $this->createStage($job, [
            'stage_number' => 1,
            'name' => 'Tahap Screening',
            'sort_order' => 1,
        ]);
        $this->createStage($job, [
            'stage_number' => 2,
            'name' => 'Tahap Interview',
            'sort_order' => 2,
        ]);

        $application = $this->createJobApplication($applicant, $job, [
            'status' => 'stage1_form_filled',
            'current_stage' => 1,
        ]);
        $application->load('jobListing.stages');

        $this->assertSame('Form Terisi: Tahap Screening', $application->status_label);
        $this->assertSame('indigo', $application->status_color);
        $this->assertSame('bg-indigo-100 text-indigo-700', $application->status_badge_class);
        $progress = $application->progress;
        $this->assertSame(2, $progress['current']);
        $this->assertSame(4, $progress['total']);
        $this->assertEquals(50, $progress['percentage']);

        $application->update([
            'status' => 'accepted',
            'final_decision_at' => now(),
        ]);
        $application->refresh()->load('jobListing.stages');

        $this->assertSame('Diterima', $application->status_label);
        $this->assertSame('green', $application->status_color);
        $this->assertEquals(100, $application->progress['percentage']);
    }
}
