<?php
/**
 * /api/dashboard/document-versions.php — per-document version history.
 *
 * GET  ?action=list&document_id=X        → { ok, versions: [...] }
 * GET  ?action=get&version_id=X          → { ok, version: {...with content} }
 * POST ?action=restore body: { document_id, version_id }
 *                                        → { ok, document_id, new_version_number, chunks }
 * POST ?action=delete  body: { version_id }
 */

declare(strict_types=1);

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

dbnToolsRequireAuth();

try {
    $tenant = dbnToolsEnsureDashboardTenant();
} catch (DbnToolsHttpException $e) {
    dbnToolsError($e->getMessage(), $e->status, $e->errorCode);
}
$clientId   = (int)$tenant['client_id'];
$userId     = (int)($tenant['client_user_id'] ?? 0);
$tenantRole = (string)($tenant['role'] ?? 'editor');

$db = dbnToolsDb();
$method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
$action = (string)($_GET['action'] ?? ($method === 'POST' ? '' : 'list'));

try {
    switch ($action) {
        case 'list':
            dbnToolsRequireMethod('GET');
            listVersions($db, $clientId, $userId, $tenantRole);
            break;
        case 'get':
            dbnToolsRequireMethod('GET');
            getVersion($db, $clientId, $userId, $tenantRole);
            break;
        case 'restore':
            dbnToolsRequireMethod('POST');
            restoreVersion($db, $clientId, $userId, $tenantRole);
            break;
        case 'delete':
            dbnToolsRequireMethod('POST');
            deleteVersion($db, $clientId, $userId, $tenantRole);
            break;
        default:
            dbnToolsError('Unknown action.', 400, 'unknown_action');
    }
} catch (DbnToolsHttpException $e) {
    dbnToolsError($e->getMessage(), $e->status, $e->errorCode, $e->extra);
} catch (Throwable $e) {
    error_log('[dbn-dms/versions] ' . $e->getMessage());
    dbnToolsError('Version operation failed.', 500, 'version_op_failed');
}

function assertDocumentReadable(PDO $db, int $clientId, int $userId, string $tenantRole, int $docId): array
{
    $stmt = $db->prepare('SELECT id, folder_id, title, current_version FROM client_documents WHERE id = ? AND client_id = ?');
    $stmt->execute([$docId, $clientId]);
    $row = $stmt->fetch();
    if (!$row) {
        dbnToolsError('Document not found.', 404, 'not_found');
    }
    $fid = $row['folder_id'] ? (int)$row['folder_id'] : 0;
    if (!dbnDmsUserCanAccessFolder($fid ?: null, 'read', $clientId, $userId, $tenantRole)) {
        dbnToolsError('Forbidden.', 403, 'forbidden');
    }
    return $row;
}

function listVersions(PDO $db, int $clientId, int $userId, string $tenantRole): void
{
    $docId = (int)($_GET['document_id'] ?? 0);
    if ($docId <= 0) {
        dbnToolsError('document_id is required.', 400, 'missing_document_id');
    }
    assertDocumentReadable($db, $clientId, $userId, $tenantRole, $docId);

    $stmt = $db->prepare(
        'SELECT v.id, v.version_number, v.title, v.original_filename, v.file_size_bytes,
                v.word_count, v.notes, v.uploaded_by, v.created_at,
                u.email AS uploaded_email, u.full_name AS uploaded_name
         FROM client_document_versions v
         LEFT JOIN client_users u ON u.id = v.uploaded_by
         WHERE v.document_id = ? AND v.client_id = ?
         ORDER BY v.version_number DESC'
    );
    $stmt->execute([$docId, $clientId]);
    dbnToolsRespond(['ok' => true, 'versions' => $stmt->fetchAll()]);
}

function getVersion(PDO $db, int $clientId, int $userId, string $tenantRole): void
{
    $vid = (int)($_GET['version_id'] ?? 0);
    if ($vid <= 0) {
        dbnToolsError('version_id is required.', 400, 'missing_version_id');
    }
    $stmt = $db->prepare(
        'SELECT * FROM client_document_versions WHERE id = ? AND client_id = ?'
    );
    $stmt->execute([$vid, $clientId]);
    $row = $stmt->fetch();
    if (!$row) {
        dbnToolsError('Version not found.', 404, 'not_found');
    }
    assertDocumentReadable($db, $clientId, $userId, $tenantRole, (int)$row['document_id']);
    dbnToolsRespond(['ok' => true, 'version' => $row]);
}

