const Quiz = require('../models/Quiz');
const QuizAttempt = require('../models/QuizAttempt');
const QuizSubmission = require('../models/QuizSubmission');
const CareerProgress = require('../models/CareerProgress');
const geminiService = require('../services/geminiService');

// Get quiz questions for a specific category and difficulty
const getQuizQuestions = async (req, res) => {
    try {
        const { category, difficulty = 'medium', stage, limit = 10 } = req.query;

        const filter = { isActive: true };
        
        if (category) filter.category = category;
        if (difficulty) filter.difficulty = difficulty;
        if (stage) filter.stage = stage;

        const questions = await Quiz.find(filter)
            .select('-correctAnswer -__v')
            .sort({ date: -1 })
            .limit(parseInt(limit));

        res.status(200).json({
            success: true,
            data: {
                questions,
                totalQuestions: questions.length
            }
        });
    } catch (error) {
        console.error('Get quiz questions error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get quiz questions',
            error: error.message
        });
    }
};

// Submit quiz answers (handles both authenticated and public submissions)
const submitQuizAnswers = async (req, res) => {
    try {
        const { answers, userId: providedUserId } = req.body; // [{ quizId, userAnswer, timeSpent }]
        
        console.log('🔍 [QUIZ SUBMIT] Request received:', {
            hasUser: !!req.user,
            userId: req.user?.id,
            userEmail: req.user?.email,
            providedUserId,
            answersCount: answers?.length || 0,
            headers: {
                authorization: req.headers.authorization ? 'Bearer [HIDDEN]' : 'None',
                contentType: req.headers['content-type']
            }
        });
        
        // Handle both authenticated and public submissions
        let userId;
        if (req.user && req.user.id) {
            // Authenticated user
            userId = req.user.id;
            console.log('🔐 [QUIZ SUBMIT] Authenticated user:', userId);
        } else if (providedUserId) {
            // Public submission with provided user ID
            userId = providedUserId;
            console.log('👤 [QUIZ SUBMIT] Public user:', userId);
        } else {
            // Anonymous submission
            userId = `anonymous_${Date.now()}`;
            console.log('👻 [QUIZ SUBMIT] Anonymous user:', userId);
        }

        let correctAnswers = 0;
        let totalQuestions = answers.length;
        const attemptDetails = [];

        for (const answer of answers) {
            const quiz = await Quiz.findById(answer.quizId);
            if (!quiz) continue;

            const isCorrect = quiz.correctAnswer === answer.userAnswer;
            if (isCorrect) correctAnswers++;

            // Save attempt
            const attempt = new QuizAttempt({
                userId,
                quizId: answer.quizId,
                userAnswer: answer.userAnswer,
                isCorrect,
                timeSpent: answer.timeSpent || 0,
                category: quiz.category,
                difficulty: quiz.difficulty,
                stage: quiz.stage
            });

            await attempt.save();
            attemptDetails.push({
                quizId: answer.quizId,
                question: quiz.question,
                userAnswer: answer.userAnswer,
                correctAnswer: quiz.correctAnswer,
                isCorrect,
                explanation: quiz.explanation
            });
        }

        const score = Math.round((correctAnswers / totalQuestions) * 100);

        // Update career progress (only for non-anonymous users)
        let careerProgress = null;
        if (!userId.startsWith('anonymous_')) {
            console.log('📊 [QUIZ SUBMIT] Updating career progress for user:', userId);
            careerProgress = await CareerProgress.findOne({ userId });
            if (!careerProgress) {
                console.log('📊 [QUIZ SUBMIT] Creating new career progress for user:', userId);
                careerProgress = new CareerProgress({ 
                    userId: userId,
                    currentStage: 'class_6_10' // Default stage, can be updated later
                });
            }

            careerProgress.quizStats.totalAttempts += 1;
            careerProgress.quizStats.correctAnswers += correctAnswers;
            careerProgress.quizStats.averageScore = 
                ((careerProgress.quizStats.averageScore * (careerProgress.quizStats.totalAttempts - 1)) + score) / 
                careerProgress.quizStats.totalAttempts;

            // Update category scores
            const categoryStats = {};
            answers.forEach(answer => {
                if (!categoryStats[answer.category]) {
                    categoryStats[answer.category] = { correct: 0, total: 0 };
                }
                categoryStats[answer.category].total += 1;
                if (answer.isCorrect) {
                    categoryStats[answer.category].correct += 1;
                }
            });

            Object.keys(categoryStats).forEach(category => {
                const existingCategory = careerProgress.quizStats.categoryScores.find(
                    cat => cat.category === category
                );
                
                if (existingCategory) {
                    existingCategory.attempts += categoryStats[category].total;
                    existingCategory.score = 
                        ((existingCategory.score * (existingCategory.attempts - categoryStats[category].total)) + 
                         (categoryStats[category].correct / categoryStats[category].total * 100)) / 
                        existingCategory.attempts;
                } else {
                    careerProgress.quizStats.categoryScores.push({
                        category,
                        score: (categoryStats[category].correct / categoryStats[category].total) * 100,
                        attempts: categoryStats[category].total
                    });
                }
            });

            await careerProgress.save();
        }

        res.status(200).json({
            success: true,
            data: {
                score,
                correctAnswers,
                totalQuestions,
                attemptDetails,
                message: score >= 80 ? 'Excellent!' : score >= 60 ? 'Good job!' : 'Keep practicing!'
            }
        });
    } catch (error) {
        console.error('Submit quiz answers error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to submit quiz answers',
            error: error.message
        });
    }
};

