<?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);
}

$password = dbnToolsEnv('DBN_SETUP_PASSWORD');
if ($password === null || $password === '') {
    fwrite(STDERR, "Set DBN_SETUP_PASSWORD for this process only.\n");
    exit(1);
}

$clientSlug = dbnToolsClientSlug();
$packageSlug = dbnToolsRequiredPackageSlug();
$email = strtolower(trim(dbnToolsEnv('DBN_SETUP_EMAIL') ?: 'daveadmin@dobetternorge.no'));
$username = trim(dbnToolsEnv('DBN_SETUP_USERNAME') ?: 'daveadmin');
$displayName = trim(dbnToolsEnv('DBN_SETUP_DISPLAY_NAME') ?: 'Dave Admin');
$domain = strtolower(trim(dbnToolsEnv('DBN_SETUP_PORTAL_DOMAIN') ?: 'ai.dobetternorge.no'));

function setupColumnExists(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 setupJson(array $value): string
{
    return json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}

function setupEnumValues(PDO $db, string $table, string $column): array
{
    $stmt = $db->prepare(
        'SELECT COLUMN_TYPE
         FROM information_schema.COLUMNS
         WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?
         LIMIT 1'
    );
    $stmt->execute([$table, $column]);
    $type = (string)$stmt->fetchColumn();

    if (!preg_match("/^enum\\((.*)\\)$/", $type, $matches)) {
        return [];
    }

    $values = str_getcsv($matches[1], ',', "'");
    return array_values(array_filter(array_map('strval', $values)));
}

function setupPreferredValue(array $available, array $preferred, string $fallback): string
{
    foreach ($preferred as $value) {
        if (in_array($value, $available, true)) {
            return $value;
        }
    }
    return $available[0] ?? $fallback;
}

try {
    $db = dbnToolsDb();
    $db->beginTransaction();

    $plan = setupPreferredValue(
        setupEnumValues($db, 'clients', 'plan'),
        ['enterprise', 'sovereign', 'corporate', 'professional', 'beta', 'starter', 'trial', 'sandbox'],
        'professional'
    );

    $client = dbnToolsFetchClient($db);
    if (!$client) {
        $apiKeyHash = hash('sha256', random_bytes(32));
        $apiKeyPrefix = 'dbn_' . substr(bin2hex(random_bytes(4)), 0, 8);

        $columns = [
            'slug' => $clientSlug,
            'name' => 'Do Better Norge',
            'contact_email' => $email,
            'industry' => 'Legal services',
            'country' => 'NO',
            'plan' => $plan,
            'api_key_hash' => $apiKeyHash,
            'api_key_prefix' => $apiKeyPrefix,
            'monthly_query_limit' => 10000,
            'monthly_document_limit' => 1000,
            'monthly_user_limit' => 25,
            'is_active' => 1,
            'subscription_status' => 'active',
            'payment_method' => 'manual',
            'billing_email' => $email,
        ];

        if (setupColumnExists($db, 'clients', 'white_label_enabled')) {
            $columns['white_label_enabled'] = 1;
        }
        if (setupColumnExists($db, 'clients', 'white_label_config')) {
            $columns['white_label_config'] = setupJson([
                'brand_name' => 'Do Better Norge',
                'primary_color' => '#0c5f82',
                'support_email' => $email,
                'hide_powered_by' => false,
            ]);
        }

        $names = array_keys($columns);
        $placeholders = array_fill(0, count($names), '?');
        $stmt = $db->prepare(
            'INSERT INTO clients (' . implode(', ', $names) . ')
             VALUES (' . implode(', ', $placeholders) . ')'
        );
        $stmt->execute(array_values($columns));
        $clientId = (int)$db->lastInsertId();
    } else {
        $clientId = (int)$client['id'];
        $updates = [
            'name' => 'Do Better Norge',
            'contact_email' => $email,
            'industry' => 'Legal services',
            'country' => 'NO',
            'plan' => $plan,
            'monthly_query_limit' => 10000,
            'monthly_document_limit' => 1000,
            'monthly_user_limit' => 25,
            'is_active' => 1,
            'subscription_status' => 'active',
            'payment_method' => 'manual',
            'billing_email' => $email,
        ];

        if (setupColumnExists($db, 'clients', 'white_label_enabled')) {
            $updates['white_label_enabled'] = 1;
        }
        if (setupColumnExists($db, 'clients', 'white_label_config')) {
            $updates['white_label_config'] = setupJson([
                'brand_name' => 'Do Better Norge',
                'primary_color' => '#0c5f82',
                'support_email' => $email,
                'hide_powered_by' => false,
            ]);
        }

        $set = implode(', ', array_map(static fn (string $key): string => "{$key} = ?", array_keys($updates)));
        $stmt = $db->prepare("UPDATE clients SET {$set} WHERE id = ?");
        $stmt->execute([...array_values($updates), $clientId]);
    }

    $passwordHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
    $stmt = $db->prepare('SELECT id, client_id FROM client_users WHERE email = ? LIMIT 1');
    $stmt->execute([$email]);
    $existingUser = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($existingUser) {
        $stmt = $db->prepare(
            'UPDATE client_users
             SET client_id = ?, username = ?, display_name = ?, password_hash = ?, role = ?, is_active = 1
             WHERE id = ?'
        );
        $stmt->execute([$clientId, $username, $displayName, $passwordHash, 'owner', (int)$existingUser['id']]);
        $userId = (int)$existingUser['id'];
    } else {
        $stmt = $db->prepare(
            'INSERT INTO client_users (client_id, username, email, display_name, password_hash, role, is_active)
             VALUES (?, ?, ?, ?, ?, ?, 1)'
        );
        $stmt->execute([$clientId, $username, $email, $displayName, $passwordHash, 'owner']);
        $userId = (int)$db->lastInsertId();
    }

    $package = dbnToolsFetchPackage($packageSlug, $db);
    if (!$package) {
        $stmt = $db->prepare(
            'INSERT INTO corpus_packages (slug, name, description, icon, is_free, included_in_plans, is_active, sort_order)
             VALUES (?, ?, ?, ?, 1, ?, 1, 10)'
        );
        $stmt->execute([
            $packageSlug,
            'Family Legal',
            'Family law corpus package for Do Better Norge legal tools.',
            'LAW',
            setupJson([$plan]),
        ]);
        $packageId = (int)$db->lastInsertId();
    } else {
        $packageId = (int)$package['id'];
        $db->prepare('UPDATE corpus_packages SET is_active = 1 WHERE id = ?')->execute([$packageId]);
    }

    $stmt = $db->prepare(
        'INSERT INTO client_corpus_subscriptions (client_id, package_id, is_active, source)
         VALUES (?, ?, 1, ?)
         ON DUPLICATE KEY UPDATE is_active = VALUES(is_active), source = VALUES(source), cancelled_at = NULL'
    );
    $stmt->execute([$clientId, $packageId, 'manual']);

    if (setupColumnExists($db, 'client_domains', 'hostname') && $domain !== '') {
        $domainColumns = [
            'client_id' => $clientId,
            'hostname' => $domain,
            'service_type' => 'portal',
            'is_active' => 1,
        ];
        if (setupColumnExists($db, 'client_domains', 'display_name')) {
            $domainColumns['display_name'] = 'Do Better Norge Caveau';
        }
        if (setupColumnExists($db, 'client_domains', 'service_config')) {
            $domainColumns['service_config'] = setupJson([
                'audience' => 'internal',
                'search_private' => true,
                'search_shared' => true,
                'package_ids' => [$packageId],
                'allowed_classifications' => ['public', 'public-record', 'internal', 'client-work'],
                'language' => 'no',
            ]);
        }
        if (setupColumnExists($db, 'client_domains', 'is_verified')) {
            $domainColumns['is_verified'] = 1;
        }
        if (setupColumnExists($db, 'client_domains', 'verified_at')) {
            $domainColumns['verified_at'] = date('Y-m-d H:i:s');
        }

        $names = array_keys($domainColumns);
        $updates = implode(', ', array_map(static fn (string $key): string => "{$key} = VALUES({$key})", $names));
        $stmt = $db->prepare(
            'INSERT INTO client_domains (' . implode(', ', $names) . ')
             VALUES (' . implode(', ', array_fill(0, count($names), '?')) . ')
             ON DUPLICATE KEY UPDATE ' . $updates
        );
        $stmt->execute(array_values($domainColumns));
    }

    $db->commit();

    echo "Caveau access configured.\n";
    echo "Client: {$clientSlug} (#{$clientId})\n";
    echo "User: {$email} (#{$userId}) role owner\n";
    echo "Package: {$packageSlug} (#{$packageId}) active subscription\n";
    echo "Portal domain: {$domain}\n";
} catch (Throwable $e) {
    if (isset($db) && $db instanceof PDO && $db->inTransaction()) {
        $db->rollBack();
    }
    fwrite(STDERR, "Setup failed: {$e->getMessage()}\n");
    exit(1);
}
