// ── AI Question Generation (Gemini) ──
// Replaces the former Supabase edge function. Runs on the cPanel backend.
// The local offline backend can proxy to the cPanel URL when online.
//
// Endpoints:
//   POST /api/ai/generate-questions   — generate (limited per user+course)
//   GET  /api/ai/usage?courseId=...   — current user's usage for a course
//   GET  /api/ai/usage-list           — admin: list all usage rows
//   POST /api/ai/reset-usage          — admin: reset usage (by user/course/all)
//   GET  /api/ai/config               — public AI config (enabled, limits)

const { Router } = require('express');
const { pool } = require('../db/pool');
const { authenticate, requireRole } = require('../middleware/auth');

const router = Router();

const SUPPORTED_TYPES = ['mcq', 'true_false', 'fill_blank', 'short_answer', 'essay'];
const MAX_INPUT_CHARS = 5000;
const DEFAULT_MAX_PER_COURSE = 2;

async function getAiSettings() {
  const { rows } = await pool.query(`SELECT settings FROM site_settings WHERE id = 1`);
  const s = rows[0]?.settings || {};
  return {
    enabled: s.aiGenerationEnabled !== false, // default true
    maxPerCourse: Number.isFinite(Number(s.aiMaxPerCourse))
      ? Math.max(1, Number(s.aiMaxPerCourse))
      : DEFAULT_MAX_PER_COURSE,
  };
}

router.get('/config', async (_req, res) => {
  try {
    const cfg = await getAiSettings();
    res.json({ ...cfg, maxInputChars: MAX_INPUT_CHARS });
  } catch (err) {
    res.status(500).json({ error: 'Failed to load AI config' });
  }
});