// Get quiz leaderboard
const getQuizLeaderboard = async (req, res) => {
    try {
        const { category, stage, timeframe = 'month' } = req.query;

        let dateFilter = {};
        const now = new Date();
        
        switch (timeframe) {
            case 'week':
                dateFilter = { createdAt: { $gte: new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000) } };
                break;
            case 'month':
                dateFilter = { createdAt: { $gte: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000) } };
                break;
            case 'year':
                dateFilter = { createdAt: { $gte: new Date(now.getTime() - 365 * 24 * 60 * 60 * 1000) } };
                break;
        }

        const matchFilter = { ...dateFilter };
        if (category) matchFilter.category = category;
        if (stage) matchFilter.stage = stage;

        const leaderboard = await QuizAttempt.aggregate([
            { $match: matchFilter },
            {
                $group: {
                    _id: '$userId',
                    totalAttempts: { $sum: 1 },
                    correctAnswers: { $sum: { $cond: ['$isCorrect', 1, 0] } },
                    averageTime: { $avg: '$timeSpent' }
                }
            },
            {
                $addFields: {
                    accuracy: { $multiply: [{ $divide: ['$correctAnswers', '$totalAttempts'] }, 100] }
                }
            },
            {
                $lookup: {
                    from: 'users',
                    localField: '_id',
                    foreignField: '_id',
                    as: 'user'
                }
            },
            { $unwind: '$user' },
            {
                $project: {
                    userId: '$_id',
                    name: '$user.name',
                    totalAttempts: 1,
                    correctAnswers: 1,
                    accuracy: { $round: ['$accuracy', 2] },
                    averageTime: { $round: ['$averageTime', 2] }
                }
            },
            { $sort: { accuracy: -1, totalAttempts: -1 } },
            { $limit: 50 }
        ]);

        res.status(200).json({
            success: true,
            data: {
                leaderboard,
                timeframe,
                category,
                stage
            }
        });
    } catch (error) {
        console.error('Get quiz leaderboard error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get quiz leaderboard',
            error: error.message
        });
    }
};

// Get user's quiz statistics
const getUserQuizStats = async (req, res) => {
    try {
        const userId = req.user.id;

        const careerProgress = await CareerProgress.findOne({ userId });
        
        if (!careerProgress) {
            return res.status(404).json({
                success: false,
                message: 'No quiz statistics found'
            });
        }

        // Get recent attempts
        const recentAttempts = await QuizAttempt.find({ userId })
            .sort({ createdAt: -1 })
            .limit(10)
            .populate('quizId', 'question category difficulty');

        res.status(200).json({
            success: true,
            data: {
                stats: careerProgress.quizStats,
                recentAttempts
            }
        });
    } catch (error) {
        console.error('Get user quiz stats error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get quiz statistics',
            error: error.message
        });
    }
};

