<?php
/**
 * cron/dbn-dms-trash-purge.php
 *
 * Daily cron that hard-deletes any document/folder soft-deleted more than
 * DBN_DMS_TRASH_RETENTION_DAYS ago.
 *
 * Pass --dry-run for a no-op preview.
 *
 * Crontab (on chloe, as dobetternorge):
 *   15 3 * * * /usr/bin/php /home/dobetternorge/public_html/cron/dbn-dms-trash-purge.php >> /home/dobetternorge/logs/dms-purge.log 2>&1
 */

declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    http_response_code(403);
    exit("CLI only.\n");
}

require_once dirname(__DIR__) . '/includes/bootstrap.php';

$dryRun = in_array('--dry-run', $argv ?? [], true);
$cutoff = DBN_DMS_TRASH_RETENTION_DAYS;

try {
    dbnToolsBootCaveau();
    $db = getDb();
} catch (Throwable $e) {
    fwrite(STDERR, "[dbn-dms-purge] DB connect failed: " . $e->getMessage() . "\n");
    exit(1);
}

$start = microtime(true);
$purgedDocs    = 0;
$purgedFolders = 0;
$skipped       = 0;
$errors        = 0;

try {
    $docs = $db->prepare(
        "SELECT id, client_id, storage_path
         FROM client_documents
         WHERE deleted_at IS NOT NULL AND deleted_at < (NOW() - INTERVAL ? DAY)
         LIMIT 5000"
    );
    $docs->execute([$cutoff]);
    foreach ($docs->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $docId    = (int)$row['id'];
        $clientId = (int)$row['client_id'];
        $path     = $row['storage_path'] ?? null;

        if ($dryRun) {
            echo "DRY: would purge document {$docId} (client {$clientId})\n";
            $skipped++;
            continue;
        }

        try {
            // Version-file cleanup
            $vr = $db->prepare('SELECT storage_path FROM client_document_versions WHERE document_id = ? AND client_id = ?');
            $vr->execute([$docId, $clientId]);
            foreach ($vr->fetchAll() as $v) {
                if (!empty($v['storage_path']) && is_file($v['storage_path'])) @unlink($v['storage_path']);
            }

            // Chunks
            try {
                $db->prepare('DELETE FROM client_chunks WHERE client_id = ? AND document_id = ?')->execute([$clientId, $docId]);
            } catch (Throwable $e) { /* tolerated */ }

            // Qdrant
            try {
                if (class_exists('QdrantClient')) {
                    $qd = new QdrantClient();
                    $qd->deleteByFilter('bnl_client_chunks', [
                        'must' => [
                            ['key' => 'client_id',   'match' => ['value' => $clientId]],
                            ['key' => 'document_id', 'match' => ['value' => $docId]],
                        ],
                    ]);
                }
            } catch (Throwable $e) { /* tolerated */ }

            // Disk
            if ($path && is_file($path)) @unlink($path);
            if ($path) {
                $verDir = dirname($path) . '/' . $docId . '_versions';
                if (is_dir($verDir)) {
                    foreach (glob($verDir . '/*') ?: [] as $f) @unlink($f);
                    @rmdir($verDir);
                }
            }

            // Row
            $db->prepare('DELETE FROM client_documents WHERE id = ? AND client_id = ?')->execute([$docId, $clientId]);
            $purgedDocs++;
        } catch (Throwable $e) {
            $errors++;
            fwrite(STDERR, "[dbn-dms-purge] doc {$docId}: " . $e->getMessage() . "\n");
        }
    }

    if ($dryRun) {
        $foldCount = $db->prepare("SELECT COUNT(*) FROM client_folders WHERE deleted_at IS NOT NULL AND deleted_at < (NOW() - INTERVAL ? DAY)");
        $foldCount->execute([$cutoff]);
        $skipped += (int)$foldCount->fetchColumn();
        echo "DRY: would purge {$skipped} folders\n";
    } else {
        $fold = $db->prepare("DELETE FROM client_folders WHERE deleted_at IS NOT NULL AND deleted_at < (NOW() - INTERVAL ? DAY)");
        $fold->execute([$cutoff]);
        $purgedFolders = $fold->rowCount();
    }
} catch (Throwable $e) {
    fwrite(STDERR, "[dbn-dms-purge] fatal: " . $e->getMessage() . "\n");
    exit(1);
}

$elapsed = round(microtime(true) - $start, 2);
$mode = $dryRun ? 'DRY-RUN' : 'live';
printf("[dbn-dms-purge] %s done in %ss: docs=%d folders=%d errors=%d skipped=%d\n",
    $mode, $elapsed, $purgedDocs, $purgedFolders, $errors, $skipped);
