<?php
declare(strict_types=1);

require_once __DIR__ . '/../includes/bootstrap.php';

if (PHP_SAPI !== 'cli') {
    fwrite(STDERR, "This setup script must be run from the command line.\n");
    exit(1);
}

function dbnMcpColumnExists(PDO $db, string $table, string $column): bool
{
    $stmt = $db->prepare(
        'SELECT COUNT(*)
           FROM information_schema.COLUMNS
          WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?'
    );
    $stmt->execute([$table, $column]);
    return (int)$stmt->fetchColumn() > 0;
}

function dbnMcpTableExists(PDO $db, string $table): bool
{
    $stmt = $db->prepare(
        'SELECT COUNT(*)
           FROM information_schema.TABLES
          WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?'
    );
    $stmt->execute([$table]);
    return (int)$stmt->fetchColumn() > 0;
}

function dbnMcpRequireTables(PDO $db, array $tables): void
{
    $missing = [];
    foreach ($tables as $table) {
        if (!dbnMcpTableExists($db, $table)) {
            $missing[] = $table;
        }
    }
    if ($missing !== []) {
        throw new RuntimeException(
            'Missing required MCP tables: ' . implode(', ', $missing) .
            '. Apply the Caveau MCP and Azure Search migrations before running this script.'
        );
    }
}

function dbnMcpUpsertFeature(PDO $db, int $clientId, string $feature, int $enabled): void
{
    $stmt = $db->prepare(
        'INSERT INTO client_feature_overrides (client_id, feature, enabled)
         VALUES (?, ?, ?)
         ON DUPLICATE KEY UPDATE enabled = VALUES(enabled)'
    );
    $stmt->execute([$clientId, $feature, $enabled]);
}

try {
    $db = dbnToolsDb();
    dbnMcpRequireTables($db, [
        'client_mcp_config',
        'client_mcp_tokens',
        'client_corpus_subscriptions',
        'client_feature_overrides',
    ]);

    $client = dbnToolsFetchClient($db);
    if (!$client || empty($client['is_active'])) {
        throw new RuntimeException('Do Better Norge client tenant is not active or was not found.');
    }

    $clientId = (int)$client['id'];
    $packageSlug = dbnToolsRequiredPackageSlug();
    $package = dbnToolsFetchPackage($packageSlug, $db);
    if (!$package || empty($package['is_active'])) {
        throw new RuntimeException("Package {$packageSlug} is not active or was not found.");
    }
    if ((int)($package['corpus_id'] ?? 0) !== 1) {
        throw new RuntimeException("Package {$packageSlug} must point at corpus_id=1 for DBN MCP v1.");
    }

    $db->beginTransaction();

    $stmt = $db->prepare(
        'INSERT INTO client_corpus_subscriptions (client_id, package_id, is_active, source, subscribed_at)
         VALUES (?, ?, 1, ?, NOW())
         ON DUPLICATE KEY UPDATE is_active = VALUES(is_active), source = VALUES(source), cancelled_at = NULL'
    );
    $stmt->execute([$clientId, (int)$package['id'], 'dbn-mcp-v1']);

    $configColumns = [
        'client_id' => $clientId,
        'is_enabled' => 1,
        'endpoint_slug' => 'dobetter',
    ];
    if (dbnMcpColumnExists($db, 'client_mcp_config', 'inspector_enabled')) {
        $configColumns['inspector_enabled'] = 1;
    }
    if (dbnMcpColumnExists($db, 'client_mcp_config', 'inspector_retention_days')) {
        $configColumns['inspector_retention_days'] = 30;
    }
    $names = array_keys($configColumns);
    $updates = implode(', ', array_map(static fn(string $name): string => "{$name} = VALUES({$name})", $names));
    $stmt = $db->prepare(
        'INSERT INTO client_mcp_config (' . implode(', ', $names) . ')
         VALUES (' . implode(', ', array_fill(0, count($names), '?')) . ')
         ON DUPLICATE KEY UPDATE ' . $updates
    );
    $stmt->execute(array_values($configColumns));

    dbnMcpUpsertFeature($db, $clientId, 'azure_search', 1);

    $existingToken = $db->prepare(
        "SELECT id, token_prefix, name, created_at
           FROM client_mcp_tokens
          WHERE client_id = ? AND is_active = 1 AND revoked_at IS NULL
            AND name = 'DBN MCP v1'
          ORDER BY id DESC
          LIMIT 1"
    );
    $existingToken->execute([$clientId]);
    $tokenRow = $existingToken->fetch(PDO::FETCH_ASSOC);

    $plaintext = null;
    if (!$tokenRow) {
        $plaintext = 'dbn_mcp_' . bin2hex(random_bytes(32));
        $tokenHash = hash('sha256', $plaintext);
        $prefix = substr($plaintext, 0, 16);
        $scopes = json_encode([
            'tools' => ['dbn.search_legal', 'dbn.compare_retrieval', 'dbn.list_sources', 'dbn.get_document'],
            'backend' => ['azure-search', 'qdrant'],
            'corpus_id' => [1],
        ], JSON_UNESCAPED_SLASHES);

        $stmt = $db->prepare(
            'INSERT INTO client_mcp_tokens (client_id, token_hash, token_prefix, name, scopes, is_active, created_at)
             VALUES (?, ?, ?, ?, ?, 1, NOW())'
        );
        $stmt->execute([$clientId, $tokenHash, $prefix, 'DBN MCP v1', $scopes]);
        $tokenRow = [
            'id' => (int)$db->lastInsertId(),
            'token_prefix' => $prefix,
            'name' => 'DBN MCP v1',
            'created_at' => date('Y-m-d H:i:s'),
        ];
    }

    $db->commit();

    echo "DBN MCP configured.\n";
    echo "Client: " . dbnToolsClientSlug() . " (#{$clientId})\n";
    echo "Package: {$packageSlug} (#{$package['id']}) corpus_id={$package['corpus_id']}\n";
    echo "MCP config: enabled endpoint_slug=dobetter\n";
    echo "Azure Search feature: enabled\n";
    echo "Token: {$tokenRow['name']} (#{$tokenRow['id']}) prefix={$tokenRow['token_prefix']}\n";
    if ($plaintext !== null) {
        echo "Plaintext token (shown once): {$plaintext}\n";
    } else {
        echo "Plaintext token: not shown; an active DBN MCP v1 token already exists.\n";
    }
} catch (Throwable $e) {
    if (isset($db) && $db instanceof PDO && $db->inTransaction()) {
        $db->rollBack();
    }
    fwrite(STDERR, "DBN MCP setup failed: {$e->getMessage()}\n");
    exit(1);
}
