<?php

namespace Tests\Feature;

use App\Livewire\AssessmentRunner;
use App\Models\Assessment;
use App\Models\AssessmentAttempt;
use Database\Seeders\ChamaHealthSeeder;
use Database\Seeders\MoneyPersonalitySeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;

class NewToolsTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();

        $this->seed(MoneyPersonalitySeeder::class);
        $this->seed(ChamaHealthSeeder::class);
    }

    private function answersByType(Assessment $assessment, string $type): array
    {
        return $assessment->questions->mapWithKeys(function ($q) use ($type) {
            $option = collect($q->options)->firstWhere('type', $type);

            return [$q->id => $option['key']];
        })->all();
    }

    public function test_personality_test_assigns_dominant_type_band(): void
    {
        $assessment = Assessment::where('slug', 'money-personality')->firstOrFail();

        Livewire::test(AssessmentRunner::class, ['assessment' => $assessment])
            ->call('submit', $this->answersByType($assessment, 'amasser'), 'Tester', 'newtools@example.com');

        $attempt = AssessmentAttempt::firstOrFail();

        $this->assertSame('The Amasser', $attempt->band->label);
        $this->assertSame(100.0, (float) $attempt->percent);
        $this->assertSame(100, $attempt->dimension_percents['amasser']);
        $this->assertSame(0, $attempt->dimension_percents['hoarder']);
    }

    public function test_personality_results_page_renders_type(): void
    {
        $assessment = Assessment::where('slug', 'money-personality')->firstOrFail();

        Livewire::test(AssessmentRunner::class, ['assessment' => $assessment])
            ->call('submit', $this->answersByType($assessment, 'spender'), 'Tester', 'newtools@example.com');

        $attempt = AssessmentAttempt::firstOrFail();

        $this->get(route('assessments.results', ['assessment' => 'money-personality', 'attempt' => $attempt->uuid]))
            ->assertOk()
            ->assertSee('The Spender')
            ->assertSee('Your personality blend');
    }

    public function test_chama_health_check_scores_and_bands(): void
    {
        $assessment = Assessment::where('slug', 'chama-health')->firstOrFail();

        $answers = $assessment->questions->mapWithKeys(fn ($q) => [$q->id => $q->options[0]['key']])->all();

        Livewire::test(AssessmentRunner::class, ['assessment' => $assessment])
            ->call('submit', $answers, 'Tester', 'newtools@example.com');

        $attempt = AssessmentAttempt::firstOrFail();

        $this->assertSame('The Institution', $attempt->band->label);
        $this->assertSame(100.0, (float) $attempt->percent);
    }

    public function test_new_tool_pages_render_and_save(): void
    {
        foreach (['values-clarification', 'wealth-goals'] as $tool) {
            $this->get("/tools/{$tool}")->assertOk();

            $this->postJson("/tools/{$tool}/save", [
                'email' => "saver-{$tool}@example.com",
                'inputs' => ['sample' => true],
                'outputs' => ['sample' => true],
            ])->assertOk();

            $this->assertDatabaseHas('tool_results', ['tool' => $tool]);
        }
    }

    public function test_newsletter_signup_creates_lead(): void
    {
        $this->postJson('/newsletter', ['email' => 'reader@example.com'])
            ->assertOk()
            ->assertJson(['subscribed' => true]);

        $this->assertDatabaseHas('leads', ['email' => 'reader@example.com', 'source' => 'newsletter']);
    }
}
