<?php

use App\Models\SolicitudBien;
use App\Models\Usuario;
use App\Services\ShipMarketService;
use Illuminate\Http\Request;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

beforeEach(function (): void {
    if (Schema::hasTable('solicitud_bienes')) {
        Schema::drop('solicitud_bienes');
    }

    Schema::create('solicitud_bienes', function (Blueprint $table): void {
        $table->id();
        $table->string('numero_solicitud', 40)->unique();
        $table->string('solicitante_cedula', 40)->index();
        $table->string('estado', 40)->default('pendiente')->index();
        $table->unsignedInteger('articulos_count')->default(0);
        $table->unsignedInteger('unidades_count')->default(0);
        $table->text('detalle_json');
        $table->text('observaciones')->nullable();
        $table->timestamp('fecha_solicitud')->nullable();
        $table->timestamps();
    });
});

afterEach(function (): void {
    Schema::dropIfExists('solicitud_bienes');
});

it('allows admin users to access solicitudes de bienes crud', function (): void {
    $user = new Usuario(['cargo' => 'Administrador', 'tipo' => 1]);
    $user->id = 9101;

    $this->actingAs($user)
        ->get(route('administracion.crud.index', ['entity' => 'solicitudes-bienes']))
        ->assertOk()
        ->assertSee('Solicitudes de Bienes');
});

    it('allows superusuario users to access solicitudes de bienes crud', function (): void {
        $user = new Usuario(['cargo' => 'Superusuario', 'tipo' => 8]);
        $user->id = 9105;

        $this->actingAs($user)
        ->get(route('administracion.crud.index', ['entity' => 'solicitudes-bienes']))
        ->assertOk()
        ->assertSee('Solicitudes de Bienes');
    });

it('blocks almacenista users from accessing solicitudes de bienes crud', function (): void {
    $user = new Usuario(['cargo' => 'Almacenista', 'tipo' => 2]);
    $user->id = 9102;

    $this->actingAs($user)
        ->get(route('administracion.crud.index', ['entity' => 'solicitudes-bienes']))
        ->assertForbidden();
});

it('generates a solicitud de bienes from the ship market cart', function (): void {
    $user = new Usuario(['cargo' => 'Solicitante', 'tipo' => 7, 'cedula' => '12345678', 'nombre' => 'Usuario Demo']);
    $user->id = 9103;

    $service = new class extends ShipMarketService {
        public function cartQuantities(Request $request): array
        {
            return ['ABS001' => 2];
        }

        public function buildCartData(array $cart): array
        {
            return [
                'items' => [[
                    'codigo' => 'ABS001',
                    'descripcion' => 'Bien de prueba',
                    'cantidad' => 2,
                    'stock_disponible' => 5,
                    'tipo' => 'Dotacion',
                ]],
                'summary' => ['lineas' => 1, 'unidades' => 2],
                'quantities' => ['ABS001' => 2],
            ];
        }

        public function clearCart(Request $request): void
        {
        }
    };

    $this->app->instance(ShipMarketService::class, $service);

    $response = $this->actingAs($user)->postJson(route('ship-market.solicitudes.store'));

    $response->assertOk();
    $response->assertJsonPath('message', 'Solicitud generada correctamente.');
    $response->assertJsonPath('cart.summary.lineas', 0);
});

it('replaces the active solicitud de bienes from the same solicitante', function (): void {
    $user = new Usuario(['cargo' => 'Solicitante', 'tipo' => 7, 'cedula' => '12345678', 'nombre' => 'Usuario Demo']);
    $user->id = 9104;

    $solicitud = SolicitudBien::query()->create([
        'numero_solicitud' => 'SM-OLD-000001',
        'solicitante_cedula' => '12345678',
        'estado' => 'generada',
        'articulos_count' => 1,
        'unidades_count' => 1,
        'detalle_json' => json_encode([['codigo' => 'OLD001', 'descripcion' => 'Anterior', 'cantidad' => 1]]),
        'fecha_solicitud' => now()->subDay(),
    ]);

    $service = new class extends ShipMarketService {
        public function cartQuantities(Request $request): array
        {
            return ['ABS001' => 3];
        }

        public function buildCartData(array $cart): array
        {
            return [
                'items' => [[
                    'codigo' => 'ABS001',
                    'descripcion' => 'Bien de reemplazo',
                    'cantidad' => 3,
                    'stock_disponible' => 5,
                    'tipo' => 'Dotacion',
                ]],
                'summary' => ['lineas' => 1, 'unidades' => 3],
                'quantities' => ['ABS001' => 3],
            ];
        }

        public function clearCart(Request $request): void
        {
        }
    };

    $this->app->instance(ShipMarketService::class, $service);

    $response = $this->actingAs($user)->postJson(route('ship-market.solicitudes.store'));

    $response->assertOk();
    $response->assertJsonPath('message', 'Solicitud reemplazada correctamente.');
    $response->assertJsonPath('replaced_previous', true);

    expect(SolicitudBien::query()->count())->toBe(1);

    $solicitud->refresh();

    expect($solicitud->numero_solicitud)->not->toBe('SM-OLD-000001')
        ->and($solicitud->articulos_count)->toBe(1)
        ->and($solicitud->unidades_count)->toBe(3)
        ->and((string) data_get($solicitud->detalle_json, '0.codigo'))->toBe('ABS001');
});

it('renders a replacement modal when the solicitante already has an active solicitud', function (): void {
    $user = new Usuario(['cargo' => 'Solicitante', 'tipo' => 7, 'cedula' => '12345678', 'nombre' => 'Usuario Demo']);
    $user->id = 9105;

    SolicitudBien::query()->create([
        'numero_solicitud' => 'SM-ACTIVA-000001',
        'solicitante_cedula' => '12345678',
        'estado' => 'generada',
        'articulos_count' => 1,
        'unidades_count' => 1,
        'detalle_json' => json_encode([['codigo' => 'ABS001', 'descripcion' => 'Bien activo', 'cantidad' => 1]]),
        'fecha_solicitud' => now(),
    ]);

    $service = new class extends ShipMarketService {
        public function cartQuantities(Request $request): array
        {
            return [];
        }

        public function buildCatalogData(Request $request, array $cart): array
        {
            return [
                'filters' => ['q' => '', 'tipo' => 0],
                'typeOptions' => [],
                'items' => [],
                'totals' => ['bienes_disponibles' => 0, 'unidades_disponibles' => 0],
            ];
        }

        public function buildCartData(array $cart): array
        {
            return [
                'items' => [],
                'summary' => ['lineas' => 0, 'unidades' => 0],
                'quantities' => [],
            ];
        }
    };

    $this->app->instance(ShipMarketService::class, $service);

    $response = $this->actingAs($user)->get(route('ship-market.index'));

    $response->assertOk();
    $response->assertSee('Reemplazar solicitud actual');
    $response->assertSee('La solicitud SM-ACTIVA-000001 sera reemplazada por la nueva solicitud.');
});