// Get quiz categories
const getQuizCategories = async (req, res) => {
    try {
        const categories = await Quiz.aggregate([
            { $match: { isActive: true } },
            { $group: { _id: '$category', count: { $sum: 1 } } },
            { $sort: { count: -1 } }
        ]);

        const difficulties = await Quiz.aggregate([
            { $match: { isActive: true } },
            { $group: { _id: '$difficulty', count: { $sum: 1 } } },
            { $sort: { count: -1 } }
        ]);

        res.status(200).json({
            success: true,
            data: {
                categories,
                difficulties
            }
        });
    } catch (error) {
        console.error('Get quiz categories error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get quiz categories',
            error: error.message
        });
    }
};

// Get all quiz questions (Admin only)
const getAllQuizQuestions = async (req, res) => {
    try {
        const { page = 1, limit = 50, category, difficulty, stage, isActive } = req.query;

        const filter = {};

        if (category) filter.category = category;
        if (difficulty) filter.difficulty = difficulty;
        if (stage) filter.stage = stage;
        if (isActive !== undefined) filter.isActive = isActive === 'true';

        const questions = await Quiz.find(filter)
            .select('-__v')
            .sort({ createdAt: -1 })
            .limit(limit * 1)
            .skip((page - 1) * limit);

        const total = await Quiz.countDocuments(filter);

        res.status(200).json({
            success: true,
            data: {
                questions,
                pagination: {
                    currentPage: parseInt(page),
                    totalPages: Math.ceil(total / limit),
                    totalQuestions: total,
                    hasNext: page < Math.ceil(total / limit),
                    hasPrev: page > 1
                }
            }
        });
    } catch (error) {
        console.error('Get all quiz questions error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get quiz questions',
            error: error.message
        });
    }
};

// Add new quiz question (Admin only)
const addQuizQuestion = async (req, res) => {
    try {
        const quizData = req.body;

        const quiz = new Quiz(quizData);
        await quiz.save();

        res.status(201).json({
            success: true,
            message: 'Quiz question added successfully',
            data: quiz
        });
    } catch (error) {
        console.error('Add quiz question error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to add quiz question',
            error: error.message
        });
    }
};

// Update quiz question (Admin only)
const updateQuizQuestion = async (req, res) => {
    try {
        const { quizId } = req.params;
        const updateData = req.body;

        const quiz = await Quiz.findByIdAndUpdate(
            quizId,
            updateData,
            { new: true, runValidators: true }
        );

        if (!quiz) {
            return res.status(404).json({
                success: false,
                message: 'Quiz question not found'
            });
        }

        res.status(200).json({
            success: true,
            message: 'Quiz question updated successfully',
            data: quiz
        });
    } catch (error) {
        console.error('Update quiz question error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to update quiz question',
            error: error.message
        });
    }
};

// Delete quiz question (Admin only)
const deleteQuizQuestion = async (req, res) => {
    try {
        const { quizId } = req.params;

        const quiz = await Quiz.findByIdAndDelete(quizId);

        if (!quiz) {
            return res.status(404).json({
                success: false,
                message: 'Quiz question not found'
            });
        }

        res.status(200).json({
            success: true,
            message: 'Quiz question deleted successfully'
        });
    } catch (error) {
        console.error('Delete quiz question error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to delete quiz question',
            error: error.message
        });
    }
};

// Generate quiz questions using Gemini AI
const generateQuizQuestions = async (req, res) => {
    try {
        const { stage, category, difficulty, count, topic } = req.body;

        // Validate required parameters
        if (!stage || !category || !difficulty || !count) {
            return res.status(400).json({
                success: false,
                message: 'Missing required parameters: stage, category, difficulty, count'
            });
        }

        // Generate questions using Gemini AI
        const result = await geminiService.generateQuizQuestions(
            stage, 
            category, 
            difficulty, 
            parseInt(count), 
            topic
        );

        if (result.success) {
            // Save generated questions to database
            const savedQuestions = [];
            for (const questionData of result.data.questions) {
                try {
                    const question = new Quiz(questionData);
                    const savedQuestion = await question.save();
                    savedQuestions.push(savedQuestion);
                } catch (saveError) {
                    console.error('Error saving question:', saveError);
                }
            }

            res.status(200).json({
                success: true,
                message: `Generated ${savedQuestions.length} quiz questions`,
                data: {
                    questions: savedQuestions,
                    generatedBy: result.data.generatedBy,
                    parameters: result.data.parameters,
                    warning: result.warning
                }
            });
        } else {
            res.status(500).json({
                success: false,
                message: 'Failed to generate quiz questions',
                error: result.error
            });
        }

    } catch (error) {
        console.error('Generate quiz questions error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to generate quiz questions',
            error: error.message
        });
    }
};

