// Task Team — Spaced Repetition Engine — 2026-03-30
// SM-2 algorithm for study goals

function calculateNextReview(quality, repetitions, easeFactor, interval) {
    // quality: 0-5 (0=complete fail, 5=perfect)
    if (quality < 3) {
        return { repetitions: 0, interval: 1, easeFactor };
    }
    let newInterval;
    if (repetitions === 0) newInterval = 1;
    else if (repetitions === 1) newInterval = 6;
    else newInterval = Math.round(interval * easeFactor);
    
    const newEase = Math.max(1.3, easeFactor + (0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02)));
    return { repetitions: repetitions + 1, interval: newInterval, easeFactor: newEase };
}

async function spacedRepRoutes(app) {
    // Create review_items table
    await app.db.query(`
        CREATE TABLE IF NOT EXISTS review_items (
            id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
            user_id UUID REFERENCES users(id) ON DELETE CASCADE,
            goal_id UUID REFERENCES goals(id) ON DELETE CASCADE,
            title VARCHAR(500) NOT NULL,
            content TEXT DEFAULT '',
            repetitions INTEGER DEFAULT 0,
            ease_factor NUMERIC(4,2) DEFAULT 2.5,
            interval_days INTEGER DEFAULT 1,
            next_review TIMESTAMPTZ DEFAULT NOW(),
            last_reviewed TIMESTAMPTZ,
            created_at TIMESTAMPTZ DEFAULT NOW()
        )
    `).catch(() => {});

    // Get items due for review
    app.get("/review/due", async (req) => {
        const { user_id, goal_id, limit } = req.query;
        let query = "SELECT * FROM review_items WHERE next_review <= NOW()";
        const params = [];
        if (user_id) { params.push(user_id); query += ` AND user_id = $${params.length}`; }
        if (goal_id) { params.push(goal_id); query += ` AND goal_id = $${params.length}`; }
        query += " ORDER BY next_review ASC";
        if (limit) { params.push(limit); query += ` LIMIT $${params.length}`; }
        const { rows } = await app.db.query(query, params);
        return { data: rows, count: rows.length };
    });

    // Create review item
    app.post("/review/items", async (req) => {
        const { user_id, goal_id, title, content } = req.body;
        const { rows } = await app.db.query(
            "INSERT INTO review_items (user_id, goal_id, title, content) VALUES ($1,$2,$3,$4) RETURNING *",
            [user_id, goal_id, title, content || ""]
        );
        return { data: rows[0] };
    });

    // Submit review (rate quality 0-5)
    app.post("/review/items/:id/review", async (req) => {
        const { quality } = req.body; // 0-5
        if (quality < 0 || quality > 5) throw { statusCode: 400, message: "Quality must be 0-5" };
        
        const { rows } = await app.db.query("SELECT * FROM review_items WHERE id = $1", [req.params.id]);
        if (!rows.length) throw { statusCode: 404, message: "Item not found" };
        const item = rows[0];
        
        const result = calculateNextReview(quality, item.repetitions, parseFloat(item.ease_factor), item.interval_days);
        const nextReview = new Date(Date.now() + result.interval * 86400000);
        
        const { rows: updated } = await app.db.query(
            `UPDATE review_items SET repetitions=$1, ease_factor=$2, interval_days=$3, 
             next_review=$4, last_reviewed=NOW() WHERE id=$5 RETURNING *`,
            [result.repetitions, result.easeFactor, result.interval, nextReview, req.params.id]
        );
        return { data: updated[0], next_review_in_days: result.interval };
    });

    // Get single review item
    app.get("/review/items/:id", async (req) => {
        const { rows } = await app.db.query("SELECT * FROM review_items WHERE id = $1", [req.params.id]);
        if (!rows.length) throw { statusCode: 404, message: "Item not found" };
        return { data: rows[0] };
    });

    // Delete review item
    app.delete("/review/items/:id", async (req) => {
        const { rowCount } = await app.db.query("DELETE FROM review_items WHERE id = $1", [req.params.id]);
        if (!rowCount) throw { statusCode: 404, message: "Item not found" };
        return { status: "deleted" };
    });

    // Stats
    app.get("/review/stats", async (req) => {
        const { user_id } = req.query;
        const { rows } = await app.db.query(`
            SELECT count(*) as total,
                   count(*) FILTER (WHERE next_review <= NOW()) as due,
                   count(*) FILTER (WHERE last_reviewed > NOW() - INTERVAL '24 hours') as reviewed_today,
                   avg(ease_factor)::numeric(4,2) as avg_ease
            FROM review_items WHERE user_id = $1`, [user_id || "00000000-0000-0000-0000-000000000000"]);
        return { data: rows[0] };
    });
}

module.exports = spacedRepRoutes;
