<?php

declare(strict_types=1);

use Illuminate\Database\QueryException;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

uses(DatabaseTransactions::class);

test('supplier_leads table exists with required columns', function () {
    expect(Schema::hasTable('supplier_leads'))->toBeTrue();

    expect(Schema::hasColumns('supplier_leads', [
        'id',
        'supplier_project_id',
        'platform',
        'raw_payload',
        'vid',
        'phone',
        'received_at',
        'source',
        'processed_at',
        'deals_created_count',
    ]))->toBeTrue();
});

test('supplier_leads has FK to supplier_projects with ON DELETE SET NULL', function () {
    $row = DB::selectOne(
        "SELECT c.confdeltype
         FROM pg_constraint c
         JOIN pg_class t ON c.conrelid = t.oid
         JOIN pg_class r ON c.confrelid = r.oid
         WHERE t.relname = 'supplier_leads'
           AND r.relname = 'supplier_projects'
           AND c.contype = 'f'"
    );

    expect($row)->not->toBeNull();
    // confdeltype: 'a'=NO ACTION, 'r'=RESTRICT, 'c'=CASCADE, 'n'=SET NULL, 'd'=SET DEFAULT
    expect($row->confdeltype)->toBe('n');
});

test('supplier_leads.source has CHECK enum', function () {
    // Valid source: должно пройти.
    $insertedId = DB::table('supplier_leads')->insertGetId([
        'platform' => 'B1',
        'raw_payload' => json_encode(['test' => 'valid_source']),
        'vid' => 1000001,
        'phone' => '+79991234567',
        'source' => 'webhook',
    ]);
    expect($insertedId)->toBeGreaterThan(0);
    DB::table('supplier_leads')->where('id', $insertedId)->delete();

    // Invalid source: должно отклониться CHECK constraint'ом.
    expect(fn () => DB::table('supplier_leads')->insert([
        'platform' => 'B1',
        'raw_payload' => json_encode(['test' => 'invalid']),
        'vid' => 1000002,
        'phone' => '+79991234568',
        'source' => 'invalid_source',
    ]))->toThrow(QueryException::class);
});

test('projects.delivered_today exists with default 0', function () {
    expect(Schema::hasColumn('projects', 'delivered_today'))->toBeTrue();

    $col = DB::selectOne(
        "SELECT column_default
         FROM information_schema.columns
         WHERE table_name = 'projects' AND column_name = 'delivered_today'"
    );

    expect($col)->not->toBeNull();
    expect($col->column_default)->toContain('0');
});

test('UNIQUE INDEX on vid prevents duplicate inserts (idempotency)', function () {
    DB::statement("INSERT INTO supplier_leads (platform, raw_payload, vid, phone, received_at, source) VALUES ('B1', '{}', 999000111, '79991234567', NOW(), 'webhook')");

    expect(fn () => DB::statement(
        "INSERT INTO supplier_leads (platform, raw_payload, vid, phone, received_at, source) VALUES ('B2', '{}', 999000111, '79991234567', NOW(), 'webhook')"
    ))->toThrow(QueryException::class);
});

test('system_settings seed rows exist for supplier_webhook_secret + supplier_ip_allowlist', function () {
    $secret = DB::table('system_settings')
        ->where('key', 'supplier_webhook_secret')
        ->first();
    expect($secret)->not->toBeNull();
    expect($secret->type)->toBe('string');
    // Placeholder only valid in dev/test — production must override via deploy script.
    // Real secret strength validation belongs to a deploy-time validator (out of scope).
    expect($secret->value)->toBe('__SET_ON_DEPLOY__');

    $allowlist = DB::table('system_settings')
        ->where('key', 'supplier_ip_allowlist')
        ->first();
    expect($allowlist)->not->toBeNull();
    expect($allowlist->type)->toBe('json');
    $decoded = json_decode($allowlist->value, true);
    expect($decoded)->toBeArray();
});
