// ============================================================
// LEARNING HUB ROUTES — User-facing content & quizzes
// ============================================================

var express = require('express');
var router = express.Router();
var db = require('../db/database');
var { authMiddleware } = require('../middleware/auth');
var { searchSimilar, isEmbeddingsAvailable } = require('../utils/embeddings');

router.use(authMiddleware);

// ============================================================
// GET CATEGORIES
// ============================================================
router.get('/categories', async function(req, res) {
  try {
    var categories = await db.all(
      'SELECT id, name, slug, description FROM learning_categories ORDER BY sort_order ASC, name ASC',
      []
    );
    res.json({ success: true, categories: categories });
  } catch (err) { console.error('[LearningHub]', err.message); res.status(500).json({ error: 'Internal server error' }); }
});

// ============================================================
// GET LATEST CONTENT (feed)
// ============================================================
router.get('/feed', async function(req, res) {
  try {
    var limit = Math.min(parseInt(req.query.limit) || 20, 50);
    var offset = parseInt(req.query.offset) || 0;

    var content = await db.all(
      `SELECT c.id, c.title, c.slug, c.subject, c.content_type, c.created_at, c.updated_at,
              cat.name as category_name, cat.slug as category_slug,
              u.name as author_name,
              (SELECT COUNT(*) FROM learning_questions q WHERE q.content_id = c.id) as question_count
       FROM learning_content c
       LEFT JOIN learning_categories cat ON c.category_id = cat.id
       LEFT JOIN users u ON c.author_id = u.id
       WHERE c.published = true
       ORDER BY c.created_at DESC
       LIMIT ? OFFSET ?`,
      [limit, offset]
    );

    var total = await db.get('SELECT COUNT(*) as count FROM learning_content WHERE published = true', []);

    res.json({ success: true, content: content, total: total ? parseInt(total.count) : 0 });
  } catch (err) { console.error('[LearningHub]', err.message); res.status(500).json({ error: 'Internal server error' }); }
});

// ============================================================
// GET CONTENT BY CATEGORY
// ============================================================
router.get('/category/:slug', async function(req, res) {
  try {
    var cat = await db.get('SELECT * FROM learning_categories WHERE slug = ?', [req.params.slug]);
    if (!cat) return res.status(404).json({ error: 'Category not found' });

    var content = await db.all(
      `SELECT c.id, c.title, c.slug, c.subject, c.content_type, c.created_at, c.updated_at,
              u.name as author_name,
              (SELECT COUNT(*) FROM learning_questions q WHERE q.content_id = c.id) as question_count
       FROM learning_content c
       LEFT JOIN users u ON c.author_id = u.id
       WHERE c.category_id = ? AND c.published = true
       ORDER BY c.created_at DESC`,
      [cat.id]
    );

    res.json({ success: true, category: cat, content: content });
  } catch (err) { console.error('[LearningHub]', err.message); res.status(500).json({ error: 'Internal server error' }); }
});

// ============================================================
// GET SINGLE CONTENT (with questions)
// ============================================================
router.get('/content/:slug', async function(req, res) {
  try {
    var item = await db.get(
      `SELECT c.*, cat.name as category_name, cat.slug as category_slug, u.name as author_name
       FROM learning_content c
       LEFT JOIN learning_categories cat ON c.category_id = cat.id
       LEFT JOIN users u ON c.author_id = u.id
       WHERE c.slug = ? AND c.published = true`,
      [req.params.slug]
    );
    if (!item) return res.status(404).json({ error: 'Content not found' });

    // Get questions + options
    var questions = await db.all(
      'SELECT * FROM learning_questions WHERE content_id = ? ORDER BY sort_order ASC',
      [item.id]
    );

    for (var i = 0; i < questions.length; i++) {
      var options = await db.all(
        'SELECT id, option_text, sort_order FROM learning_options WHERE question_id = ? ORDER BY sort_order ASC',
        [questions[i].id]
      );
      questions[i].options = options;
    }

    // Get user's past attempts
    var progress = await db.all(
      'SELECT score, total, completed_at FROM learning_progress WHERE user_id = ? AND content_id = ? ORDER BY completed_at DESC LIMIT 5',
      [req.user.id, item.id]
    );

    item.questions = questions;
    item.progress = progress;

    res.json({ success: true, content: item });
  } catch (err) { console.error('[LearningHub]', err.message); res.status(500).json({ error: 'Internal server error' }); }
});