// Public quiz submission (no authentication required)
const submitQuizAnswersPublic = async (req, res) => {
    try {
        const { answers, userId = 'anonymous' } = req.body; // Allow anonymous submissions
        const user = userId === 'anonymous' ? 'anonymous' : userId;

        let correctAnswers = 0;
        let totalQuestions = answers.length;
        const attemptDetails = [];

        for (const answer of answers) {
            const quiz = await Quiz.findById(answer.quizId);
            if (!quiz) continue;

            const isCorrect = quiz.correctAnswer === answer.userAnswer;
            if (isCorrect) correctAnswers++;

            // Save attempt
            console.log('💾 [QUIZ SUBMIT] Saving attempt:', {
                userId: user,
                userIdType: typeof user,
                quizId: answer.quizId,
                userAnswer: answer.userAnswer,
                isCorrect,
                timeSpent: answer.timeSpent || 0,
                category: quiz.category,
                difficulty: quiz.difficulty,
                stage: quiz.stage
            });

            const attempt = new QuizAttempt({
                userId: user,
                quizId: answer.quizId,
                userAnswer: answer.userAnswer,
                isCorrect,
                timeSpent: answer.timeSpent || 0,
                category: quiz.category,
                difficulty: quiz.difficulty,
                stage: quiz.stage
            });

            await attempt.save();
            console.log('✅ [QUIZ SUBMIT] Attempt saved successfully');
            attemptDetails.push({
                quizId: answer.quizId,
                question: quiz.question,
                userAnswer: answer.userAnswer,
                correctAnswer: quiz.correctAnswer,
                isCorrect,
                explanation: quiz.explanation
            });
        }

        const score = Math.round((correctAnswers / totalQuestions) * 100);

        // Update career progress (if user is not anonymous)
        if (user !== 'anonymous') {
            let careerProgress = await CareerProgress.findOne({ userId: user });
            if (!careerProgress) {
                careerProgress = new CareerProgress({ userId: user });
            }

            careerProgress.quizStats.totalAttempts += 1;
            careerProgress.quizStats.totalCorrect += correctAnswers;
            careerProgress.quizStats.averageScore = Math.round(
                (careerProgress.quizStats.totalCorrect / 
                (careerProgress.quizStats.totalAttempts * totalQuestions)) * 100
            );

            await careerProgress.save();
        }

        res.status(200).json({
            success: true,
            message: 'Quiz submitted successfully',
            data: {
                score,
                correctAnswers,
                totalQuestions,
                percentage: score,
                attemptDetails,
                userId: user
            }
        });

    } catch (error) {
        console.error('Submit quiz answers error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to submit quiz answers',
            error: error.message
        });
    }
};