function restoreVersion(PDO $db, int $clientId, int $userId, string $tenantRole): void
{
    $input = dbnToolsJsonInput(5_000);
    $docId = (int)($input['document_id'] ?? 0);
    $vid   = (int)($input['version_id'] ?? 0);
    if ($docId <= 0 || $vid <= 0) {
        dbnToolsError('document_id and version_id are required.', 400, 'missing_args');
    }
    $cur = assertDocumentReadable($db, $clientId, $userId, $tenantRole, $docId);
    $fid = $cur['folder_id'] ? (int)$cur['folder_id'] : 0;
    if (!dbnDmsUserCanAccessFolder($fid ?: null, 'write', $clientId, $userId, $tenantRole)) {
        dbnToolsError('Forbidden.', 403, 'forbidden');
    }

    $vstmt = $db->prepare('SELECT * FROM client_document_versions WHERE id = ? AND document_id = ? AND client_id = ?');
    $vstmt->execute([$vid, $docId, $clientId]);
    $ver = $vstmt->fetch();
    if (!$ver) {
        dbnToolsError('Version not found.', 404, 'not_found');
    }

    // Snapshot current state before restoring so we can roll-forward later.
    dbnDmsSnapshotVersion($docId, $clientId, $userId, "Snapshot before restoring v{$ver['version_number']}");
    $next = (int)$db->query("SELECT current_version FROM client_documents WHERE id = {$docId}")->fetchColumn();
    $next = max($next, (int)$ver['version_number']) + 1;

    $upd = $db->prepare(
        "UPDATE client_documents
         SET title = ?, content = ?, file_size_bytes = ?, word_count = ?,
             original_filename = ?, storage_path = ?, current_version = ?, status = 'pending',
             error_message = NULL, updated_at = NOW()
         WHERE id = ? AND client_id = ?"
    );
    $upd->execute([
        (string)$ver['title'],
        (string)$ver['content'],
        (int)$ver['file_size_bytes'],
        (int)$ver['word_count'],
        $ver['original_filename'],
        $ver['storage_path'],
        $next,
        $docId, $clientId,
    ]);

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

    $chunks = 0;
    try {
        $rag = new ClientRagPipeline($clientId);
        $chunks = (int)$rag->ingestDocument($docId);
    } catch (Throwable $e) {
        $db->prepare("UPDATE client_documents SET status='error', error_message=? WHERE id=?")
           ->execute([substr($e->getMessage(), 0, 1000), $docId]);
    }

    dbnDmsLogAudit($clientId, $userId ?: null, 'restore_version',
        ['version_id' => $vid, 'restored_to' => $next], $docId, $fid ?: null);

    dbnToolsRespond([
        'ok' => true,
        'document_id' => $docId,
        'new_version_number' => $next,
        'chunks' => $chunks,
    ]);
}

function deleteVersion(PDO $db, int $clientId, int $userId, string $tenantRole): void
{
    $input = dbnToolsJsonInput(2_000);
    $vid   = (int)($input['version_id'] ?? 0);
    if ($vid <= 0) {
        dbnToolsError('version_id is required.', 400, 'missing_version_id');
    }
    $stmt = $db->prepare('SELECT document_id, storage_path FROM client_document_versions WHERE id = ? AND client_id = ?');
    $stmt->execute([$vid, $clientId]);
    $ver = $stmt->fetch();
    if (!$ver) {
        dbnToolsError('Version not found.', 404, 'not_found');
    }
    $cur = assertDocumentReadable($db, $clientId, $userId, $tenantRole, (int)$ver['document_id']);
    $fid = $cur['folder_id'] ? (int)$cur['folder_id'] : 0;
    if (!dbnDmsUserCanAccessFolder($fid ?: null, 'write', $clientId, $userId, $tenantRole)) {
        dbnToolsError('Forbidden.', 403, 'forbidden');
    }
    $del = $db->prepare('DELETE FROM client_document_versions WHERE id = ? AND client_id = ?');
    $del->execute([$vid, $clientId]);
    if (!empty($ver['storage_path']) && is_file($ver['storage_path'])) {
        @unlink($ver['storage_path']);
    }
    dbnDmsLogAudit($clientId, $userId ?: null, 'delete_version', ['version_id' => $vid], (int)$ver['document_id']);
    dbnToolsRespond(['ok' => true]);
}
