// Assessment Controller - Skill Assessment for Interviews
const db = require('../db');
const crypto = require('crypto');

// ============================================
// CREATE ASSESSMENT
// ============================================
const createAssessment = async (req, res) => {
    try {
        const { title, description, time_limit_minutes = 60, passing_score = 70, alert_ids, difficulty_filter, random_count = 3 } = req.body;
        const userId = Number(req.user.id);
        
        // Get user's organization
        const orgCheck = await db.query(
            'SELECT organization_id FROM organization_members WHERE user_id = ? AND role IN ("owner", "admin")',
            [userId]
        );
        
        if (orgCheck.rows.length === 0) {
            return res.status(403).json({ message: 'Only organization admins can create assessments' });
        }
        
        const orgId = orgCheck.rows[0].organization_id;
        
        const result = await db.query(
            `INSERT INTO assessments (organization_id, title, description, time_limit_minutes, passing_score, alert_ids, difficulty_filter, alert_type_filter, random_count, created_by)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [orgId, title, description, time_limit_minutes, passing_score, JSON.stringify(alert_ids || []), difficulty_filter, difficulty_filter, random_count, userId]
        );
        
        res.status(201).json({
            message: 'Assessment created successfully',
            assessment: { id: result.insertId, title }
        });
    } catch (error) {
        console.error('Error creating assessment:', error);
        res.status(500).json({ message: 'Failed to create assessment' });
    }
};

// ============================================
// GET ASSESSMENTS
// ============================================
const getAssessments = async (req, res) => {
    try {
        const userId = Number(req.user.id);
        
        const orgCheck = await db.query(
            'SELECT organization_id FROM organization_members WHERE user_id = ?',
            [userId]
        );
        
        if (orgCheck.rows.length === 0) {
            return res.status(403).json({ message: 'Not part of an organization' });
        }
        
        const orgId = orgCheck.rows[0].organization_id;
        
        const assessments = await db.query(
            `SELECT a.*, u.name as created_by_name,
                    (SELECT COUNT(*) FROM assessment_invites WHERE assessment_id = a.id) as invite_count,
                    (SELECT COUNT(*) FROM assessment_invites WHERE assessment_id = a.id AND status = 'completed') as completed_count
             FROM assessments a
             JOIN users u ON a.created_by = u.id
             WHERE a.organization_id = ?
             ORDER BY a.created_at DESC`,
            [orgId]
        );
        
        res.json({ assessments: assessments.rows });
    } catch (error) {
        console.error('Error fetching assessments:', error);
        res.status(500).json({ message: 'Failed to fetch assessments' });
    }
};

// ============================================
// INVITE CANDIDATE
// ============================================
const inviteCandidate = async (req, res) => {
    try {
        const { assessmentId } = req.params;
        const { email, name, userId: targetUserId } = req.body;
        const adminId = Number(req.user.id);
        
        // Verify assessment ownership
        const assessment = await db.query(
            `SELECT a.* FROM assessments a
             JOIN organization_members om ON a.organization_id = om.organization_id
             WHERE a.id = ? AND om.user_id = ? AND om.role IN ('owner', 'admin')`,
            [assessmentId, adminId]
        );
        
        if (assessment.rows.length === 0) {
            return res.status(403).json({ message: 'Assessment not found or access denied' });
        }

        let candidateEmail = email;
        let candidateName = name;
        let internalUserId = null;

        // If assigning to existing user
        if (targetUserId) {
            const userRes = await db.query('SELECT email, name FROM users WHERE id = ?', [targetUserId]);
            if (userRes.rows.length === 0) {
                return res.status(404).json({ message: 'User not found' });
            }
            candidateEmail = userRes.rows[0].email;
            candidateName = userRes.rows[0].name;
            internalUserId = targetUserId;
        }
        
        const token = crypto.randomBytes(32).toString('hex');
        const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 days
        
        const result = await db.query(
            `INSERT INTO assessment_invites (assessment_id, candidate_email, candidate_name, user_id, token, expires_at, invited_by)
             VALUES (?, ?, ?, ?, ?, ?, ?)`,
            [assessmentId, candidateEmail, candidateName, internalUserId, token, expiresAt, adminId]
        );
        
        const assessmentLink = `${process.env.FRONTEND_URL || 'http://localhost:5173'}/assessment/${token}`;
        
        // TODO: Send email/notification
        
        res.status(201).json({
            message: internalUserId ? 'Assessment assigned to member successfully' : 'Candidate invited successfully',
            invite: {
                id: result.insertId,
                email: candidateEmail,
                name: candidateName,
                userId: internalUserId,
                link: assessmentLink,
                expiresAt
            }
        });
    } catch (error) {
        console.error('Error inviting candidate:', error);
        res.status(500).json({ message: 'Failed to invite candidate' });
    }
};

// ============================================
// GET ASSESSMENT FOR CANDIDATE (Public)
// ============================================
const getAssessmentByToken = async (req, res) => {
    try {
        const { token } = req.params;
        
        const invite = await db.query(
            `SELECT ai.*, a.title, a.description, a.time_limit_minutes, a.passing_score, a.alert_ids, a.difficulty_filter, a.alert_type_filter, a.random_count,
                    o.name as organization_name
             FROM assessment_invites ai
             JOIN assessments a ON ai.assessment_id = a.id
             JOIN organizations o ON a.organization_id = o.id
             WHERE ai.token = ?`,
            [token]
        );
        
        if (invite.rows.length === 0) {
            return res.status(404).json({ message: 'Assessment not found' });
        }
        
        const inv = invite.rows[0];
        
        if (inv.status === 'completed') {
            return res.status(400).json({ message: 'Assessment already completed' });
        }
        
        if (new Date(inv.expires_at) < new Date()) {
            await db.query('UPDATE assessment_invites SET status = "expired" WHERE id = ?', [inv.id]);
            return res.status(400).json({ message: 'Assessment has expired' });
        }
        
        // Get alerts for this assessment
        let alerts;
        if (inv.alert_ids && JSON.parse(inv.alert_ids).length > 0) {
            const alertIds = JSON.parse(inv.alert_ids);
            alerts = await db.query(
                `SELECT id, title, severity, details, alert_type, raw_log FROM alerts WHERE id IN (?)`,
                [alertIds]
            );
        } else {
            // Random selection based on difficulty
            let query = `SELECT id, title, severity, details, alert_type, raw_log FROM alerts WHERE playbook_solution IS NOT NULL`;
            const params = [];
            
            if (inv.difficulty_filter) {
                query += ` AND difficulty = ?`;
                params.push(inv.difficulty_filter);
            }

            if (inv.alert_type_filter) {
                query += ` AND alert_type = ?`;
                params.push(inv.alert_type_filter);
            }
            
            query += ` ORDER BY RAND() LIMIT ?`;
            params.push(inv.random_count);
            
            alerts = await db.query(query, params);
        }
        
        res.json({
            assessment: {
                title: inv.title,
                description: inv.description,
                time_limit_minutes: inv.time_limit_minutes,
                organization_name: inv.organization_name,
                candidate_name: inv.candidate_name,
                status: inv.status,
                started_at: inv.started_at
            },
            alerts: alerts.rows
        });
    } catch (error) {
        console.error('Error fetching assessment:', error);
        res.status(500).json({ message: 'Failed to fetch assessment' });
    }
};

// ============================================
// START ASSESSMENT
// ============================================
const startAssessment = async (req, res) => {
    try {
        const { token } = req.params;
        
        const result = await db.query(
            `UPDATE assessment_invites SET status = 'started', started_at = NOW() WHERE token = ? AND status = 'pending'`,
            [token]
        );
        
        if (result.affectedRows === 0) {
            return res.status(400).json({ message: 'Assessment already started or invalid' });
        }
        
        res.json({ message: 'Assessment started' });
    } catch (error) {
        console.error('Error starting assessment:', error);
        res.status(500).json({ message: 'Failed to start assessment' });
    }
};

// ============================================
// SUBMIT ASSESSMENT RESPONSE
// ============================================
const submitResponse = async (req, res) => {
    try {
        const { token } = req.params;
        const { alert_id, answer, time_spent_seconds } = req.body;
        
        const invite = await db.query(
            `SELECT ai.id, ai.assessment_id, a.organization_id FROM assessment_invites ai
             JOIN assessments a ON ai.assessment_id = a.id
             WHERE ai.token = ? AND ai.status = 'started'`,
            [token]
        );
        
        if (invite.rows.length === 0) {
            return res.status(400).json({ message: 'Assessment not active' });
        }
        
        const inviteId = invite.rows[0].id;
        
        // Get correct answer from alert playbook
        const alert = await db.query('SELECT playbook_solution FROM alerts WHERE id = ?', [alert_id]);
        
        let isCorrect = false;
        let score = 0;
        
        if (alert.rows.length > 0 && alert.rows[0].playbook_solution) {
            const playbook = typeof alert.rows[0].playbook_solution === 'string' 
                ? JSON.parse(alert.rows[0].playbook_solution) 
                : alert.rows[0].playbook_solution;
            
            // Simple scoring - check verdict match
            if (answer.verdict && playbook.verdict) {
                isCorrect = answer.verdict.toLowerCase() === playbook.verdict.toLowerCase();
                score = isCorrect ? 100 : 0;
            }
        }
        
        await db.query(
            `INSERT INTO assessment_responses (invite_id, alert_id, submitted_answer, is_correct, score, time_spent_seconds)
             VALUES (?, ?, ?, ?, ?, ?)
             ON DUPLICATE KEY UPDATE submitted_answer = VALUES(submitted_answer), is_correct = VALUES(is_correct), score = VALUES(score)`,
            [inviteId, alert_id, JSON.stringify(answer), isCorrect, score, time_spent_seconds]
        );
        
        res.json({ message: 'Response submitted', is_correct: isCorrect, score });
    } catch (error) {
        console.error('Error submitting response:', error);
        res.status(500).json({ message: 'Failed to submit response' });
    }
};

// ============================================
// COMPLETE ASSESSMENT
// ============================================
const completeAssessment = async (req, res) => {
    try {
        const { token } = req.params;
        
        const invite = await db.query(
            `SELECT ai.id, ai.started_at FROM assessment_invites ai WHERE ai.token = ? AND ai.status = 'started'`,
            [token]
        );
        
        if (invite.rows.length === 0) {
            return res.status(400).json({ message: 'Assessment not active' });
        }
        
        const inviteId = invite.rows[0].id;
        const startedAt = new Date(invite.rows[0].started_at);
        const timeSpent = Math.floor((new Date() - startedAt) / 1000);
        
        // Calculate final score
        const responses = await db.query(
            'SELECT AVG(score) as avg_score FROM assessment_responses WHERE invite_id = ?',
            [inviteId]
        );
        
        const finalScore = Math.round(responses.rows[0]?.avg_score || 0);
        
        await db.query(
            `UPDATE assessment_invites SET status = 'completed', completed_at = NOW(), score = ?, time_spent_seconds = ? WHERE id = ?`,
            [finalScore, timeSpent, inviteId]
        );
        
        res.json({ 
            message: 'Assessment completed',
            score: finalScore,
            time_spent_seconds: timeSpent
        });
    } catch (error) {
        console.error('Error completing assessment:', error);
        res.status(500).json({ message: 'Failed to complete assessment' });
    }
};

// ============================================
// GET CANDIDATE RESULTS (For org admin)
// ============================================
const getCandidateResults = async (req, res) => {
    try {
        const { inviteId } = req.params;
        const userId = Number(req.user.id);
        
        const invite = await db.query(
            `SELECT ai.*, a.title as assessment_title, a.passing_score
             FROM assessment_invites ai
             JOIN assessments a ON ai.assessment_id = a.id
             JOIN organization_members om ON a.organization_id = om.organization_id
             WHERE ai.id = ? AND om.user_id = ?`,
            [inviteId, userId]
        );
        
        if (invite.rows.length === 0) {
            return res.status(404).json({ message: 'Results not found' });
        }
        
        const responses = await db.query(
            `SELECT ar.*, al.title as alert_title, al.severity, al.alert_type
             FROM assessment_responses ar
             JOIN alerts al ON ar.alert_id = al.id
             WHERE ar.invite_id = ?`,
            [inviteId]
        );
        
        const inv = invite.rows[0];
        
        res.json({
            candidate: {
                name: inv.candidate_name,
                email: inv.candidate_email,
                status: inv.status,
                score: inv.score,
                passing_score: inv.passing_score,
                passed: inv.score >= inv.passing_score,
                time_spent_seconds: inv.time_spent_seconds,
                started_at: inv.started_at,
                completed_at: inv.completed_at
            },
            responses: responses.rows
        });
    } catch (error) {
        console.error('Error fetching results:', error);
        res.status(500).json({ message: 'Failed to fetch results' });
    }
};

// ============================================
// DELETE ASSESSMENT
// ============================================
const deleteAssessment = async (req, res) => {
    try {
        const { assessmentId } = req.params;
        const userId = Number(req.user.id);
        
        // Verify ownership/admin role
        const assessment = await db.query(
            `SELECT a.id FROM assessments a
             JOIN organization_members om ON a.organization_id = om.organization_id
             WHERE a.id = ? AND om.user_id = ? AND om.role IN ('owner', 'admin')`,
            [assessmentId, userId]
        );
        
        if (assessment.rows.length === 0) {
            return res.status(403).json({ message: 'Assessment not found or access denied' });
        }
        
        // Delete invites and responses (cascading normally handles this but safe to be explicit if no FK cascade)
        // Assuming FK constraints are set up, we just delete the assessment.
        // If not, we might need to delete relate records. 
        // For safety, let's assume we can just delete the assessment and the DB handles cascades or we leave history?
        // Usually invites should be deleted.
        
        await db.query('DELETE FROM assessment_invites WHERE assessment_id = ?', [assessmentId]);
        await db.query('DELETE FROM assessments WHERE id = ?', [assessmentId]);
        
        res.json({ message: 'Assessment deleted successfully' });
    } catch (error) {
        console.error('Error deleting assessment:', error);
        res.status(500).json({ message: 'Failed to delete assessment' });
    }
};

// ============================================
// GET ASSESSMENT INVITES (For org admin details)
// ============================================
const getAssessmentInvites = async (req, res) => {
    try {
        const { assessmentId } = req.params;
        const userId = Number(req.user.id);
        
        // Verify ownership/admin role
        const assessment = await db.query(
            `SELECT a.id FROM assessments a
             JOIN organization_members om ON a.organization_id = om.organization_id
             WHERE a.id = ? AND om.user_id = ? AND om.role IN ('owner', 'admin')`,
            [assessmentId, userId]
        );
        
        if (assessment.rows.length === 0) {
            return res.status(403).json({ message: 'Assessment not found or access denied' });
        }
        
        const invites = await db.query(
            `SELECT ai.* 
             FROM assessment_invites ai
             WHERE ai.assessment_id = ?
             ORDER BY ai.created_at DESC`,
            [assessmentId]
        );
        
        res.json({ invites: invites.rows });
    } catch (error) {
        console.error('Error fetching assessment invites:', error);
        res.status(500).json({ message: 'Failed to fetch invites' });
    }
};

// ============================================
// GET MY INVITES (For Members)
// ============================================
const getMyInvites = async (req, res) => {
    try {
        const userId = Number(req.user.id);
        // Fetch invites assigned to this user that are not completed and not expired
        const result = await db.query(
            `SELECT ai.id, ai.token, ai.status, ai.expires_at, 
                    a.title, a.description, a.time_limit_minutes, a.random_count
             FROM assessment_invites ai
             JOIN assessments a ON ai.assessment_id = a.id
             WHERE ai.user_id = ? AND ai.status != 'completed' AND ai.expires_at > NOW()
             ORDER BY ai.created_at DESC`,
            [userId]
        );
        
        res.json({ invites: result.rows });
    } catch (error) {
        console.error('Error fetching my invites:', error);
        res.status(500).json({ message: 'Failed to fetch invites' });
    }
};

module.exports = {
    createAssessment,
    getAssessments,
    inviteCandidate,
    getAssessmentByToken,
    startAssessment,
    submitResponse,
    completeAssessment,
    getCandidateResults,
    deleteAssessment,
    getAssessmentInvites,
    getMyInvites
};