router.get('/usage', authenticate, async (req, res) => {
  const { courseId } = req.query;
  if (!courseId) return res.status(400).json({ error: 'courseId is required' });
  try {
    const cfg = await getAiSettings();
    const { rows } = await pool.query(
      `SELECT count FROM ai_generation_usage WHERE user_id = $1 AND course_id = $2`,
      [req.user.id, courseId]
    );
    const used = rows[0]?.count || 0;
    res.json({
      used,
      limit: cfg.maxPerCourse,
      remaining: Math.max(0, cfg.maxPerCourse - used),
      enabled: cfg.enabled,
      maxInputChars: MAX_INPUT_CHARS,
    });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.get('/usage-list', authenticate, requireRole('super_admin', 'admin'), async (_req, res) => {
  try {
    const { rows } = await pool.query(`
      SELECT u.id, u.user_id, u.course_id, u.count, u.last_used_at,
             usr.name AS user_name, usr.email AS user_email, usr.role AS user_role,
             c.code AS course_code, c.title AS course_title
      FROM ai_generation_usage u
      JOIN users usr ON usr.id = u.user_id
      JOIN courses c ON c.id = u.course_id
      ORDER BY u.last_used_at DESC NULLS LAST
    `);
    res.json(rows);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.post('/reset-usage', authenticate, requireRole('super_admin', 'admin'), async (req, res) => {
  const { userId, courseId, all } = req.body || {};
  try {
    if (all === true) {
      await pool.query(`DELETE FROM ai_generation_usage`);
      return res.json({ success: true, reset: 'all' });
    }
    if (!userId && !courseId) {
      return res.status(400).json({ error: 'Provide userId, courseId, or all=true' });
    }
    const conds = [];
    const params = [];
    if (userId) { params.push(userId); conds.push(`user_id = $${params.length}`); }
    if (courseId) { params.push(courseId); conds.push(`course_id = $${params.length}`); }
    await pool.query(`DELETE FROM ai_generation_usage WHERE ${conds.join(' AND ')}`, params);
    res.json({ success: true });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.post('/generate-questions', authenticate, async (req, res) => {
  try {
    const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
    if (!GEMINI_API_KEY) {
      return res.status(500).json({ error: 'GEMINI_API_KEY is not configured on the server' });
    }

    const cfg = await getAiSettings();
    if (!cfg.enabled) {
      return res.status(403).json({ error: 'AI question generation is disabled by the administrator.' });
    }

    const { content, imageDataUrl, questionTypes, difficulty, count, courseCode, courseId } = req.body || {};

    const normalizedTypes = Array.isArray(questionTypes)
      ? questionTypes.filter((t) => SUPPORTED_TYPES.includes(t))
      : [];

    if ((!content || !String(content).trim()) && !imageDataUrl) {
      return res.status(400).json({ error: 'Provide pasted text content or an image' });
    }
    if (content && String(content).length > MAX_INPUT_CHARS) {
      return res.status(400).json({
        error: `Input content exceeds the ${MAX_INPUT_CHARS} character limit (${String(content).length} provided).`,
      });
    }
    if (normalizedTypes.length === 0) {
      return res.status(400).json({ error: 'Select at least one valid question type' });
    }
    if (!courseId) {
      return res.status(400).json({ error: 'A course must be selected before generating questions.' });
    }

    // ── Per-user, per-course limit ──
    const usageRes = await pool.query(
      `SELECT count FROM ai_generation_usage WHERE user_id = $1 AND course_id = $2`,
      [req.user.id, courseId]
    );
    const used = usageRes.rows[0]?.count || 0;
    if (used >= cfg.maxPerCourse) {
      return res.status(429).json({
        error: `You have reached the maximum of ${cfg.maxPerCourse} AI generations for this course. Ask an administrator to reset your usage.`,
        used,
        limit: cfg.maxPerCourse,
      });
    }

    const totalCount = Math.max(1, Math.min(100, Number(count) || 10));
    const typesList = normalizedTypes.join(', ');

    const systemPrompt = `You are an expert exam question generator for a polytechnic CBT system.
Generate exactly ${totalCount} questions.

STRICT RULES:
- Allowed question types ONLY: ${typesList}
- NEVER output any type not in the allowed list above
- Difficulty level: ${difficulty || 'mixed'}
- Course: ${courseCode || 'General'}
- For MCQ: exactly 4 options and one correct answer
- For true_false: correct answer must be "True" or "False"
- For fill_blank / short_answer / essay: provide expected answer
- Distribute types as evenly as possible among: ${typesList}
- Questions must be academically rigorous and unambiguous`;

    const parts = [];
    if (content && String(content).trim()) {
      parts.push({ text: `Generate ${totalCount} questions from this content:\n\n${String(content).slice(0, MAX_INPUT_CHARS)}` });
    }
    if (imageDataUrl) {
      const match = String(imageDataUrl).match(/^data:([^;]+);base64,(.+)$/);
      if (match) {
        parts.push({ text: `Generate ${totalCount} questions from this material image.${content ? ' Also use the provided text above.' : ''}` });
        parts.push({ inline_data: { mime_type: match[1], data: match[2] } });
      } else {
        parts.push({ text: `Generate ${totalCount} questions from this material.` });
      }
    }

    const geminiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${GEMINI_API_KEY}`;

    const upstream = await fetch(geminiUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        system_instruction: { parts: [{ text: systemPrompt }] },
        contents: [{ role: 'user', parts }],
        tools: [{
          function_declarations: [{
            name: 'generate_questions',
            description: `Generate exactly ${totalCount} exam questions from course content`,
            parameters: {
              type: 'OBJECT',
              properties: {
                questions: {
                  type: 'ARRAY',
                  items: {
                    type: 'OBJECT',
                    properties: {
                      type: { type: 'STRING', enum: normalizedTypes },
                      text: { type: 'STRING' },
                      options: { type: 'ARRAY', items: { type: 'STRING' } },
                      correctAnswer: { type: 'STRING' },
                      difficulty: { type: 'STRING', enum: ['easy', 'medium', 'hard'] },
                    },
                    required: ['type', 'text', 'correctAnswer', 'difficulty'],
                  },
                },
              },
              required: ['questions'],
            },
          }],
        }],
        tool_config: {
          function_calling_config: {
            mode: 'ANY',
            allowed_function_names: ['generate_questions'],
          },
        },
      }),
    });

    if (!upstream.ok) {
      if (upstream.status === 429) {
        return res.status(429).json({ error: 'Rate limit exceeded. Please try again in a moment.' });
      }
      const text = await upstream.text();
      console.error('[AI] Gemini error', upstream.status, text);
      return res.status(502).json({ error: `AI provider error: ${upstream.status}` });
    }

    const data = await upstream.json();
    const candidate = data.candidates?.[0];
    const fnPart = candidate?.content?.parts?.find((p) => p.functionCall);
    if (!fnPart?.functionCall?.args) {
      return res.status(502).json({ error: 'AI did not return structured output' });
    }

    const rawQuestions = Array.isArray(fnPart.functionCall.args.questions)
      ? fnPart.functionCall.args.questions
      : [];

    const sanitized = rawQuestions
      .filter((q) => q && normalizedTypes.includes(q.type))
      .slice(0, totalCount)
      .map((q) => ({
        type: q.type,
        text: String(q.text || '').trim(),
        options: Array.isArray(q.options) ? q.options.map(String) : undefined,
        correctAnswer: String(q.correctAnswer || '').trim(),
        difficulty: ['easy', 'medium', 'hard'].includes(q.difficulty) ? q.difficulty : 'medium',
      }))
      .filter((q) => q.text.length > 0 && q.correctAnswer.length > 0);

    // ── Increment usage on successful generation ──
    await pool.query(
      `INSERT INTO ai_generation_usage (user_id, course_id, count, last_used_at)
       VALUES ($1, $2, 1, NOW())
       ON CONFLICT (user_id, course_id)
       DO UPDATE SET count = ai_generation_usage.count + 1, last_used_at = NOW()`,
      [req.user.id, courseId]
    );

    const newUsed = used + 1;
    res.json({
      questions: sanitized,
      filteredOutCount: Math.max(0, rawQuestions.length - sanitized.length),
      usage: {
        used: newUsed,
        limit: cfg.maxPerCourse,
        remaining: Math.max(0, cfg.maxPerCourse - newUsed),
      },
    });
  } catch (err) {
    console.error('[AI] generate-questions fatal:', err);
    res.status(500).json({ error: err.message || 'AI generation failed' });
  }
});

module.exports = router;