// Submit quiz answers (single record storage, prevents duplicate submissions)
const submitQuizAnswersSingle = async (req, res) => {
    try {
        const { answers, userId: providedUserId } = req.body;
        
        console.log('🔍 [QUIZ SUBMIT SINGLE] Request received:', {
            hasUser: !!req.user,
            userId: req.user?.id,
            userEmail: req.user?.email,
            providedUserId,
            answersCount: answers?.length || 0
        });
        
        // Handle both authenticated and public submissions
        let userId;
        if (req.user && req.user.id) {
            userId = req.user.id;
            console.log('🔐 [QUIZ SUBMIT SINGLE] Authenticated user:', userId);
        } else if (providedUserId) {
            userId = providedUserId;
            console.log('👤 [QUIZ SUBMIT SINGLE] Public user:', userId);
        } else {
            userId = `anonymous_${Date.now()}`;
            console.log('👻 [QUIZ SUBMIT SINGLE] Anonymous user:', userId);
        }

        // Get quiz details from first answer
        const firstQuiz = await Quiz.findById(answers[0].quizId);
        if (!firstQuiz) {
            return res.status(400).json({
                success: false,
                message: 'Invalid quiz questions'
            });
        }

        const category = firstQuiz.category;
        const difficulty = firstQuiz.difficulty;
        const stage = firstQuiz.stage;

        // Check if user has already submitted this quiz
        const existingSubmission = await QuizSubmission.findOne({
            userId: userId,
            stage: stage,
            category: category,
            difficulty: difficulty
        });

        if (existingSubmission) {
            console.log('⚠️ [QUIZ SUBMIT SINGLE] User already submitted this quiz');
            
            return res.status(409).json({
                success: false,
                message: 'You have already submitted this quiz',
                data: {
                    alreadySubmitted: true,
                    previousScore: existingSubmission.score,
                    previousSubmissionDate: existingSubmission.submittedAt,
                    category: category,
                    difficulty: difficulty,
                    stage: stage
                }
            });
        }

        // Process all answers (minimal approach - only calculate score)
        let correctAnswers = 0;
        let totalTimeSpent = 0;
        const questionResults = []; // Store questions for result display

        for (const answer of answers) {
            const quiz = await Quiz.findById(answer.quizId);
            if (!quiz) continue;

            const isCorrect = quiz.correctAnswer === answer.userAnswer;
            if (isCorrect) correctAnswers++;

            totalTimeSpent += answer.timeSpent || 0;

            // Store question data for result display
            questionResults.push({
                question: quiz.question,
                options: quiz.options,
                userAnswer: answer.userAnswer,
                correctAnswer: quiz.correctAnswer,
                isCorrect: isCorrect,
                explanation: quiz.explanation,
                timeSpent: answer.timeSpent || 0
            });
        }

        const totalQuestions = answers.length;
        const score = Math.round((correctAnswers / totalQuestions) * 100);

        // Create minimal quiz submission record
        const quizSubmission = new QuizSubmission({
            userId: userId,
            stage: stage,
            category: category,
            difficulty: difficulty,
            totalQuestions: totalQuestions,
            correctAnswers: correctAnswers,
            score: score,
            totalTimeSpent: totalTimeSpent
        });

        await quizSubmission.save();
        console.log('✅ [QUIZ SUBMIT SINGLE] Single quiz submission saved successfully');

        // Update career progress (only for non-anonymous users)
        if (!userId.startsWith('anonymous_')) {
            let careerProgress = await CareerProgress.findOne({ userId });
            if (!careerProgress) {
                careerProgress = new CareerProgress({ 
                    userId: userId,
                    currentStage: stage
                });
            }

            careerProgress.quizStats.totalAttempts += 1;
            careerProgress.quizStats.correctAnswers += correctAnswers;
            careerProgress.quizStats.averageScore = 
                ((careerProgress.quizStats.averageScore * (careerProgress.quizStats.totalAttempts - 1)) + score) / 
                careerProgress.quizStats.totalAttempts;

            await careerProgress.save();
        }

        res.status(200).json({
            success: true,
            message: 'Quiz submitted successfully',
            data: {
                score,
                correctAnswers,
                totalQuestions,
                percentage: score,
                totalTimeSpent,
                category: category,
                difficulty: difficulty,
                stage: stage,
                userId,
                submittedAt: quizSubmission.submittedAt,
                questionResults: questionResults // Include questions for result display
            }
        });

    } catch (error) {
        console.error('Submit quiz answers error:', error);
        
        if (error.code === 11000) {
            return res.status(409).json({
                success: false,
                message: 'You have already submitted this quiz',
                error: 'Duplicate submission detected'
            });
        }
        
        res.status(500).json({
            success: false,
            message: 'Failed to submit quiz answers',
            error: error.message
        });
    }
};

module.exports = {
    getQuizQuestions,
    submitQuizAnswers,
    submitQuizAnswersPublic,
    submitQuizAnswersSingle,
    getQuizLeaderboard,
    getUserQuizStats,
    getQuizCategories,
    getAllQuizQuestions,
    addQuizQuestion,
    updateQuizQuestion,
    deleteQuizQuestion,
    generateQuizQuestions
};