// ============================================================
// RENDER PRESENTATION SLIDES (user-accessible)
// ============================================================
router.get('/content/:slug/slides', async function(req, res) {
  try {
    var item = await db.get(
      'SELECT body, content_type FROM learning_content WHERE slug = ? AND published = true',
      [req.params.slug]
    );
    if (!item) return res.status(404).json({ error: 'Content not found' });
    if (item.content_type !== 'presentation') return res.status(400).json({ error: 'Not a presentation' });

    var { Marp } = require('@marp-team/marp-core');
    var marp = new Marp({ html: false });
    var { html, css } = marp.render(item.body || '');

    var slides = [];
    var sectionReg = /<section[^>]*>[\s\S]*?<\/section>/g;
    var match;
    while ((match = sectionReg.exec(html)) !== null) slides.push(match[0]);
    if (slides.length === 0) slides.push(html);

    res.json({ success: true, css: css, slides: slides });
  } catch (err) { res.status(500).json({ error: 'Request failed' }); }
});

// ============================================================
// SUBMIT QUIZ ANSWERS
// ============================================================
router.post('/submit-quiz', async function(req, res) {
  try {
    var { contentId, answers } = req.body;
    // answers = [ { questionId: 1, optionId: 5 }, ... ]

    if (!contentId || !answers || !Array.isArray(answers)) {
      return res.status(400).json({ error: 'contentId and answers array required' });
    }

    // Get all questions for this content (include question_type)
    var questions = await db.all(
      'SELECT id, question_text, question_type, explanation as general_explanation FROM learning_questions WHERE content_id = ? ORDER BY sort_order ASC',
      [contentId]
    );

    var results = [];
    var score = 0;

    for (var i = 0; i < questions.length; i++) {
      var q = questions[i];
      var userAnswer = answers.find(function(a) { return a.questionId === q.id; });

      // Get all options with correct flag
      var options = await db.all(
        'SELECT id, option_text, is_correct, explanation FROM learning_options WHERE question_id = ? ORDER BY sort_order ASC',
        [q.id]
      );

      var isCorrect, resultEntry;

      if (q.question_type === 'multi') {
        var selectedIds = (userAnswer && Array.isArray(userAnswer.optionIds)) ? userAnswer.optionIds.map(Number) : [];
        var correctIds = options.filter(function(o) { return o.is_correct; }).map(function(o) { return o.id; });
        var allCorrectChosen = correctIds.length > 0 && correctIds.every(function(id) { return selectedIds.indexOf(id) !== -1; });
        var noWrongChosen = selectedIds.every(function(id) { return correctIds.indexOf(id) !== -1; });
        isCorrect = allCorrectChosen && noWrongChosen && selectedIds.length > 0;
        if (isCorrect) score++;
        resultEntry = {
          questionId: q.id,
          questionType: 'multi',
          questionText: q.question_text,
          selectedOptionIds: selectedIds,
          correctOptionIds: correctIds,
          isCorrect: isCorrect,
          generalExplanation: q.general_explanation || ''
        };
      } else {
        var selectedOptionId = userAnswer ? userAnswer.optionId : null;
        var correctOption = options.find(function(o) { return o.is_correct; });
        var selectedOption = selectedOptionId ? options.find(function(o) { return o.id === selectedOptionId; }) : null;
        isCorrect = selectedOption ? selectedOption.is_correct : false;
        if (isCorrect) score++;
        resultEntry = {
          questionId: q.id,
          questionType: q.question_type,
          questionText: q.question_text,
          selectedOptionId: selectedOptionId,
          isCorrect: isCorrect,
          correctOptionId: correctOption ? correctOption.id : null,
          correctOptionText: correctOption ? correctOption.option_text : '',
          selectedExplanation: selectedOption && !isCorrect ? selectedOption.explanation : '',
          generalExplanation: q.general_explanation || ''
        };
      }
      results.push(resultEntry);
    }

    // Save progress
    await db.run(
      'INSERT INTO learning_progress (user_id, content_id, score, total) VALUES (?, ?, ?, ?)',
      [req.user.id, contentId, score, questions.length]
    );

    res.json({
      success: true,
      score: score,
      total: questions.length,
      percentage: questions.length > 0 ? Math.round((score / questions.length) * 100) : 0,
      results: results
    });
  } catch (err) { console.error('[LearningHub]', err.message); res.status(500).json({ error: 'Internal server error' }); }
});

