<?php

namespace Tests\Feature\Front;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;

class EstacionesEndpointTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Confirma que la geolocalización pública ordena por cercanía real y
     * devuelve la distancia para comunicar el resultado en pantalla.
     */
    public function test_orders_stations_by_distance_when_location_is_provided(): void
    {
        $cityId = $this->createCatalogCity('Asunción', 'Capital');

        DB::query()->from('estaciones')->insert([
            [
                'titulo' => '',
                'slug' => 'cerca',
                'estado' => true,
                'ciudad_id' => $cityId,
                'ubicacion' => json_encode(['lat' => -25.3000, 'lng' => -57.6000]),
                'direccion' => 'Estación cercana',
                'created_at' => now(),
                'updated_at' => now(),
            ],
            [
                'titulo' => '',
                'slug' => 'lejos',
                'estado' => true,
                'ciudad_id' => $cityId,
                'ubicacion' => json_encode(['lat' => -25.5000, 'lng' => -57.9000]),
                'direccion' => 'Estación lejana',
                'created_at' => now(),
                'updated_at' => now(),
            ],
        ]);

        $response = $this->getJson('/endpoint/estaciones?nearest=1&lat=-25.3010&lng=-57.6010');

        $response->assertOk();
        $response->assertJsonPath('estaciones.data.0.direccion', 'Estación cercana');
        $response->assertJsonPath('estaciones.data.1.direccion', 'Estación lejana');
        $response->assertJsonStructure([
            'estaciones' => [
                'data' => [
                    ['distance_km'],
                ],
            ],
        ]);
    }

    /**
     * Endurece el endpoint frente a coordenadas inválidas o a requests que
     * pidan cercanía sin enviar una ubicación completa.
     */
    public function test_validates_coordinates_for_nearest_search(): void
    {
        $response = $this->getJson('/endpoint/estaciones?nearest=1&lat=-25.3010');

        $response->assertStatus(422);
        $response->assertJsonValidationErrors(['nearest']);
    }

    /**
     * Catálogo mínimo para la relación ciudad/departamento del endpoint.
     */
    private function createCatalogCity(string $city, string $department): int
    {
        $departmentId = DB::query()->from('departamentos')->insertGetId([
            'nombre' => $department,
            'slug' => str_slug($department),
            'estado' => true,
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return DB::query()->from('ciudades')->insertGetId([
            'nombre' => $city,
            'slug' => str_slug($city),
            'latitud' => -25.30,
            'longitud' => -57.60,
            'departamento_id' => $departmentId,
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    }
}
