<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Models\Company;
use App\Models\HeldPayment;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
use PHPUnit\Framework\Attributes\Test;
use RuntimeException;
use Tests\TestCase;

/**
 * `held_payments` es la única copia de cobros que el cliente sí entregó: revertir
 * la migración no puede borrarlos. El borrado de la tabla se simula (Schema
 * falso): la base de los tests es la de desarrollo y un DROP no se revierte.
 */
class HeldPaymentsMigrationTest extends TestCase
{
    use DatabaseTransactions;

    private function migration(): Migration
    {
        return require database_path('migrations/2026_09_24_120000_create_held_payments_table.php');
    }

    #[Test]
    public function revertir_con_cobros_retenidos_se_niega_y_no_borra_la_tabla(): void
    {
        HeldPayment::create([
            'company_id' => Company::factory()->create()->id,
            'idempotency_key' => (string) Str::uuid(),
            'reason' => HeldPayment::REASON_STALE,
            'payload' => [],
            'status' => HeldPayment::STATUS_PENDING,
        ]);
        Schema::shouldReceive('hasTable')->with('held_payments')->andReturn(true);
        Schema::shouldReceive('dropIfExists')->never();

        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('contiene cobros retenidos');

        $this->migration()->down();
    }

    #[Test]
    public function revertir_con_la_tabla_vacia_la_borra(): void
    {
        DB::table('held_payments')->delete();
        Schema::shouldReceive('hasTable')->with('held_payments')->andReturn(true);
        Schema::shouldReceive('dropIfExists')->once()->with('held_payments');

        $this->migration()->down();
    }
}
