<?php

declare(strict_types=1);

use App\Models\Project;
use App\Models\SupplierManualSyncQueue;
use App\Models\Tenant;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;

uses(DatabaseTransactions::class);

it('table supplier_manual_sync_queue exists with required columns', function (): void {
    $cols = collect(DB::select(
        "SELECT column_name FROM information_schema.columns WHERE table_name = 'supplier_manual_sync_queue'"
    ))->pluck('column_name')->all();

    expect($cols)->toContain(
        'id', 'project_id', 'platform', 'operation', 'external_id',
        'payload_snapshot', 'failure_reason', 'status',
        'resolved_by_user_id', 'created_at', 'resolved_at',
    );
});

it('platform CHECK constraint rejects non-B1/B2/B3', function (): void {
    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();

    expect(fn () => DB::table('supplier_manual_sync_queue')->insert([
        'project_id' => $project->id,
        'platform' => 'B9',
        'operation' => 'create',
        'payload_snapshot' => json_encode([]),
        'failure_reason' => 'portal_unreachable',
        'status' => 'pending',
        'created_at' => now(),
    ]))->toThrow(QueryException::class);
});

it('operation CHECK constraint rejects non-create/update', function (): void {
    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();

    expect(fn () => DB::table('supplier_manual_sync_queue')->insert([
        'project_id' => $project->id,
        'platform' => 'B1',
        'operation' => 'delete',
        'payload_snapshot' => json_encode([]),
        'failure_reason' => 'portal_unreachable',
        'status' => 'pending',
        'created_at' => now(),
    ]))->toThrow(QueryException::class);
});

it('status CHECK constraint rejects non-pending/resolved/cancelled', function (): void {
    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();

    expect(fn () => DB::table('supplier_manual_sync_queue')->insert([
        'project_id' => $project->id,
        'platform' => 'B1',
        'operation' => 'create',
        'payload_snapshot' => json_encode([]),
        'failure_reason' => 'portal_unreachable',
        'status' => 'archived',
        'created_at' => now(),
    ]))->toThrow(QueryException::class);
});

it('FK on project_id enforces referential integrity', function (): void {
    expect(fn () => DB::table('supplier_manual_sync_queue')->insert([
        'project_id' => 999_999_999,
        'platform' => 'B1',
        'operation' => 'create',
        'payload_snapshot' => json_encode([]),
        'failure_reason' => 'portal_unreachable',
        'status' => 'pending',
        'created_at' => now(),
    ]))->toThrow(QueryException::class);
});

it('Eloquent model SupplierManualSyncQueue creates row and casts payload_snapshot to array', function (): void {
    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();

    $row = SupplierManualSyncQueue::create([
        'project_id' => $project->id,
        'platform' => 'B1',
        'operation' => 'create',
        'payload_snapshot' => ['limit' => 10, 'workdays' => [1, 2, 3]],
        'failure_reason' => 'contract_break',
        'status' => 'pending',
    ]);

    expect($row->fresh()->payload_snapshot)->toBe(['limit' => 10, 'workdays' => [1, 2, 3]]);
});
