const express = require('express');
const { errorReportHelpers, logToFile, pool } = require('../mariadb');
const { validateSession } = require('../sessionModel');
const { exec } = require('child_process');
const execPromise = (cmd) => new Promise((resolve, reject) => exec(cmd, { timeout: 30000 }, (err, stdout) => err ? reject(err) : resolve(stdout)));
const router = express.Router();

// Middleware: require valid session (logged-in user)
const requireSession = async (req, res, next) => {
  const sessionId = req.headers['x-session-id'] || (req.body && req.body.sessionId) || (req.query && req.query.sessionId);
  if (!sessionId) return res.status(401).json({ error: 'Login required' });
  const session = await validateSession(sessionId);
  if (!session || !session.data || !session.data.playerName) {
    return res.status(401).json({ error: 'Invalid or expired session' });
  }
  req.session = session;
  req.sessionPlayerName = session.data.playerName;
  next();
};

// POST /api/errors - Submit error report (requires login)
router.post('/', requireSession, async (req, res) => {
  try {
    const { title, description, category, pageUrl } = req.body;
    if (!title || !description) {
      return res.status(400).json({ error: 'Title and description are required' });
    }
    const reportId = await errorReportHelpers.create({
      playerName: req.sessionPlayerName,
      title,
      description,
      category: category || 'other',
      pageUrl: pageUrl || ''
    });
    logToFile(`API: Error report #${reportId} created by ${req.sessionPlayerName}`);

    // Also create a GitHub issue
    let issueUrl = null;
    try {
      const body = [
        `**Category:** ${category || 'other'}\n`,
        `**Reported by:** ${req.sessionPlayerName}\n`,
        `**Page:** ${pageUrl || 'N/A'}\n`,
        `**Description:**\n${description}`
      ].join('\n');
      const label = category && category !== 'other' ? category : 'other';
      const result = await execPromise(`cd /nas/git/dwroller && gh issue create --title "Error: ${title}" --body '${body.replace(/'/g, "\\'")}' --label '${label}' --repo alexpolo1/dwroller`);
      // gh issue create outputs: https://github.com/...#issue-xxx
      issueUrl = result.trim();
      logToFile(`API: GitHub issue created: ${issueUrl}`);
      // Update DB with the GitHub issue URL
      await pool.execute('UPDATE error_reports SET github_issue_url = ? WHERE id = ?', [issueUrl, reportId]);
    } catch (ghError) {
      logToFile('API: Failed to create GitHub issue', ghError);
      // Don't fail the request — the DB report still succeeded
    }

    res.json({ success: true, id: reportId, githubIssueUrl: issueUrl });
  } catch (error) {
    logToFile('API: Error creating report', error);
    res.status(500).json({ error: String(error) });
  }
});

// GET /api/errors - List error reports (requires login, GM sees all, player sees their own)
router.get('/', requireSession, async (req, res) => {
  try {
    const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
    const reports = isGM
      ? await errorReportHelpers.getAll()
      : await errorReportHelpers.getByPlayer(req.sessionPlayerName);
    res.json(reports);
  } catch (error) {
    logToFile('API: Error listing reports', error);
    res.status(500).json({ error: String(error) });
  }
});

// GET /api/errors/:id - Get one error report (requires login)
router.get('/:id', requireSession, async (req, res) => {
  try {
    const report = await errorReportHelpers.getById(parseInt(req.params.id));
    if (!report) return res.status(404).json({ error: 'Not found' });
    // Players can only see their own reports, GM sees all
    const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
    if (!isGM && report.player_name !== req.sessionPlayerName) {
      return res.status(403).json({ error: 'Access denied' });
    }
    res.json(report);
  } catch (error) {
    logToFile('API: Error getting report', error);
    res.status(500).json({ error: String(error) });
  }
});

// PUT /api/errors/:id/resolve - Resolve error report (GM only)
router.put('/:id/resolve', requireSession, async (req, res) => {
  try {
    const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
    if (!isGM) return res.status(403).json({ error: 'GM access required' });
    const { note } = req.body;
    await errorReportHelpers.resolve(parseInt(req.params.id), req.sessionPlayerName, note || '');
    logToFile(`API: Error report #${req.params.id} resolved by ${req.sessionPlayerName}`);
    res.json({ success: true });
  } catch (error) {
    logToFile('API: Error resolving report', error);
    res.status(500).json({ error: String(error) });
  }
});

// PUT /api/errors/:id/status - Update status (GM only)
router.put('/:id/status', requireSession, async (req, res) => {
  try {
    const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
    if (!isGM) return res.status(403).json({ error: 'GM access required' });
    const { status } = req.body;
    await errorReportHelpers.updateStatus(parseInt(req.params.id), status);
    res.json({ success: true });
  } catch (error) {
    logToFile('API: Error updating status', error);
    res.status(500).json({ error: String(error) });
  }
});

// DELETE /api/errors/:id - Delete error report (GM only)
router.delete('/:id', requireSession, async (req, res) => {
  try {
    const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
    if (!isGM) return res.status(403).json({ error: 'GM access required' });
    await errorReportHelpers.delete(parseInt(req.params.id));
    logToFile(`API: Error report #${req.params.id} deleted by ${req.sessionPlayerName}`);
    res.json({ success: true });
  } catch (error) {
    logToFile('API: Error deleting report', error);
    res.status(500).json({ error: String(error) });
  }
});

console.log('Error report routes registered');
module.exports = router;