"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateDatasetDetails = void 0;
/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
const drizzle_orm_1 = require("drizzle-orm");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const lodash_1 = __importDefault(require("lodash"));
const uuid_1 = require("uuid");
const constants_1 = require("../../../constants");
const database_1 = require("../../../database");
const tables_1 = require("../../../database/tables");
const logger_1 = __importDefault(require("../../../logger"));
const uploadFilesToAzure_1 = require("../../../util/uploadFilesToAzure");
const convertTextToAudioWithProvider_1 = require("../../../util/convertTextToAudioWithProvider/convertTextToAudioWithProvider");
const billing_logger_1 = __importDefault(require("../../services/billing/billing-logger"));
const constants_2 = require("../../../constants");
const activityLogService_1 = require("../../services/activityLogService");
const datasetDynamicDatasetLanguage_1 = require("../../services/datasetDynamicDatasetLanguage");
// Function to call bulk analyze API for encryption
const callBulkAnalyzeAPI = async (texts, language = 'en') => {
    try {
        const response = await fetch('https://presidio-analyzer.spydra.app/bulk_analyze', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'x-api-key': 'abde3594-4450-41e7-a41c-1450cb0808a9',
            },
            body: JSON.stringify({
                texts,
                language,
            }),
        });
        const result = await response.json();
        return result;
    }
    catch (error) {
        console.error('Error calling bulk analyze API:', error);
        throw error;
    }
};
// Function to encrypt fields in CSV data
const encryptFieldsInCSVData = async (csvData, encryptFields, language = 'en') => {
    try {
        if (!encryptFields || encryptFields.length === 0) {
            // No fields need encryption, return original data
            return csvData;
        }
        logger_1.default.info(`Encrypting fields: ${JSON.stringify(encryptFields)}`);
        // Break csvData into batches of 10
        const batchSize = 10;
        const batches = [];
        for (let i = 0; i < csvData.length; i += batchSize) {
            batches.push(csvData.slice(i, i + batchSize));
        }
        const encryptedResults = [];
        // Process each batch
        for (const batch of batches) {
            // Create array of strings for bulk analyze
            const textsToAnalyze = [];
            for (const row of batch) {
                for (const fieldName of encryptFields) {
                    if (row[fieldName] !== undefined && row[fieldName] !== null) {
                        // Create more natural text format that the analyzer can recognize
                        textsToAnalyze.push(`${fieldName}: ${row[fieldName]}`);
                    }
                }
            }
            logger_1.default.info(`Processing batch with ${textsToAnalyze.length} texts to analyze`);
            if (textsToAnalyze.length > 0) {
                // Call bulk analyze API for this batch
                const bulkAnalyzeResult = await callBulkAnalyzeAPI(textsToAnalyze, language);
                // Filter bulkAnalyzeResult to only include objects with analyzer_results scores > 0.75
                const filteredBulkAnalyzeResult = bulkAnalyzeResult
                    .map((item) => {
                    if (item.analyzer_results && Array.isArray(item.analyzer_results)) {
                        // Filter analyzer_results to only include those with score > 0.75
                        const filteredAnalyzerResults = item.analyzer_results.filter((result) => result.score >= 0.75);
                        // Return the item with filtered analyzer_results
                        return {
                            ...item,
                            analyzer_results: filteredAnalyzerResults,
                        };
                    }
                    return item;
                })
                    .filter((item) => {
                    // Only keep items that have analyzer_results with scores > 0.75
                    return item.analyzer_results && item.analyzer_results.length > 0;
                });
                logger_1.default.info(`Filtered ${filteredBulkAnalyzeResult.length} items with score > 0.75`);
                // Create payload for bulk_anonymize endpoint
                const anonymizePayload = filteredBulkAnalyzeResult.map((item) => ({
                    text: item.text,
                    anonymizers: {
                        PERSON: {
                            type: 'fpe',
                            key: 'NjrK7ZmS0zNwN3PsnReNWg==',
                            alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz@_. ',
                        },
                        PHONE_NUMBER: {
                            type: 'fpe',
                            key: 'NjrK7ZmS0zNwN3PsnReNWg==',
                            alphabet: '0123456789+ ()-',
                        },
                        EMAIL_ADDRESS: {
                            type: 'fpe',
                            key: 'NjrK7ZmS0zNwN3PsnReNWg==',
                            alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz@_.',
                        },
                        PAN: {
                            type: 'fpe',
                            key: 'NjrK7ZmS0zNwN3PsnReNWg==',
                            alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz',
                        },
                        CREDIT_CARD: {
                            type: 'fpe',
                            key: 'NjrK7ZmS0zNwN3PsnReNWg==',
                            alphabet: '0123456789- ',
                        },
                        LOCATION: {
                            type: 'fpe',
                            key: 'NjrK7ZmS0zNwN3PsnReNWg==',
                            alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz@_. ',
                        },
                    },
                    analyzer_results: item.analyzer_results,
                }));
                // Call bulk_anonymize endpoint
                let anonymizeResult = null;
                try {
                    const anonymizeResponse = await fetch('https://presidio-anonymizer.spydra.app/bulk_anonymize', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'x-api-key': 'abde3594-4450-41e7-a41c-1450cb0808a9',
                        },
                        body: JSON.stringify(anonymizePayload),
                    });
                    if (anonymizeResponse.ok) {
                        anonymizeResult = await anonymizeResponse.json();
                        logger_1.default.info(`Bulk anonymize API response received for ${anonymizeResult.length} items`);
                        // Update csvData with anonymized values
                        if (anonymizeResult && Array.isArray(anonymizeResult)) {
                            // Create a mapping from original text to anonymized text
                            const textToAnonymizedMap = new Map();
                            anonymizeResult.forEach((item) => {
                                textToAnonymizedMap.set(item.text, item.anonymized_text);
                            });
                            // Update each row in the current batch
                            for (const row of batch) {
                                for (const fieldName of encryptFields) {
                                    if (row[fieldName] !== undefined && row[fieldName] !== null) {
                                        const originalText = `${fieldName}: ${row[fieldName]}`;
                                        const anonymizedText = textToAnonymizedMap.get(originalText);
                                        if (anonymizedText) {
                                            // Extract the anonymized value from the anonymized text
                                            // Format: "user_id: [PERSON]" -> extract "[PERSON]"
                                            const colonIndex = anonymizedText.indexOf(':');
                                            if (colonIndex !== -1) {
                                                const anonymizedValue = anonymizedText.substring(colonIndex + 1).trim();
                                                row[fieldName] = anonymizedValue;
                                                logger_1.default.info(`Encrypted ${fieldName}: ${originalText} -> ${anonymizedText}`);
                                            }
                                        }
                                    }
                                }
                            }
                            logger_1.default.info(`Updated ${batch.length} rows with anonymized values`);
                        }
                    }
                    else {
                        const errorText = await anonymizeResponse.text();
                        logger_1.default.error(`Bulk anonymize API error: ${anonymizeResponse.status} - ${errorText}`);
                    }
                }
                catch (anonymizeError) {
                    logger_1.default.error(`Error calling bulk anonymize API: ${anonymizeError}`);
                }
                // Add processed batch to encryptedResults
                encryptedResults.push(...batch);
            }
            else {
                // No fields to encrypt in this batch, add as is
                encryptedResults.push(...batch);
            }
        }
        return encryptedResults;
    }
    catch (error) {
        logger_1.default.error(`Error encrypting CSV fields: ${error}`);
        // If encryption fails, return original data
        return csvData;
    }
};
const processVoiceField = async (value, columnName, resultCounter, audioFolder, workspaceId, outputFormat, sampleRate, language) => {
    try {
        const audioFilePath = await (0, convertTextToAudioWithProvider_1.convertTextToAudioFile)(value, workspaceId, outputFormat, sampleRate, columnName, resultCounter, audioFolder, language);
        return {
            type: 'voice',
            value,
            wavFilePath: audioFilePath,
            // Match blob name to on-disk file (includes .wav | .mp3 | .opus from selected output format)
            fileName: audioFilePath ? path.basename(audioFilePath) : `${resultCounter}-${columnName}`,
        };
    }
    catch (error) {
        logger_1.default.error(`Error processing voice field ${columnName}: ${error}`);
        return {
            type: 'voice',
            value,
            wavFilePath: '',
            fileName: '',
        };
    }
};
const processDatasetRow = async (row, fields, resultCounter, audioFolder, workspaceId, language) => {
    const updatedRow = {};
    const voiceFields = [];
    for (const [columnName, value] of Object.entries(row)) {
        const field = fields?.find((f) => f?.name === columnName);
        if (field?.type === constants_1.DATASET_VAR_TYPE.VOICE) {
            // Get outputFormat and sampleRate from field, with defaults (UI stores lowercase mp3|wav|opus)
            const outputFormat = String(field?.outputFormat || 'wav').toLowerCase().trim() || 'wav';
            const sampleRate = String(field?.sampleRate || '44100').trim() || '44100';
            const fieldLanguage = field?.language?.SpeechSynthesisLanguage || language || 'en-US';
            const processedField = await processVoiceField(value, columnName, resultCounter, audioFolder, workspaceId, outputFormat, sampleRate, fieldLanguage);
            voiceFields.push({ field: columnName, data: processedField });
            updatedRow[columnName] = processedField;
        }
        else {
            updatedRow[columnName] = {
                type: 'text',
                value,
            };
        }
    }
    const filesToUpload = voiceFields
        ?.map(({ data }) => ({
        wavFilePath: data?.wavFilePath,
        fileName: data?.fileName,
    }))
        ?.filter((file) => file?.wavFilePath &&
        String(file.wavFilePath).trim() &&
        file?.fileName &&
        fs.existsSync(file.wavFilePath));
    return { row: updatedRow, filesToUpload };
};
const updateDatasetDetails = async (req, res) => {
    try {
        const token = req.headers['x-access-token'] || req.headers.authorization;
        const { name, datasetId, orgId, projectId, status = 0, type, data, fields, encryptFields, config, isLive = false, tokenUsages, } = req.body;
        let updatedFields = fields;
        // Log the received fields and encrypt fields
        logger_1.default.info(`Dataset creation/update request received - Name: ${name}, Type: ${type}, Fields: ${JSON.stringify(fields || [])}, EncryptFields: ${JSON.stringify(encryptFields || [])}, ProjectId: ${projectId}`);
        if (lodash_1.default.isEmpty(name) || lodash_1.default.isEmpty(projectId) || lodash_1.default.isEmpty(type)) {
            res.status(400).json({ error: 'Dataset name, type and projectId is required' });
            return;
        }
        const db = await (0, database_1.getDb)();
        let normalizedBaseConfig = typeof config === 'object' && config !== null ? { ...config } : {};
        const bodyLanguage = req.body.language;
        if (bodyLanguage !== undefined && bodyLanguage !== null) {
            normalizedBaseConfig = { ...normalizedBaseConfig, language: bodyLanguage };
        }
        const persistedConfig = type === 'upload' && encryptFields != null && Array.isArray(encryptFields)
            ? { ...normalizedBaseConfig, encryptFields }
            : normalizedBaseConfig;
        const toNumber = (v) => {
            if (v == null) {
                return 0;
            }
            if (typeof v === 'number') {
                return v;
            }
            if (typeof v === 'string') {
                const n = Number(v);
                return Number.isFinite(n) ? n : 0;
            }
            // Handle potential BigNumber-like objects that expose .toNumber()
            if (typeof v.toNumber === 'function') {
                try {
                    return v.toNumber();
                }
                catch {
                    return 0;
                }
            }
            return 0;
        };
        // Encrypt fields for CSV upload if encryptFields are provided
        let processedData = data;
        if (type === 'upload' && encryptFields && encryptFields.length > 0) {
            try {
                logger_1.default.info(`Starting encryption for upload dataset with fields: ${JSON.stringify(encryptFields)}`);
                // For upload type, data is an array of objects
                if (Array.isArray(data)) {
                    processedData = await encryptFieldsInCSVData(data, encryptFields, 'en');
                    logger_1.default.info(`Encryption completed for ${processedData.length} rows`);
                }
            }
            catch (encryptionError) {
                logger_1.default.error(`Error during encryption: ${encryptionError}`);
                // Continue with original data if encryption fails
                processedData = data;
            }
        }
        // Check for existing prompts library with same name and projectId
        // Handle voice data generation
        if (status === constants_1.DatasetStatus.LIVE && type === constants_1.DATASET_TYPE.GENERATE && !isLive) {
            const audioFolder = 'audioprompts';
            if (!fs.existsSync(audioFolder)) {
                fs.mkdirSync(audioFolder);
            }
            const defaultLanguage = (0, datasetDynamicDatasetLanguage_1.getDatasetDefaultTtsLocale)(persistedConfig);
            try {
                // Process rows with limited concurrency to avoid hitting TTS provider limits.
                const CONCURRENCY_LIMIT = 5;
                const results = [];
                // Prefer processedData if available (may include encrypted values), otherwise fall back to raw data.
                const rowsSource = Array.isArray(processedData)
                    ? processedData
                    : (Array.isArray(data) ? data : []);
                const totalRows = rowsSource.length;
                for (let start = 0; start < totalRows; start += CONCURRENCY_LIMIT) {
                    const slice = rowsSource.slice(start, start + CONCURRENCY_LIMIT);
                    const batchResults = await Promise.all(slice.map((row, idx) => processDatasetRow(row, fields, start + idx + 1, audioFolder, orgId, defaultLanguage)));
                    results.push(...batchResults);
                }
                const allFilesToUpload = results
                    ?.flatMap((result) => result?.filesToUpload)
                    ?.filter((file) => file?.wavFilePath &&
                    String(file.wavFilePath).trim() &&
                    file?.fileName &&
                    fs.existsSync(file.wavFilePath));
                if (!allFilesToUpload?.length) {
                    logger_1.default.warn('No voice audio files were generated for upload; dataset rows will keep text-only voice metadata');
                }
                // Upload files in parallel batches of 10
                const batchSize = 10;
                const batches = [];
                for (let i = 0; i < (allFilesToUpload?.length ?? 0); i += batchSize) {
                    const batch = allFilesToUpload.slice(i, i + batchSize);
                    batches.push((0, uploadFilesToAzure_1.uploadAudioFiles)(batch, token, `workspace/${orgId}/project/${projectId}/dataset/${datasetId}`));
                }
                // Wait for all batches to complete and merge results
                const batchResults = await Promise.all(batches);
                const urlMap = batchResults.reduce((acc, curr) => ({ ...acc, ...curr }), {});
                // Delete local wav files after upload
                for (const file of allFilesToUpload) {
                    if (file?.wavFilePath && fs.existsSync(file.wavFilePath)) {
                        try {
                            fs.unlinkSync(file.wavFilePath);
                        }
                        catch (err) {
                            logger_1.default.error(`Failed to delete file ${file.wavFilePath}: ${err}`);
                        }
                    }
                }
                // Update rows with URLs
                const processedRows = results?.map(({ row }) => {
                    const updatedRow = { ...row };
                    Object.entries(updatedRow)?.forEach(([key, value]) => {
                        if (value && typeof value === 'object' && 'type' in value && value.type === 'voice') {
                            const voiceValue = value;
                            updatedRow[key] = {
                                value: voiceValue?.value,
                                type: voiceValue?.type,
                                voiceUrl: urlMap[voiceValue?.fileName] || null,
                            };
                        }
                    });
                    return updatedRow;
                });
                // Replace source rows in-place so downstream logic sees voice metadata.
                if (Array.isArray(processedData)) {
                    processedData.splice(0, processedData.length, ...processedRows);
                }
                else if (Array.isArray(data)) {
                    data.splice(0, data.length, ...processedRows);
                }
                else {
                    logger_1.default.warn('Audio dataset processing completed, but neither processedData nor data is an array; skipping in-place row update');
                }
                logger_1.default.info('All voice files processed and uploaded successfully');
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                logger_1.default.error(`Error in processing audio dataset: ${message}`);
                // Special-case rate limit / concurrency errors from TTS providers (e.g., ElevenLabs 429)
                // so the UI can present a clear, actionable message instead of a generic 500.
                if (message.includes('429') ||
                    message.toLowerCase().includes('rate_limit_error') ||
                    message.toLowerCase().includes('too_many_concurrent_requests')) {
                    res.status(429).json({
                        error: 'Audio provider rate limit exceeded while generating voice fields. Please wait a moment and try again, or reduce concurrent requests.',
                    });
                    return;
                }
                res.status(500).json({ error: 'Error while handling audio datasets' });
                return;
            }
        }
        if (status === constants_1.DatasetStatus.LIVE && type === constants_1.DATASET_TYPE.CONNECT) {
            const response = await fetch(config?.datasetUrl);
            const responseData = await response.json();
            updatedFields = responseData?.features?.map((item) => item?.name) || [];
        }
        const statusNum = Number(status);
        let resultDataset;
        if (datasetId) {
            // Update existing dataset
            const [existingRow] = await db
                .select({ status: tables_1.trusysDatasetsTable.status })
                .from(tables_1.trusysDatasetsTable)
                .where((0, drizzle_orm_1.eq)(tables_1.trusysDatasetsTable.id, datasetId))
                .limit(1);
            if (!existingRow) {
                res.status(404).json({ error: 'Dataset not found' });
                return;
            }
            const wasDraft = Number(existingRow.status) === constants_1.DatasetStatus.DRAFT;
            const publishDraftToLive = statusNum === constants_1.DatasetStatus.LIVE && wasDraft;
            const [updatedDataset] = await db
                .update(tables_1.trusysDatasetsTable)
                .set({
                name,
                projectId,
                status,
                type,
                fields: updatedFields,
                config: persistedConfig,
                updatedAt: new Date(),
                ...(publishDraftToLive ? { createdAt: new Date() } : {}),
            })
                .where((0, drizzle_orm_1.eq)(tables_1.trusysDatasetsTable.id, datasetId))
                .returning();
            if (!updatedDataset) {
                res.status(404).json({ error: 'Dataset not found' });
                return;
            }
            // Delete existing records and insert new ones
            await db.delete(tables_1.datasetRecordsTable).where((0, drizzle_orm_1.eq)(tables_1.datasetRecordsTable.datasetId, datasetId));
            if (processedData && processedData.length > 0) {
                const recordInserts = processedData.map((record, index) => ({
                    id: (0, uuid_1.v4)(),
                    datasetId,
                    recordData: record,
                    recordIndex: index,
                }));
                await db.insert(tables_1.datasetRecordsTable).values(recordInserts);
            }
            resultDataset = updatedDataset;
            if (lodash_1.default.isEmpty(tokenUsages) === false &&
                lodash_1.default.isEmpty(tokenUsages?.tokenUsage) === false &&
                (toNumber(tokenUsages?.tokenUsage?.total) > 0 ||
                    toNumber(tokenUsages?.cost) > 0 ||
                    toNumber(tokenUsages?.tokenUsage?.prompt) > 0 ||
                    toNumber(tokenUsages?.tokenUsage?.completion) > 0 ||
                    toNumber(tokenUsages?.tokenUsage?.cached) > 0)) {
                billing_logger_1.default.logDatasetUsage({
                    workspaceId: orgId,
                    datasetId,
                    tokenUsage: {
                        prompt: tokenUsages?.tokenUsage?.prompt ?? 0,
                        completion: tokenUsages?.tokenUsage?.completion ?? 0,
                        total: tokenUsages?.tokenUsage?.total ?? 0,
                        cached: tokenUsages?.tokenUsage?.cached ?? 0,
                    },
                    cost: tokenUsages?.cost,
                    metadata: {
                        projectId,
                        datasetId,
                        name,
                    },
                    provider: 'trusys',
                    model: 'gpt-4.1',
                });
            }
        }
        else {
            // Create new dataset if id is not present
            const newDatasetId = (0, uuid_1.v4)();
            const [createdDataset] = await db
                .insert(tables_1.trusysDatasetsTable)
                .values({
                id: newDatasetId,
                name,
                projectId,
                status,
                type,
                fields: updatedFields,
                config: persistedConfig,
                createdAt: new Date(),
                updatedAt: new Date(),
            })
                .returning();
            if (!createdDataset) {
                res.status(500).json({ error: 'Failed to create dataset' });
                return;
            }
            // Insert records into datasetRecordsTable
            if (processedData && processedData.length > 0) {
                const recordInserts = processedData.map((record, index) => ({
                    id: (0, uuid_1.v4)(),
                    datasetId: newDatasetId,
                    recordData: record,
                    recordIndex: index,
                }));
                await db.insert(tables_1.datasetRecordsTable).values(recordInserts);
            }
            resultDataset = createdDataset;
            if (lodash_1.default.isEmpty(tokenUsages) === false &&
                lodash_1.default.isEmpty(tokenUsages?.tokenUsage) === false &&
                (toNumber(tokenUsages?.tokenUsage?.total) > 0 ||
                    toNumber(tokenUsages?.cost) > 0 ||
                    toNumber(tokenUsages?.tokenUsage?.prompt) > 0 ||
                    toNumber(tokenUsages?.tokenUsage?.completion) > 0 ||
                    toNumber(tokenUsages?.tokenUsage?.cached) > 0)) {
                billing_logger_1.default.logDatasetUsage({
                    workspaceId: orgId,
                    datasetId: newDatasetId,
                    tokenUsage: {
                        prompt: tokenUsages?.tokenUsage?.prompt ?? 0,
                        completion: tokenUsages?.tokenUsage?.completion ?? 0,
                        total: tokenUsages?.tokenUsage?.total ?? 0,
                        cached: tokenUsages?.tokenUsage?.cached ?? 0,
                    },
                    cost: tokenUsages?.cost,
                    metadata: {
                        projectId,
                        datasetId: newDatasetId,
                        name,
                    },
                    provider: 'trusys',
                    model: 'gpt-4.1',
                });
            }
        }
        // Log activity for dataset update
        try {
            const { userId, userName } = (0, activityLogService_1.getUserInfo)(req);
            const [orgName, projectName] = await Promise.all([
                (0, activityLogService_1.fetchOrgName)(token, orgId),
                (0, activityLogService_1.fetchProjectName)(token, orgId, projectId),
            ]);
            await (0, activityLogService_1.logActivity)(token, {
                type: constants_2.ActivityType.UPDATE_DATASET,
                params: (0, activityLogService_1.buildActivityParams)({
                    dataset_name: { value: name, _id: datasetId || resultDataset?.id },
                    user_name: { value: userName, _id: userId },
                    org_name: { value: orgName || orgId, _id: orgId },
                    project_name: { value: projectName || projectId, _id: projectId },
                }),
                project_id: projectId,
                org_id: orgId,
                created_by: userId,
                updated_by: userId,
            });
        }
        catch (activityError) {
            logger_1.default.error(`Error logging activity for update dataset: ${activityError}`);
        }
        res.json({ data: resultDataset });
    }
    catch (error) {
        console.error('Error updating dataset:', error);
        res.status(500).json({ error: 'Failed to update dataset' });
    }
};
exports.updateDatasetDetails = updateDatasetDetails;
//# sourceMappingURL=update-dataset-details.js.map