<?php
declare(strict_types=1);

require_once __DIR__ . '/session_store.php';
require_once __DIR__ . '/backup_service.php';

function golder_sql_ident(string $value): string
{
    return str_replace('`', '', trim($value));
}

function golder_hard_delete_customer(PDO $master, int $customerId): array
{
    golder_ensure_customers_columns($master);
    golder_ensure_payment_tables($master);
    golder_ensure_customer_devices_schema($master);
    golder_ensure_api_security_tables($master);
    golder_ensure_backup_tables($master);

    $customer = golder_customer_by_id($master, $customerId);
    if (!$customer) {
        return ['ok' => false, 'message' => 'Customer not found.'];
    }

    $tenantDbName = golder_sql_ident((string)($customer['mysql_db_name'] ?? ''));
    $tenantDbUser = trim((string)($customer['mysql_db_user'] ?? ''));
    $portalUserId = (int)($customer['portal_user_id'] ?? 0);

    $backupRows = $master->prepare('SELECT file_path FROM backup_files WHERE customer_id = :cid');
    $backupRows->execute([':cid' => $customerId]);
    $backupFiles = [];
    foreach ($backupRows->fetchAll() ?: [] as $row) {
        $path = trim((string)($row['file_path'] ?? ''));
        if ($path !== '') {
            $backupFiles[] = $path;
        }
    }

    $paymentIds = [];
    $stPay = $master->prepare('SELECT id FROM payment_requests WHERE customer_id = :cid');
    $stPay->execute([':cid' => $customerId]);
    foreach ($stPay->fetchAll() ?: [] as $row) {
        $pid = trim((string)($row['id'] ?? ''));
        if ($pid !== '') {
            $paymentIds[] = $pid;
        }
    }

    $demoRequestIds = [];
    $stDemoReq = $master->prepare('SELECT id FROM demo_requests WHERE approved_customer_id = :cid');
    $stDemoReq->execute([':cid' => $customerId]);
    foreach ($stDemoReq->fetchAll() ?: [] as $row) {
        $rid = trim((string)($row['id'] ?? ''));
        if ($rid !== '') {
            $demoRequestIds[] = $rid;
        }
    }

    $tokenIds = [];
    $stTok = $master->prepare('SELECT id FROM api_tokens WHERE customer_id = :cid');
    $stTok->execute([':cid' => $customerId]);
    foreach ($stTok->fetchAll() ?: [] as $row) {
        $tid = (int)($row['id'] ?? 0);
        if ($tid > 0) {
            $tokenIds[] = $tid;
        }
    }

    $counts = [
        'payment_messages' => 0,
        'payment_requests' => 0,
        'support_messages' => 0,
        'support_threads' => 0,
        'demo_request_messages' => 0,
        'demo_requests' => 0,
        'demo_licenses' => 0,
        'web_sessions' => 0,
        'devices' => 0,
        'api_nonces' => 0,
        'api_tokens' => 0,
        'remember_tokens' => 0,
        'backups_meta' => 0,
        'customers' => 0,
        'backup_files_deleted' => 0,
    ];
    $warnings = [];

    $master->beginTransaction();
    try {
        if ($paymentIds) {
            $ph = implode(',', array_fill(0, count($paymentIds), '?'));
            $del = $master->prepare("DELETE FROM payment_request_messages WHERE payment_request_id IN ({$ph})");
            $del->execute($paymentIds);
            $counts['payment_messages'] += (int)$del->rowCount();
        }

        $delPay = $master->prepare('DELETE FROM payment_requests WHERE customer_id = :cid');
        $delPay->execute([':cid' => $customerId]);
        $counts['payment_requests'] += (int)$delPay->rowCount();

        if ($portalUserId > 0) {
            $threadIds = [];
            $stThreads = $master->prepare('SELECT id FROM support_threads WHERE customer_id = :cid OR portal_user_id = :uid');
            $stThreads->execute([':cid' => $customerId, ':uid' => $portalUserId]);
            foreach ($stThreads->fetchAll() ?: [] as $row) {
                $tid = trim((string)($row['id'] ?? ''));
                if ($tid !== '') {
                    $threadIds[] = $tid;
                }
            }
            if ($threadIds) {
                $ph = implode(',', array_fill(0, count($threadIds), '?'));
                $delSupportMsg = $master->prepare("DELETE FROM support_thread_messages WHERE thread_id IN ({$ph})");
                $delSupportMsg->execute($threadIds);
                $counts['support_messages'] += (int)$delSupportMsg->rowCount();

                $delSupport = $master->prepare("DELETE FROM support_threads WHERE id IN ({$ph})");
                $delSupport->execute($threadIds);
                $counts['support_threads'] += (int)$delSupport->rowCount();
            }
        }

        if ($demoRequestIds) {
            $ph = implode(',', array_fill(0, count($demoRequestIds), '?'));
            $delMsg = $master->prepare("DELETE FROM demo_request_messages WHERE demo_request_id IN ({$ph})");
            $delMsg->execute($demoRequestIds);
            $counts['demo_request_messages'] += (int)$delMsg->rowCount();
        }

        $delDemoReq = $master->prepare('DELETE FROM demo_requests WHERE approved_customer_id = :cid');
        $delDemoReq->execute([':cid' => $customerId]);
        $counts['demo_requests'] += (int)$delDemoReq->rowCount();

        $delDemoLic = $master->prepare('DELETE FROM demo_licenses WHERE customer_id = :cid');
        $delDemoLic->execute([':cid' => $customerId]);
        $counts['demo_licenses'] += (int)$delDemoLic->rowCount();

        $delSess = $master->prepare('DELETE FROM customer_web_sessions WHERE customer_id = :cid');
        $delSess->execute([':cid' => $customerId]);
        $counts['web_sessions'] += (int)$delSess->rowCount();

        $delDev = $master->prepare('DELETE FROM customer_devices WHERE customer_id = :cid');
        $delDev->execute([':cid' => $customerId]);
        $counts['devices'] += (int)$delDev->rowCount();

        if ($tokenIds) {
            $ph = implode(',', array_fill(0, count($tokenIds), '?'));
            $delNonce = $master->prepare("DELETE FROM api_nonces WHERE token_id IN ({$ph})");
            $delNonce->execute($tokenIds);
            $counts['api_nonces'] += (int)$delNonce->rowCount();
        }

        $delTok = $master->prepare('DELETE FROM api_tokens WHERE customer_id = :cid');
        $delTok->execute([':cid' => $customerId]);
        $counts['api_tokens'] += (int)$delTok->rowCount();

        try {
            $delRemember = $master->prepare('DELETE FROM customer_remember_tokens WHERE customer_id = :cid');
            $delRemember->execute([':cid' => $customerId]);
            $counts['remember_tokens'] += (int)$delRemember->rowCount();
        } catch (Throwable $_ignored) {
        }

        $delBackup = $master->prepare('DELETE FROM backup_files WHERE customer_id = :cid');
        $delBackup->execute([':cid' => $customerId]);
        $counts['backups_meta'] += (int)$delBackup->rowCount();

        $delCustomer = $master->prepare('DELETE FROM customers WHERE id = :id');
        $delCustomer->execute([':id' => $customerId]);
        $counts['customers'] += (int)$delCustomer->rowCount();

        $master->commit();
    } catch (Throwable $e) {
        if ($master->inTransaction()) {
            $master->rollBack();
        }
        return ['ok' => false, 'message' => 'Master cleanup failed: ' . $e->getMessage()];
    }

    if ($tenantDbName !== '') {
        try {
            $master->exec(sprintf('DROP DATABASE IF EXISTS `%s`', $tenantDbName));
        } catch (Throwable $e) {
            $warnings[] = 'tenant_db_drop_failed: ' . $e->getMessage();
        }
    }

    if ($tenantDbUser !== '') {
        try {
            $safeUser = str_replace("'", "''", $tenantDbUser);
            $master->exec("DROP USER IF EXISTS '{$safeUser}'@'%'");
            $master->exec("DROP USER IF EXISTS '{$safeUser}'@'localhost'");
            $master->exec('FLUSH PRIVILEGES');
        } catch (Throwable $e) {
            $warnings[] = 'tenant_user_drop_failed: ' . $e->getMessage();
        }
    }

    foreach ($backupFiles as $path) {
        if (is_file($path) && @unlink($path)) {
            $counts['backup_files_deleted']++;
        }
    }

    $customerBackupDir = rtrim(golder_backup_storage_dir(), '/\\') . DIRECTORY_SEPARATOR . (string)$customerId;
    if (is_dir($customerBackupDir)) {
        $items = @scandir($customerBackupDir);
        if (is_array($items) && count(array_diff($items, ['.', '..'])) === 0) {
            @rmdir($customerBackupDir);
        }
    }

    return [
        'ok' => true,
        'customer_id' => $customerId,
        'counts' => $counts,
        'warnings' => $warnings,
    ];
}

function golder_demo_hard_delete_candidates(PDO $master, int $hoursAfterExpire = 48, int $limit = 200): array
{
    golder_ensure_payment_tables($master);
    $hours = max(1, $hoursAfterExpire);
    $limit = max(1, min(500, $limit));
    $sql = "
        SELECT DISTINCT c.id
        FROM demo_licenses dl
        INNER JOIN customers c ON c.id = dl.customer_id
        WHERE dl.status = 'expired'
          AND dl.expires_at < DATE_SUB(UTC_TIMESTAMP(), INTERVAL {$hours} HOUR)
        ORDER BY c.id ASC
        LIMIT {$limit}
    ";
    $rows = $master->query($sql)->fetchAll() ?: [];
    $ids = [];
    foreach ($rows as $row) {
        $id = (int)($row['id'] ?? 0);
        if ($id > 0) {
            $ids[] = $id;
        }
    }
    return $ids;
}


