"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const asyncHandler_1 = require("../utils/asyncHandler");
const db_1 = require("../db");
const schema_1 = require("../db/schema");
const drizzle_orm_1 = require("drizzle-orm");
const auth_1 = require("../utils/auth");
const errorHandler_1 = require("../middleware/errorHandler");
const validation_1 = require("../utils/validation");
const router = (0, express_1.Router)();
router.use(auth_1.authMiddleware);
// Helper to build nested subtask tree
const buildSubtaskTree = (allSubtasks, parentId = null) => {
    return allSubtasks
        .filter((s) => s.parentSubtaskId === parentId)
        .sort((a, b) => a.order - b.order)
        .map((s) => ({
        ...s,
        subtasks: buildSubtaskTree(allSubtasks, s.id),
    }));
};
router.get('/task/:taskId', (0, asyncHandler_1.asyncHandler)(async (req, res) => {
    const userId = req.user.userId;
    // Verify task exists and belongs to user
    const task = await db_1.db
        .select()
        .from(schema_1.tasks)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.tasks.id, req.params.taskId), (0, drizzle_orm_1.eq)(schema_1.tasks.userId, userId)))
        .limit(1);
    if (task.length === 0) {
        throw new errorHandler_1.AppError('NOT_FOUND', 'Task not found', 404);
    }
    const taskSubtasks = await db_1.db
        .select()
        .from(schema_1.subtasks)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.subtasks.taskId, req.params.taskId), (0, drizzle_orm_1.eq)(schema_1.subtasks.userId, userId)))
        .orderBy((0, drizzle_orm_1.asc)(schema_1.subtasks.order));
    const nestedSubtasks = buildSubtaskTree(taskSubtasks);
    res.json({ subtasks: nestedSubtasks });
}));
router.post('/task/:taskId', (0, asyncHandler_1.asyncHandler)(async (req, res) => {
    const data = validation_1.subtaskCreateSchema.parse(req.body);
    const userId = req.user.userId;
    const task = await db_1.db
        .select()
        .from(schema_1.tasks)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.tasks.id, req.params.taskId), (0, drizzle_orm_1.eq)(schema_1.tasks.userId, userId)))
        .limit(1);
    if (task.length === 0) {
        throw new errorHandler_1.AppError('NOT_FOUND', 'Task not found', 404);
    }
    const now = Date.now();
    const parentSubtaskId = data.parentSubtaskId || null;
    const maxOrder = await db_1.db
        .select({ order: schema_1.subtasks.order })
        .from(schema_1.subtasks)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.subtasks.taskId, req.params.taskId), (0, drizzle_orm_1.eq)(schema_1.subtasks.userId, userId), parentSubtaskId ? (0, drizzle_orm_1.eq)(schema_1.subtasks.parentSubtaskId, parentSubtaskId) : (0, drizzle_orm_1.isNull)(schema_1.subtasks.parentSubtaskId)))
        .orderBy((0, drizzle_orm_1.desc)(schema_1.subtasks.order))
        .limit(1);
    const subtaskId = `sub_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`;
    const newSubtask = {
        id: subtaskId,
        userId,
        taskId: req.params.taskId,
        parentSubtaskId,
        title: data.title,
        description: data.description ?? '',
        priority: data.priority ?? 'none',
        completed: false,
        dueDate: data.dueDate ?? 0,
        dueTime: data.dueTime ?? '',
        endTime: data.endTime ?? '',
        allDay: data.allDay ?? false,
        repeat: data.repeat ?? 'none',
        repeatInterval: data.repeatInterval ?? 1,
        repeatDays: data.repeatDays ?? '',
        seriesId: data.seriesId ?? '',
        reminder: data.reminder ?? 'none',
        reminders: data.reminders ?? '',
        assigneeId: data.assigneeId ?? null,
        order: data.order ?? (maxOrder[0]?.order ?? -1) + 1,
        createdAt: now,
        updatedAt: now,
    };
    await db_1.db.insert(schema_1.subtasks).values(newSubtask);
    // Update task updatedAt
    await db_1.db
        .update(schema_1.tasks)
        .set({ updatedAt: now })
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.tasks.id, req.params.taskId), (0, drizzle_orm_1.eq)(schema_1.tasks.userId, userId)));
    res.status(201).json(newSubtask);
}));
router.patch('/:id', (0, asyncHandler_1.asyncHandler)(async (req, res) => {
    const data = validation_1.subtaskUpdateSchema.parse(req.body);
    const userId = req.user.userId;
    const existing = await db_1.db
        .select()
        .from(schema_1.subtasks)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.subtasks.id, req.params.id), (0, drizzle_orm_1.eq)(schema_1.subtasks.userId, userId)))
        .limit(1);
    if (existing.length === 0) {
        throw new errorHandler_1.AppError('NOT_FOUND', 'Subtask not found', 404);
    }
    const now = Date.now();
    const updated = await db_1.db
        .update(schema_1.subtasks)
        .set({ ...data, updatedAt: now })
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.subtasks.id, req.params.id), (0, drizzle_orm_1.eq)(schema_1.subtasks.userId, userId)))
        .returning();
    // Update task updatedAt
    await db_1.db
        .update(schema_1.tasks)
        .set({ updatedAt: now })
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.tasks.id, existing[0].taskId), (0, drizzle_orm_1.eq)(schema_1.tasks.userId, userId)));
    res.json(updated[0]);
}));
router.delete('/:id', (0, asyncHandler_1.asyncHandler)(async (req, res) => {
    const userId = req.user.userId;
    const existing = await db_1.db
        .select()
        .from(schema_1.subtasks)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.subtasks.id, req.params.id), (0, drizzle_orm_1.eq)(schema_1.subtasks.userId, userId)))
        .limit(1);
    if (existing.length === 0) {
        throw new errorHandler_1.AppError('NOT_FOUND', 'Subtask not found', 404);
    }
    const taskId = existing[0].taskId;
    await db_1.db
        .delete(schema_1.subtasks)
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.subtasks.id, req.params.id), (0, drizzle_orm_1.eq)(schema_1.subtasks.userId, userId)));
    // Update task updatedAt
    await db_1.db
        .update(schema_1.tasks)
        .set({ updatedAt: Date.now() })
        .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.tasks.id, taskId), (0, drizzle_orm_1.eq)(schema_1.tasks.userId, userId)));
    res.status(204).send();
}));
exports.default = router;
//# sourceMappingURL=subtasks.js.map