"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.canCreateDataset = exports.getDatasetList = void 0;
const drizzle_orm_1 = require("drizzle-orm");
const constants_1 = require("../../../constants");
const database_1 = require("../../../database");
const tables_1 = require("../../../database/tables");
const logger_1 = __importDefault(require("../../../logger"));
const get_upgrade_meta_1 = require("../../../util/get-upgrade-meta");
const time_1 = require("../../../util/time");
const decimal_js_1 = __importDefault(require("decimal.js"));
const restriction_message_1 = require("../../constants/restriction.message");
const getDatasetList = async (req, res) => {
    try {
        const { orgId, projectId, page = 1, limit = 10, filter, archived_data_required = 'true', search, status, fetchDynamicDatasets = 'true' } = req.query;
        const parsedLimit = Number(limit);
        const parsedPage = Number(page);
        const offset = (parsedPage - 1) * parsedLimit;
        const includeArchived = archived_data_required === 'true';
        const shouldFetchDynamicDatasets = fetchDynamicDatasets === 'true';
        // Mandatory projectId check
        if (!projectId) {
            res.status(400).json({
                success: false,
                message: 'projectId is required',
            });
            return;
        }
        // Parse filter array from query parameters
        const filterArray = [];
        if (filter && typeof filter === 'string') {
            filterArray.push(...filter
                .split(',')
                .map((f) => f.trim())
                .filter((f) => f.length > 0));
        }
        const db = await (0, database_1.getDb)();
        const buildFilterConditions = (filterArray) => {
            return filterArray?.map((filterStr) => {
                const prefix = `${filterStr}%`;
                return (0, drizzle_orm_1.sql) `
        (
          EXISTS (
            SELECT 1 FROM jsonb_array_elements(${tables_1.trusysDatasetsTable.fields}) AS field
            WHERE jsonb_typeof(field) = 'object' AND field->>'name' ILIKE ${prefix}
          )
          OR
          EXISTS (
            SELECT 1 FROM jsonb_array_elements_text(${tables_1.trusysDatasetsTable.fields}) AS field
            WHERE field ILIKE ${prefix}
          )
        )
      `;
            });
        };
        // Build all conditions for the count query
        const whereConditions = [];
        // Base condition with projectId
        whereConditions.push((0, drizzle_orm_1.eq)(tables_1.trusysDatasetsTable.projectId, projectId));
        // Add archived filter if needed
        if (!includeArchived) {
            whereConditions.push((0, drizzle_orm_1.eq)(tables_1.trusysDatasetsTable.is_archived, false));
        }
        // Add search filter if provided
        if (search && typeof search === 'string' && search.trim() !== '') {
            whereConditions.push((0, drizzle_orm_1.ilike)(tables_1.trusysDatasetsTable.name, `%${search}%`));
        }
        // Add status filter if provided
        if (status !== undefined) {
            const statusValue = typeof status === 'string' ? Number.parseInt(status, 10) : Number(status);
            if (!Number.isNaN(statusValue) && [constants_1.DatasetStatus.DRAFT, constants_1.DatasetStatus.LIVE].includes(statusValue)) {
                whereConditions.push((0, drizzle_orm_1.eq)(tables_1.trusysDatasetsTable.status, statusValue));
            }
        }
        // Add field filters if provided
        if (filterArray?.length > 0) {
            const filterConditions = buildFilterConditions(filterArray);
            whereConditions.push(...filterConditions);
        }
        // Exclude dynamic datasets (generateOnEvaluation = true) if fetchDynamicDatasets is false
        if (!shouldFetchDynamicDatasets) {
            whereConditions.push((0, drizzle_orm_1.sql) `(
          ${tables_1.trusysDatasetsTable.config}->>'generateOnEvaluation' IS NULL
          OR ${tables_1.trusysDatasetsTable.config}->>'generateOnEvaluation' != 'true'
        )`);
        }
        // Combine all conditions
        const whereCondition = whereConditions.length > 0
            ? whereConditions.length === 1
                ? whereConditions[0]
                : (0, drizzle_orm_1.sql) `${drizzle_orm_1.sql.join(whereConditions, (0, drizzle_orm_1.sql) ` AND `)}`
            : null;
        const query = db
            .select({
            id: tables_1.trusysDatasetsTable.id,
            name: tables_1.trusysDatasetsTable.name,
            type: tables_1.trusysDatasetsTable.type,
            status: tables_1.trusysDatasetsTable.status,
            fields: tables_1.trusysDatasetsTable.fields,
            createdAt: tables_1.trusysDatasetsTable.createdAt,
            config: tables_1.trusysDatasetsTable.config,
            is_archived: tables_1.trusysDatasetsTable.is_archived,
            testRunCount: (0, drizzle_orm_1.sql) `(
          SELECT COUNT(*) FROM ${tables_1.testRunsToDatasetsTable}
          WHERE ${tables_1.testRunsToDatasetsTable.datasetId} = ${tables_1.trusysDatasetsTable.id}
        )`,
        })
            .from(tables_1.trusysDatasetsTable)
            .orderBy(tables_1.trusysDatasetsTable.is_archived, (0, drizzle_orm_1.desc)(tables_1.trusysDatasetsTable.createdAt));
        // Get total count for pagination
        const totalCountQuery = db.select({ count: (0, drizzle_orm_1.sql) `count(*)` }).from(tables_1.trusysDatasetsTable);
        // Apply the condition if it exists
        if (whereCondition) {
            query.where(whereCondition);
            totalCountQuery.where(whereCondition);
        }
        const totalCount = await totalCountQuery.then((result) => Number(result[0].count));
        const { upgradeMetadata, isEnterprise, restrictionsData, globalBanner, } = await (0, get_upgrade_meta_1.getUpgradeMetaByOrgId)(orgId);
        if (!isEnterprise && restrictionsData?.datasets > 0) {
            const whereConditions = (0, time_1.createTimespanWhereConditions)({
                table: tables_1.trusysDatasetsTable,
                timeColumn: 'createdAt',
                orgId: orgId,
                timespan: restrictionsData?.datasets_timespan || 'lifetime',
            });
            const count = await db
                .select({ count: (0, drizzle_orm_1.sql) `count(*)` })
                .from(tables_1.trusysDatasetsTable)
                .where(whereConditions)
                .then((result) => Number(result[0]?.count));
            if (count != 0
                && new decimal_js_1.default(count).gte(restrictionsData?.datasets ?? 0)) {
                upgradeMetadata.upgradeRequired = true;
                upgradeMetadata.topUpRequired = false;
                upgradeMetadata.upgradeTitle = restriction_message_1.RESTRICTION_MESSAGE.upgrade.title;
                upgradeMetadata.upgradeMessage = restriction_message_1.RESTRICTION_MESSAGE.upgrade.message;
                upgradeMetadata.currentPlan = restrictionsData?.currentPlan ?? '';
                upgradeMetadata.currentPlanId = restrictionsData?.currentPlanId ?? '';
            }
        }
        // Apply pagination
        query.limit(parsedLimit).offset(offset);
        const datasets = await query;
        logger_1.default.info(`Loaded ${datasets?.length} datasets`);
        // Get counts for each dataset
        const datasetIds = datasets.map((d) => d.id);
        let recordsCounts = {};
        if (datasetIds.length > 0) {
            // Get records counts
            const recordsCountQuery = await db
                .select({
                datasetId: tables_1.datasetRecordsTable.datasetId,
                count: (0, drizzle_orm_1.sql) `COUNT(*)`.as('count'),
            })
                .from(tables_1.datasetRecordsTable)
                .where((0, drizzle_orm_1.inArray)(tables_1.datasetRecordsTable.datasetId, datasetIds))
                .groupBy(tables_1.datasetRecordsTable.datasetId);
            recordsCounts = recordsCountQuery.reduce((acc, row) => {
                acc[row.datasetId] = Number(row.count);
                return acc;
            }, {});
        }
        logger_1.default.info(`Sample dataset with recordsCount: ${datasets[0] ? JSON.stringify({ id: datasets[0].id, recordsCount: recordsCounts[datasets[0].id] || 0 }) : 'No datasets'}`);
        const resultDatasets = datasets?.map((item) => ({
            ...item,
            fields: item?.type === constants_1.DATASET_TYPE.GENERATE
                ? item?.fields?.map((field) => field?.name)
                : (item?.fields ?? []),
            fieldWithType: item?.type === constants_1.DATASET_TYPE.GENERATE
                ? item?.fields?.map((field) => ({ name: field?.name, type: field?.type }))
                : (item?.fields ?? []),
            count: item?.config?.generateOnEvaluation ? 0 : recordsCounts[item.id] || 0,
            testRunCount: Number(item?.testRunCount) || 0,
        }));
        res.json({
            data: resultDatasets,
            pagination: {
                total: totalCount,
                page: parsedPage,
                limit: parsedLimit,
                totalPages: Math.ceil(totalCount / parsedLimit),
            },
            upgradeMetadata,
            globalBanner,
        });
    }
    catch (error) {
        logger_1.default.error(`Error fetching datasets: ${error}`);
        res.status(500).json({
            success: false,
            message: 'Failed to fetch datasets',
        });
    }
};
exports.getDatasetList = getDatasetList;
const canCreateDataset = async (req, res) => {
    try {
        const { orgId } = req.query;
        const { isEnterprise, restrictionsData, upgradeMetadata, globalBanner, wallet, thresholds, } = await (0, get_upgrade_meta_1.getUpgradeMetaByOrgId)(orgId);
        const db = await (0, database_1.getDb)();
        if (!isEnterprise && restrictionsData?.datasets > 0) {
            const whereConditions = (0, time_1.createTimespanWhereConditions)({
                table: tables_1.trusysDatasetsTable,
                timeColumn: 'createdAt',
                orgId: orgId,
                timespan: restrictionsData?.datasets_timespan || 'lifetime',
            });
            const count = await db
                .select({ count: (0, drizzle_orm_1.sql) `count(*)` })
                .from(tables_1.trusysDatasetsTable)
                .where(whereConditions)
                .then((result) => Number(result[0]?.count));
            if (count != 0
                && new decimal_js_1.default(count).gte(restrictionsData?.datasets ?? 0)) {
                upgradeMetadata.upgradeRequired = true;
                upgradeMetadata.topUpRequired = false;
                upgradeMetadata.upgradeTitle = restriction_message_1.RESTRICTION_MESSAGE.upgrade.title;
                upgradeMetadata.upgradeMessage = restriction_message_1.RESTRICTION_MESSAGE.upgrade.message;
                upgradeMetadata.currentPlan = restrictionsData?.currentPlan ?? '';
                upgradeMetadata.currentPlanId = restrictionsData?.currentPlanId ?? '';
            }
        }
        if (!isEnterprise && new decimal_js_1.default(wallet?.credits ?? 0).lte(0)) {
            upgradeMetadata.topUpRequired = true;
            upgradeMetadata.upgradeRequired = false;
            upgradeMetadata.upgradeTitle = restriction_message_1.RESTRICTION_MESSAGE.lowCredits.title;
            upgradeMetadata.upgradeMessage = restriction_message_1.RESTRICTION_MESSAGE.lowCredits.message;
            upgradeMetadata.currentPlan = restrictionsData?.currentPlan ?? '';
            upgradeMetadata.currentPlanId = restrictionsData?.currentPlanId ?? '';
            globalBanner.show = true;
            globalBanner.data.content = `You're low on TRU CREDITS`;
            globalBanner.data.type = 'credits';
            globalBanner.data.action = 'Add TRU CREDITS';
            globalBanner.data.actionType = 'credits';
            globalBanner.data.actionContent = `to continue evaluating your application`;
        }
        if (!isEnterprise) {
            const isLowOnBalance = new decimal_js_1.default(wallet?.credits ?? 0).lte(new decimal_js_1.default(thresholds?.walletNotificationThreshold ?? 0));
            if (isLowOnBalance) {
                globalBanner.show = true;
                globalBanner.data.content = `You're low on TRU CREDITS`;
                globalBanner.data.type = 'credits';
                globalBanner.data.action = 'Add TRU CREDITS';
                globalBanner.data.actionType = 'credits';
                globalBanner.data.actionContent = `to continue evaluating your application`;
            }
        }
        res.json({
            upgradeMetadata,
            globalBanner,
        });
    }
    catch (error) {
        logger_1.default.error(`Error checking if can create ai dataset: ${error}`);
        res.status(500).json({
            success: false,
            message: 'Failed to check if can create ai dataset',
        });
    }
};
exports.canCreateDataset = canCreateDataset;
//# sourceMappingURL=get-dataset-list.js.map