<?php

namespace Tests\Feature\Applicants;

use App\Models\Application;
use App\Models\ImportedJob;
use App\Models\JobSource;
use App\Models\Profile;
use App\Models\QuestionnaireResponse;
use App\Models\ResumeReport;
use App\Models\User;
use App\Services\Jobs\JobAiAssistantService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ApplicantProductivityModulesTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_update_job_alert_preferences(): void
    {
        $user = $this->unlockedUser();

        $response = $this
            ->actingAs($user)
            ->patch(route('job-alerts.preferences.update'), [
                'enabled' => '1',
                'frequency' => 'weekly',
                'minimum_match_score' => 72,
                'categories' => ['design', 'support'],
                'keywords' => "Figma\nCustomer Success",
            ]);

        $response->assertRedirect();

        $this->assertDatabaseHas('job_alert_preferences', [
            'user_id' => $user->id,
            'enabled' => true,
            'frequency' => 'weekly',
            'minimum_match_score' => 72,
        ]);

        $preference = $user->jobAlertPreference()->firstOrFail();
        $this->assertSame(['design', 'support'], $preference->categories);
        $this->assertSame(['Figma', 'Customer Success'], $preference->keywords);
    }

    public function test_resume_reupload_creates_version_history_and_current_report(): void
    {
        Storage::fake('local');
        Queue::fake();

        $user = User::factory()->create([
            'questionnaire_completed_at' => now(),
            'access_unlocked_at' => now(),
            'resume_uploaded_at' => now(),
        ]);

        $user->resumeReports()->create([
            'is_current' => true,
            'original_filename' => 'old-resume.pdf',
            'disk' => 'local',
            'path' => 'resumes/'.$user->id.'/old-resume.pdf',
            'mime_type' => 'application/pdf',
            'size_bytes' => 1024,
            'status' => ResumeReport::STATUS_COMPLETED,
            'analyzed_at' => now(),
        ]);

        $this
            ->actingAs($user)
            ->post(route('resume.store'), [
                'resume' => UploadedFile::fake()->create('new-resume.pdf', 10, 'application/pdf'),
            ])
            ->assertRedirect(route('resume.show'));

        $this->assertDatabaseCount('resume_reports', 2);
        $this->assertDatabaseHas('resume_reports', [
            'user_id' => $user->id,
            'original_filename' => 'old-resume.pdf',
            'is_current' => false,
        ]);
        $this->assertSame('new-resume.pdf', $user->fresh()->resumeReport->original_filename);

        $this
            ->actingAs($user)
            ->get(route('resume.history'))
            ->assertOk()
            ->assertSeeText('old-resume.pdf')
            ->assertSeeText('new-resume.pdf');
    }

    public function test_job_note_and_ai_generation_can_update_without_page_reload(): void
    {
        $user = $this->unlockedUser();
        $job = $this->remoteJob();

        $this
            ->actingAs($user)
            ->withHeader('Accept', 'application/json')
            ->patch(route('jobs.notes.update', $job), [
                'body' => 'Ask about async collaboration expectations.',
            ])
            ->assertOk()
            ->assertJsonPath('message', 'Job note saved.');

        $this->assertDatabaseHas('job_notes', [
            'user_id' => $user->id,
            'imported_job_id' => $job->id,
            'body' => 'Ask about async collaboration expectations.',
        ]);

        $this->mock(JobAiAssistantService::class, function ($mock) use ($job): void {
            $mock->shouldReceive('generate')
                ->once()
                ->andReturn([
                    'content' => 'Generated applicant assistance for '.$job->title,
                    'payload' => ['content' => 'Generated applicant assistance for '.$job->title],
                ]);
        });

        $this
            ->actingAs($user)
            ->withHeader('Accept', 'application/json')
            ->post(route('jobs.ai.store', $job), [
                'type' => 'cover_letter',
            ])
            ->assertOk()
            ->assertJsonPath('content', 'Generated applicant assistance for '.$job->title);

        $this->assertDatabaseHas('job_ai_assistances', [
            'user_id' => $user->id,
            'imported_job_id' => $job->id,
            'type' => 'cover_letter',
        ]);
    }

    public function test_application_pipeline_and_follow_up_reminder_are_created(): void
    {
        $user = $this->unlockedUser();
        $job = $this->remoteJob();

        $this->actingAs($user)->post(route('jobs.apply', $job));
        $application = $user->applications()->firstOrFail();
        $followUpDate = now()->addDays(2)->format('Y-m-d');

        $this
            ->actingAs($user)
            ->patch(route('applications.update', $application), [
                'status' => Application::STATUS_FOLLOW_UP_NEEDED,
                'notes' => 'Send follow-up if no recruiter response.',
                'follow_up_at' => $followUpDate,
            ])
            ->assertRedirect();

        $this->assertDatabaseHas('application_follow_up_reminders', [
            'user_id' => $user->id,
            'application_id' => $application->id,
            'due_on' => $followUpDate.' 00:00:00',
            'status' => 'pending',
        ]);

        $this
            ->actingAs($user)
            ->get(route('applications.pipeline'))
            ->assertOk()
            ->assertSeeText('Application pipeline')
            ->assertSeeText('Send follow-up if no recruiter response.');
    }

    private function unlockedUser(): User
    {
        $user = User::factory()->create([
            'questionnaire_completed_at' => now(),
            'access_unlocked_at' => now(),
            'resume_uploaded_at' => now(),
            'resume_analyzed_at' => now(),
            'profile_completed_at' => now(),
        ]);

        QuestionnaireResponse::query()->create([
            'user_id' => $user->id,
            'answers' => [],
            'preferred_categories' => ['design'],
            'preferred_roles' => ['Product Designer'],
            'skills' => ['Figma', 'UI/UX'],
            'experience_level' => 'mid',
            'salary_currency' => 'USD',
            'salary_min' => 80000,
            'open_to_full_time' => true,
            'completed_at' => now(),
        ]);

        ResumeReport::query()->create([
            'user_id' => $user->id,
            'is_current' => true,
            'original_filename' => 'resume.pdf',
            'disk' => 'local',
            'path' => 'resumes/'.$user->id.'/resume.pdf',
            'mime_type' => 'application/pdf',
            'size_bytes' => 1024,
            'status' => ResumeReport::STATUS_COMPLETED,
            'ats_score' => 82,
            'remote_readiness_score' => 90,
            'extracted_skills' => ['Figma', 'UI/UX'],
            'role_suggestions' => ['Product Designer'],
            'missing_keywords' => [],
            'resume_improvements' => [],
            'analysis' => ['summary' => 'Product designer with remote experience.'],
            'analyzed_at' => now(),
        ]);

        Profile::query()->create([
            'user_id' => $user->id,
            'headline' => 'Remote product designer',
            'summary' => 'Designs SaaS product experiences.',
            'current_role' => 'Product Designer',
            'experience_level' => 'mid',
            'skills' => ['Figma', 'UI/UX'],
            'preferred_roles' => ['Product Designer'],
            'preferred_categories' => ['design'],
            'salary_currency' => 'USD',
            'salary_min' => 80000,
            'open_to_full_time' => true,
            'completed_at' => now(),
        ]);

        return $user;
    }

    private function remoteJob(): ImportedJob
    {
        $source = JobSource::query()->create([
            'name' => 'Applicant Productivity Source',
            'slug' => 'applicant-productivity-source',
            'type' => 'manual',
            'base_url' => 'https://jobs.example',
            'attribution_text' => 'Source: Applicant Productivity Source',
            'is_active' => true,
        ]);

        return ImportedJob::query()->create([
            'job_source_id' => $source->id,
            'external_id' => 'applicant-productivity-001',
            'title' => 'Remote Product Designer',
            'company' => 'Remote Design Co',
            'category' => 'design',
            'employment_type' => 'full_time',
            'experience_level' => 'mid',
            'location_type' => 'remote',
            'salary_currency' => 'USD',
            'salary_min' => 90000,
            'salary_max' => 120000,
            'summary' => 'Design remote SaaS workflows.',
            'description' => 'Lead UI/UX work for a distributed SaaS product team.',
            'skills' => ['Figma', 'UI/UX'],
            'tags' => ['remote', 'design'],
            'source_url' => 'https://jobs.example/roles/designer',
            'apply_url' => 'https://jobs.example/roles/designer/apply',
            'source_attribution' => 'Source: Applicant Productivity Source',
            'status' => ImportedJob::STATUS_ACTIVE,
            'posted_at' => now(),
            'last_seen_at' => now(),
        ]);
    }
}