// ============================================================
// SEARCH CONTENT (keyword-based)
// ============================================================
router.get('/search', async function(req, res) {
  try {
    var q = (req.query.q || '').trim();
    if (!q) return res.json({ success: true, content: [] });

    var pattern = '%' + q + '%';
    var content = await db.all(
      `SELECT c.id, c.title, c.slug, c.subject, c.content_type, c.created_at,
              cat.name as category_name, cat.slug as category_slug,
              (SELECT COUNT(*) FROM learning_questions lq WHERE lq.content_id = c.id) as question_count
       FROM learning_content c
       LEFT JOIN learning_categories cat ON c.category_id = cat.id
       WHERE c.published = true AND (c.title ILIKE ? OR c.subject ILIKE ? OR c.body ILIKE ?)
       ORDER BY c.created_at DESC LIMIT 30`,
      [pattern, pattern, pattern]
    );

    res.json({ success: true, content: content, method: 'keyword' });
  } catch (err) { console.error('[LearningHub]', err.message); res.status(500).json({ error: 'Internal server error' }); }
});

// ============================================================
// SEMANTIC SEARCH (vector-based)
// ============================================================
router.get('/search/semantic', async function(req, res) {
  try {
    if (!isEmbeddingsAvailable()) {
      return res.status(400).json({ error: 'Semantic search not available. Embeddings not configured.' });
    }

    var q = (req.query.q || '').trim();
    if (!q) return res.json({ success: true, content: [], method: 'semantic' });

    var limit = Math.min(parseInt(req.query.limit) || 10, 50);
    var threshold = parseFloat(req.query.threshold) || 0.5;

    var results = await searchSimilar(q, {
      limit: limit,
      threshold: threshold,
      contentType: req.query.contentType || null
    });

    res.json({
      success: true,
      content: results,
      method: 'semantic',
      query: q
    });

  } catch (err) {
    console.error('[LearningHub] Semantic search error:', err.message);
    res.status(500).json({ error: 'Request failed' });
  }
});

// ============================================================
// HYBRID SEARCH (keyword + semantic combined)
// ============================================================
router.get('/search/hybrid', async function(req, res) {
  try {
    var q = (req.query.q || '').trim();
    if (!q) return res.json({ success: true, content: [], method: 'hybrid' });

    var limit = Math.min(parseInt(req.query.limit) || 20, 50);

    // 1. Get keyword matches
    var pattern = '%' + q + '%';
    var keywordResults = await db.all(
      `SELECT c.id, c.title, c.slug, c.subject, c.content_type, c.created_at,
              cat.name as category_name, cat.slug as category_slug,
              (SELECT COUNT(*) FROM learning_questions lq WHERE lq.content_id = c.id) as question_count,
              1.0 as score, 'keyword' as match_type
       FROM learning_content c
       LEFT JOIN learning_categories cat ON c.category_id = cat.id
       WHERE c.published = true AND (c.title ILIKE ? OR c.subject ILIKE ? OR c.body ILIKE ?)
       LIMIT 15`,
      [pattern, pattern, pattern]
    );

    // 2. Get semantic matches (if available)
    var semanticResults = [];
    if (isEmbeddingsAvailable()) {
      try {
        semanticResults = await searchSimilar(q, {
          limit: 15,
          threshold: 0.4
        });
        // Add match_type
        semanticResults = semanticResults.map(function(r) {
          return Object.assign(r, { score: r.similarity, match_type: 'semantic' });
        });
      } catch (err) {
        console.error('[LearningHub] Semantic search in hybrid failed:', err.message);
      }
    }

    // 3. Merge and deduplicate (favor semantic if both match)
    var seen = {};
    var combined = [];

    // Add semantic results first (higher quality)
    semanticResults.forEach(function(r) {
      if (!seen[r.id]) {
        seen[r.id] = true;
        combined.push(r);
      }
    });

    // Add keyword results if not already included
    keywordResults.forEach(function(r) {
      if (!seen[r.id]) {
        seen[r.id] = true;
        combined.push(r);
      }
    });

    // Sort by score descending, limit results
    combined.sort(function(a, b) { return (b.score || 0) - (a.score || 0); });
    combined = combined.slice(0, limit);

    res.json({
      success: true,
      content: combined,
      method: 'hybrid',
      query: q,
      keywordCount: keywordResults.length,
      semanticCount: semanticResults.length
    });

  } catch (err) {
    console.error('[LearningHub] Hybrid search error:', err.message);
    res.status(500).json({ error: 'Request failed' });
  }
});

module.exports = router;
