import { randomUUID } from 'node:crypto';
import path from 'node:path';
import { getConnection } from '../../../modules/database/connection.js';
import { normalizeProjectPath } from '../../../shared/utils.js';
function normalizeProjectDisplayName(projectPath, customProjectName) {
    const trimmedCustomName = typeof customProjectName === 'string' ? customProjectName.trim() : '';
    if (trimmedCustomName.length > 0) {
        return trimmedCustomName;
    }
    const directoryName = path.basename(projectPath);
    return directoryName || projectPath;
}
export const projectsDb = {
    createProjectPath(userId, projectPath, customProjectName = null) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        const normalizedProjectName = normalizeProjectDisplayName(normalizedProjectPath, customProjectName);
        const attemptedId = randomUUID();
        const row = db.prepare(`
        INSERT INTO projects (project_id, user_id, project_path, custom_project_name, isArchived)
            VALUES (?, ?, ?, ?, 0)
            ON CONFLICT(user_id, project_path) DO UPDATE SET
            isArchived = 0
            WHERE projects.isArchived = 1
            RETURNING project_id, project_path, custom_project_name, isStarred, isArchived
        `).get(attemptedId, userId, normalizedProjectPath, normalizedProjectName);
        if (row) {
            return {
                outcome: row.project_id === attemptedId ? 'created' : 'reactivated_archived',
                project: row,
            };
        }
        const existingProject = projectsDb.getProjectPath(userId, normalizedProjectPath);
        return {
            outcome: 'active_conflict',
            project: existingProject,
        };
    },
    getProjectPath(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        const row = db.prepare(`
            SELECT project_id, project_path, custom_project_name, isStarred, isArchived
            FROM projects
            WHERE user_id = ? AND project_path = ?
        `).get(userId, normalizedProjectPath);
        return row ?? null;
    },
    getProjectById(userId, projectId) {
        const db = getConnection();
        const row = db.prepare(`
            SELECT project_id, project_path, custom_project_name, isStarred, isArchived
            FROM projects
            WHERE user_id = ? AND project_id = ?
        `).get(userId, projectId);
        return row ?? null;
    },
    /**
     * Resolve the absolute project directory from a database project_id.
     *
     * This is the canonical lookup used after the projectName → projectId migration:
     * API routes receive the DB-assigned `projectId` and must resolve the real folder
     * path through this helper before touching the filesystem. Returns `null` when the
     * project row does not exist so callers can respond with a 404.
     */
    getProjectPathById(userId, projectId) {
        const db = getConnection();
        const row = db.prepare(`
            SELECT project_path
            FROM projects
            WHERE user_id = ? AND project_id = ?
        `).get(userId, projectId);
        return row?.project_path ?? null;
    },
    getProjectPaths(userId) {
        const db = getConnection();
        return db.prepare(`
            SELECT project_id, project_path, custom_project_name, isStarred, isArchived
            FROM projects
            WHERE user_id = ? AND isArchived = 0
        `).all(userId);
    },
    /**
     * Archived rows are queried separately so archive-focused UIs can present
     * hidden workspaces without reintroducing them into the active sidebar list.
     */
    getArchivedProjectPaths(userId) {
        const db = getConnection();
        return db.prepare(`
            SELECT project_id, project_path, custom_project_name, isStarred, isArchived
            FROM projects
            WHERE user_id = ? AND isArchived = 1
        `).all(userId);
    },
    getCustomProjectName(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        const row = db.prepare(`
            SELECT custom_project_name
            FROM projects
            WHERE user_id = ? AND project_path = ?
        `).get(userId, normalizedProjectPath);
        return row?.custom_project_name ?? null;
    },
    updateCustomProjectName(userId, projectPath, customProjectName) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        db.prepare(`
            INSERT INTO projects (project_id, user_id, project_path, custom_project_name)
            VALUES (?, ?, ?, ?)
            ON CONFLICT(user_id, project_path) DO UPDATE SET custom_project_name = excluded.custom_project_name
        `).run(randomUUID(), userId, normalizedProjectPath, customProjectName);
    },
    updateCustomProjectNameById(userId, projectId, customProjectName) {
        const db = getConnection();
        db.prepare(`
            UPDATE projects
            SET custom_project_name = ?
            WHERE user_id = ? AND project_id = ?
        `).run(customProjectName, userId, projectId);
    },
    updateProjectIsStarred(userId, projectPath, isStarred) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        db.prepare(`
            UPDATE projects
            SET isStarred = ?
            WHERE user_id = ? AND project_path = ?
        `).run(isStarred ? 1 : 0, userId, normalizedProjectPath);
    },
    updateProjectIsStarredById(userId, projectId, isStarred) {
        const db = getConnection();
        db.prepare(`
            UPDATE projects
            SET isStarred = ?
            WHERE user_id = ? AND project_id = ?
        `).run(isStarred ? 1 : 0, userId, projectId);
    },
    updateProjectIsArchived(userId, projectPath, isArchived) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        db.prepare(`
            UPDATE projects
            SET isArchived = ?
            WHERE user_id = ? AND project_path = ?
        `).run(isArchived ? 1 : 0, userId, normalizedProjectPath);
    },
    updateProjectIsArchivedById(userId, projectId, isArchived) {
        const db = getConnection();
        db.prepare(`
            UPDATE projects
            SET isArchived = ?
            WHERE user_id = ? AND project_id = ?
        `).run(isArchived ? 1 : 0, userId, projectId);
    },
    deleteProjectPath(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        db.prepare(`
            DELETE FROM projects
            WHERE user_id = ? AND project_path = ?
        `).run(userId, normalizedProjectPath);
    },
    deleteProjectById(userId, projectId) {
        const db = getConnection();
        db.prepare(`
            DELETE FROM projects
            WHERE user_id = ? AND project_id = ?
        `).run(userId, projectId);
    },
    isProjectPathUsedByOthers(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        const rows = db.prepare(`
            SELECT u.username FROM projects p
            JOIN users u ON u.id = p.user_id
            WHERE p.project_path = ? AND p.user_id != ? AND p.isArchived = 0 AND u.is_active = 1
        `).all(normalizedProjectPath, userId);
        return {
            used: rows.length > 0,
            usernames: rows.map(r => r.username),
        };
    },
};
//# sourceMappingURL=projects.db.js.map