-- name: CreateFolder :one
INSERT INTO folders (path, parentId, clientId, createdBy)
VALUES ($1, $2, $3, $4)
RETURNING *;

-- name: GetFolderByID :one
SELECT * FROM folders
WHERE id = $1;

-- name: GetFolderByPath :one
SELECT * FROM folders
WHERE clientId = $1 AND path = $2;

-- name: GetFoldersByClientID :many
SELECT * FROM folders
WHERE clientId = $1
ORDER BY path;

-- name: GetFoldersByParentID :many
SELECT * FROM folders
WHERE parentId = $1
ORDER BY path;

-- name: RenameFolder :exec
UPDATE folders
SET path = $2
WHERE id = $1;

-- name: GetFolderTree :many
WITH RECURSIVE folder_tree AS (
    -- Base case: start with the target folder
    SELECT id, path, parentId, clientId, createdAt, createdBy
    FROM folders
    WHERE id = $1

    UNION ALL

    -- Recursive case: find all child folders
    SELECT f.id, f.path, f.parentId, f.clientId, f.createdAt, f.createdBy
    FROM folders f
    INNER JOIN folder_tree ft ON f.parentId = ft.id
)
SELECT id, path, parentId, clientId, createdAt, createdBy
FROM folder_tree
ORDER BY path;

-- name: GetRootFolders :many
-- Returns folders with null parentId (should only be the "/" root folder for each client)
SELECT * FROM folders
WHERE clientId = $1 AND parentId IS NULL
ORDER BY path;

-- name: GetTopLevelFolders :many
-- Returns folders that are direct children of the root folder "/"
-- These are the user-visible top-level folders (e.g., /folder1, /folder2)
SELECT f.* FROM folders f
INNER JOIN folders root ON f.parentId = root.id
WHERE f.clientId = $1 AND root.path = '/'
ORDER BY f.path;

-- name: GetClientRootFolder :one
-- Returns the root folder "/" for a client
SELECT * FROM folders
WHERE clientId = $1 AND path = '/';

-- name: GetDocumentsByFolder :many
SELECT * FROM documents
WHERE folderId = $1
ORDER BY id;

-- name: CountDocumentsByFolder :one
SELECT COUNT(*) as total FROM documents
WHERE folderId = $1;

-- name: GetFolderLabelCounts :many
SELECT dl.label, COUNT(DISTINCT dl.documentId) as count
FROM documents d
INNER JOIN documentLabels dl ON d.id = dl.documentId
WHERE d.folderId = $1
GROUP BY dl.label
ORDER BY dl.label;

-- name: UpsertFolder :one
-- Insert a folder if it doesn't exist, or return the existing one
-- Used for auto-creating folder hierarchies during document upload
INSERT INTO folders (path, parentId, clientId, createdBy)
VALUES ($1, $2, $3, $4)
ON CONFLICT (clientId, path) DO UPDATE SET path = EXCLUDED.path
RETURNING *;

-- name: GetDocumentsByFolderEnriched :many
-- Gets documents in a folder with all enriched metadata fields
SELECT
    d.id,
    d.hash,
    d.folderId,
    d.filename,
    d.originalPath,
    d.file_size_bytes
FROM documents d
WHERE d.folderId = $1
ORDER BY d.id;
