<?php

namespace Tests\Feature;

use App\Models\Avaliacao;
use App\Models\PontoTuristico;
use App\Models\Restaurante;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class AvaliacaoTest extends TestCase
{
    use RefreshDatabase;

    private function criarPonto(): PontoTuristico
    {
        $admin = User::factory()->create(['role' => 'admin']);
        return PontoTuristico::create([
            'nome' => 'Ponto', 'tipo' => 'ponto_turistico', 'endereco' => 'R. X',
            'cidade' => 'Rio', 'estado' => 'RJ', 'latitude' => -22.95, 'longitude' => -43.21,
            'status' => 'ativo', 'criado_por' => $admin->id,
        ]);
    }

    public function test_criar_avaliacao_ponto(): void
    {
        $user  = User::factory()->create();
        $ponto = $this->criarPonto();

        $response = $this->actingAs($user)->postJson('/api/v1/avaliacoes', [
            'tipo'       => 'ponto',
            'id'         => $ponto->id,
            'nota'       => 5,
            'comentario' => 'Excelente!',
        ]);

        $response->assertOk()
            ->assertJsonPath('data.nota', 5);

        $this->assertDatabaseHas('avaliacoes', [
            'user_id'       => $user->id,
            'avaliavel_type' => PontoTuristico::class,
            'avaliavel_id'  => $ponto->id,
            'nota'          => 5,
        ]);
    }

    public function test_criar_avaliacao_restaurante(): void
    {
        $user = User::factory()->create();
        $rest = Restaurante::create([
            'nome' => 'Rest', 'tipo_comida' => 'brasileira', 'preco_medio' => 50,
            'endereco' => 'R. X', 'cidade' => 'Rio', 'estado' => 'RJ',
            'latitude' => -22.95, 'longitude' => -43.21, 'status' => 'ativo',
        ]);

        $response = $this->actingAs($user)->postJson('/api/v1/avaliacoes', [
            'tipo' => 'restaurante',
            'id'   => $rest->id,
            'nota' => 4,
        ]);

        $response->assertOk()
            ->assertJsonPath('data.nota', 4);
    }

    public function test_avaliacao_update_or_create(): void
    {
        $user  = User::factory()->create();
        $ponto = $this->criarPonto();

        // Primeira avaliação
        $this->actingAs($user)->postJson('/api/v1/avaliacoes', [
            'tipo' => 'ponto', 'id' => $ponto->id, 'nota' => 3,
        ])->assertOk();

        // Atualizar avaliação (mesmo user + ponto)
        $this->actingAs($user)->postJson('/api/v1/avaliacoes', [
            'tipo' => 'ponto', 'id' => $ponto->id, 'nota' => 5, 'comentario' => 'Mudei de ideia!',
        ])->assertOk();

        $this->assertCount(1, Avaliacao::where('user_id', $user->id)->get());
        $this->assertEquals(5, Avaliacao::where('user_id', $user->id)->first()->nota);
    }

    public function test_listar_avaliacoes_de_ponto(): void
    {
        $user1 = User::factory()->create();
        $user2 = User::factory()->create();
        $ponto = $this->criarPonto();

        Avaliacao::create(['user_id' => $user1->id, 'avaliavel_type' => PontoTuristico::class, 'avaliavel_id' => $ponto->id, 'nota' => 5]);
        Avaliacao::create(['user_id' => $user2->id, 'avaliavel_type' => PontoTuristico::class, 'avaliavel_id' => $ponto->id, 'nota' => 3]);

        $response = $this->getJson("/api/v1/pontos-turisticos/{$ponto->id}/avaliacoes");

        $response->assertOk()
            ->assertJsonCount(2, 'data.data');
    }

    public function test_avaliacao_nao_autenticado(): void
    {
        $this->postJson('/api/v1/avaliacoes', [
            'tipo' => 'ponto', 'id' => 1, 'nota' => 5,
        ])->assertStatus(401);
    }
}
