<?php

namespace Tests\Feature\Admin;

use App\Http\Middleware\UUIDCheckMiddleware;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Laravel\Sanctum\Sanctum;
use Tests\Support\CreatesAdminApiUser;
use Tests\TestCase;

class EstacionesOmitidasAdminTest extends TestCase
{
    use CreatesAdminApiUser;
    use RefreshDatabase;

    private const INDEX_ENDPOINT = '/api/admin/estaciones-omitidas';

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

        $this->withoutMiddleware(UUIDCheckMiddleware::class);
        $this->withHeader('X-Requested-With', 'XMLHttpRequest');
    }

    /**
     * Mantiene el listado bajo permisos root porque permite corregir e
     * incorporar registros en el catálogo oficial de estaciones.
     */
    public function test_requires_root_permissions_to_list_omitted_rows(): void
    {
        [$admin] = $this->createAdminApiUser(false);
        Sanctum::actingAs($admin, ['admin']);

        $response = $this->getJson(self::INDEX_ENDPOINT);

        $response->assertStatus(406);
    }

    /**
     * Expone omitidas persistidas para que operación pueda revisarlas luego
     * del import sin depender del popup transitorio del resumen.
     */
    public function test_lists_persisted_omitted_rows(): void
    {
        [$admin] = $this->createAdminApiUser();
        Sanctum::actingAs($admin, ['admin']);

        DB::query()->from('estaciones_import_omitidas')->insert([
            'batch_id' => 'batch-test-001',
            'row_number' => 21,
            'direccion' => 'Ruta 5, Km. 1',
            'coordenadas' => '-22.56323, -55.71883',
            'ciudad' => 'Ciudad Falsa',
            'departamento' => 'Amambay',
            'failed_field' => 'ciudad',
            'reason' => 'No se encontró una ciudad normalizada que coincida con la fila.',
            'row_data' => json_encode([
                'direccion_yo_localidad' => 'Ruta 5, Km. 1',
                'coordenadas' => '-22.56323, -55.71883',
                'ciudad' => 'Ciudad Falsa',
                'departamento' => 'Amambay',
            ]),
            'status' => 'pendiente',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        $response = $this->getJson(self::INDEX_ENDPOINT);

        $response->assertOk();
        $response->assertJsonPath('data.0.attributes.row_number', 21);
        $response->assertJsonPath('data.0.attributes.failed_field', 'ciudad');
        $response->assertJsonPath('data.0.attributes.status', 'pendiente');
    }

    /**
     * Permite resolver una omitida puntual asignando manualmente la ciudad
     * oficial elegida desde el admin.
     */
    public function test_resolves_omitted_row_and_creates_station(): void
    {
        [$admin] = $this->createAdminApiUser();
        Sanctum::actingAs($admin, ['admin']);

        $cityId = $this->createCatalogCity('Pedro Juan Caballero', 'Amambay');

        $omittedId = DB::query()->from('estaciones_import_omitidas')->insertGetId([
            'batch_id' => 'batch-test-002',
            'row_number' => 22,
            'direccion' => 'Ruta 5, Km. 1',
            'coordenadas' => '-22.56323, -55.71883',
            'ciudad' => 'Pedro Juan Caballero',
            'departamento' => 'Amambay',
            'failed_field' => 'ciudad',
            'reason' => 'No se encontró una ciudad normalizada que coincida con la fila.',
            'row_data' => json_encode([
                'direccion_yo_localidad' => 'Ruta 5, Km. 1',
                'coordenadas' => '-22.56323, -55.71883',
                'ciudad' => 'Pedro Juan Caballero',
                'departamento' => 'Amambay',
            ]),
            'status' => 'pendiente',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        $response = $this->postJson("/api/admin/estaciones-omitidas/{$omittedId}/resolve", [
            'direccion' => 'Ruta 5, Km. 1',
            'coordenadas' => '-22.56323, -55.71883',
            'ciudad' => 'Pedro Juan Caballero',
            'departamento' => 'Amambay',
            'resolved_ciudad_id' => $cityId,
        ]);

        $response->assertOk();
        $response->assertJson([
            'status' => 'resuelto',
        ]);

        $this->assertDatabaseHas('estaciones', [
            'direccion' => 'Ruta 5, Km. 1',
            'ciudad_id' => $cityId,
        ]);

        $this->assertDatabaseHas('estaciones_import_omitidas', [
            'id' => $omittedId,
            'resolved_ciudad_id' => $cityId,
            'status' => 'resuelto',
        ]);
    }

    /**
     * Catálogo mínimo de ciudad/departamento para el flujo de resolución.
     */
    private function createCatalogCity(string $city, string $department): int
    {
        $departmentId = DB::query()
            ->from('departamentos')
            ->where('nombre', $department)
            ->value('id');

        if ($departmentId === null) {
            $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' => -22.56000,
            'longitud' => -55.72000,
            'departamento_id' => $departmentId,
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    }
}
