<?php
// Quick validation script for invite expiration flow without PHPUnit/composer.
// Creates minimal supplier/product, a quote with yesterday valid_until,
// sends an invite, verifies GET responder returns 410, and checks effective_status=failed.

use Gestoreasy\Core\Tenant\TenantAdmin;
use Gestoreasy\Core\Tenant\ConnectionManager;
use Gestoreasy\Core\Http\Request;
use Modules\Cotacoes\Controllers\PurchaseQuotesController;

require __DIR__ . '/../bootstrap.php';

function out($msg) { echo $msg . "\n"; }

// Ensure tenant migrations and base schema
try {
    TenantAdmin::runMigrations('default');
} catch (Throwable $e) {
    out('WARN: runMigrations failed: ' . $e->getMessage());
}

$db = ConnectionManager::forTenant('default');

// Ensure suppliers table exists and seed one supplier with email
try { $db->query('SELECT 1 FROM suppliers LIMIT 1'); }
catch (Throwable $e) {
    try {
        $db->exec('CREATE TABLE IF NOT EXISTS suppliers (
            id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            nome VARCHAR(190) NOT NULL,
            email VARCHAR(190) NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4');
    } catch (Throwable $e2) {
        out('ERROR: cannot ensure suppliers table: ' . $e2->getMessage());
        exit(1);
    }
}

$supplierId = null;
try {
    $row = $db->query("SELECT id FROM suppliers WHERE email = 'fornecedor@example.com' LIMIT 1")->fetch();
    if ($row) { $supplierId = (int)$row['id']; }
    if (!$supplierId) {
        $db->prepare('INSERT INTO suppliers (nome, email) VALUES (?, ?)')->execute(['Fornecedor Teste', 'fornecedor@example.com']);
        $supplierId = (int)$db->lastInsertId();
    }
} catch (Throwable $e) {
    out('ERROR: cannot seed supplier: ' . $e->getMessage());
    exit(1);
}

// Ensure products table exists and seed one product
try { $db->query('SELECT 1 FROM products LIMIT 1'); }
catch (Throwable $e) {
    try {
        $db->exec('CREATE TABLE IF NOT EXISTS products (
            id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            nome VARCHAR(190) NOT NULL,
            sku VARCHAR(100) NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4');
    } catch (Throwable $e2) {
        out('ERROR: cannot ensure products table: ' . $e2->getMessage());
        exit(1);
    }
}

$productId = null;
try {
$row = null;
try { $row = $db->query("SELECT id FROM products LIMIT 1")->fetch(); } catch (Throwable $eSel) { /* ignore */ }
if ($row) { $productId = (int)$row['id']; }
if (!$productId) {
    // Minimal insert; some schemas may require additional fields, best-effort
    try {
        $db->prepare('INSERT INTO products (nome) VALUES (?)')->execute(['Produto Teste']);
        $productId = (int)$db->lastInsertId();
    } catch (Throwable $eIns) {
        out('ERROR: cannot insert minimal product: ' . $eIns->getMessage());
        exit(1);
    }
}
} catch (Throwable $e) {
    out('ERROR: cannot seed product: ' . $e->getMessage());
    exit(1);
}

// Create a quote with valid_until yesterday
$yesterday = (new DateTimeImmutable('yesterday'))->format('Y-m-d');
$ctrl = new PurchaseQuotesController();

$storeReq = new Request(
    headers: ['authorization' => 'Bearer dev-token'],
    query: [],
    body: [
        'supplier_id' => $supplierId,
        'valid_until' => $yesterday,
        'items' => [ ['product_id' => $productId, 'quantity' => 1, 'price' => 10.0] ],
        'status' => 'open'
    ],
    files: [],
    method: 'POST',
    uri: '/api/compras/cotacoes'
);

$storeResp = $ctrl->store($storeReq);
if ($storeResp->status !== 201 && $storeResp->status !== 200) {
    out('ERROR: store quote failed: ' . json_encode($storeResp->body, JSON_UNESCAPED_UNICODE));
    exit(1);
}
$quoteId = (int)($storeResp->body['data']['id'] ?? 0);
if ($quoteId <= 0) { out('ERROR: invalid quote id'); exit(1); }
out('OK: Quote created id=' . $quoteId . ' valid_until=' . $yesterday);

// Send invite to supplier
$inviteReq = new Request(headers: [], query: [], body: [], files: [], method: 'POST', uri: '/api/compras/cotacoes/'.$quoteId.'/enviar-convite');
$inviteReq->set('params', [$quoteId]);
$inviteResp = $ctrl->sendInvite($inviteReq);
if ($inviteResp->status !== 200) {
    out('ERROR: send invite failed: ' . json_encode($inviteResp->body, JSON_UNESCAPED_UNICODE));
    exit(1);
}
$token = (string)($inviteResp->body['data']['token'] ?? '');
if ($token === '') { out('ERROR: missing invite token'); exit(1); }
out('OK: Invite sent token=' . $token);

// Open public link (getInviteByToken) expecting 410 link_expired
$openReq = new Request(headers: [], query: ['token' => $token], body: [], files: [], method: 'GET', uri: '/api/compras/cotacoes/responder');
$openResp = $ctrl->getInviteByToken($openReq);
out('Open responder status=' . $openResp->status);
if ($openResp->status !== 410) {
    out('ERROR: expected 410 link_expired, got ' . $openResp->status . ' body=' . json_encode($openResp->body, JSON_UNESCAPED_UNICODE));
    exit(1);
}
if (($openResp->body['error'] ?? '') !== 'link_expired') {
    out('ERROR: expected error=link_expired, got ' . json_encode($openResp->body, JSON_UNESCAPED_UNICODE));
    exit(1);
}
out('OK: Link expired correctly with 410');

// List invites/responses and assert effective_status=failed
$listReq = new Request(headers: [], query: [], body: [], files: [], method: 'GET', uri: '/api/compras/cotacoes/'.$quoteId.'/convites-respostas');
$listReq->set('params', [$quoteId]);
$listResp = $ctrl->listInvitesAndResponses($listReq);
if ($listResp->status !== 200) {
    out('ERROR: list invites failed: ' . json_encode($listResp->body, JSON_UNESCAPED_UNICODE));
    exit(1);
}
$invites = $listResp->body['data']['invites'] ?? [];
$okEffective = false;
foreach ($invites as $inv) {
    if (($inv['effective_status'] ?? '') === 'failed') { $okEffective = true; break; }
}
if (!$okEffective) {
    out('ERROR: effective_status failed not found in invites: ' . json_encode($invites, JSON_UNESCAPED_UNICODE));
    exit(1);
}
out('OK: effective_status=failed confirmed');
out('SUCCESS: Invite expiration flow validated.');
exit(0);