/**
 * Reports Controller
 * Analytics and reporting endpoints
 */

const express = require('express');
const router = express.Router();

// Database path
const dbPath = process.env.DB_PATH || require('path').join(__dirname, '../../data/school.db');
const Database = require('better-sqlite3');
let db;

const getDb = () => {
  if (!db) {
    db = new Database(dbPath);
    db.pragma('foreign_keys = ON');
  }
  return db;
};

// Auth middleware
const auth = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'No token provided' });
  try {
    const jwt = require('jsonwebtoken');
    const JWT_SECRET = process.env.JWT_SECRET || 'africa-alert-secret-key-2024';
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

// Admin or teacher only
const adminOrTeacher = (req, res, next) => {
  if (req.user.role !== 'admin' && req.user.role !== 'teacher') {
    return res.status(403).json({ error: 'Admin or Teacher access required' });
  }
  next();
};

// ============ DASHBOARD OVERVIEW ============

router.get('/dashboard', auth, adminOrTeacher, (req, res) => {
  try {
    const { academic_year } = req.query;
    
    // User counts
    const userCounts = getDb().prepare(`
      SELECT role, COUNT(*) as count
      FROM users
      WHERE is_deleted = 0 AND is_active = 1
      GROUP BY role
    `).all();
    
    // Class counts
    const classCount = getDb().prepare('SELECT COUNT(*) as count FROM classes WHERE is_deleted = 0').get().count;
    
    // Active enrollments
    const enrollmentCount = getDb().prepare('SELECT COUNT(*) as count FROM enrollments WHERE status = ? AND is_deleted = 0').get('active').count;
    
    // Revenue stats
    const revenue = getDb().prepare(`
      SELECT 
        COALESCE(SUM(amount), 0) as total_revenue,
        COALESCE(SUM(CASE WHEN payment_date >= date('now', '-30 days') THEN amount ELSE 0 END), 0) as last_30_days
      FROM payments
      WHERE is_deleted = 0
    `).get();
    
    // Pending fees
    const pendingFees = getDb().prepare(`
      SELECT COALESCE(SUM(amount - paid_amount), 0) as total
      FROM student_fees
      WHERE status != 'paid' AND is_deleted = 0
    `).get();
    
    // Attendance stats (today)
    const todayAttendance = getDb().prepare(`
      SELECT 
        COUNT(CASE WHEN status = 'present' THEN 1 END) as present,
        COUNT(CASE WHEN status = 'absent' THEN 1 END) as absent,
        COUNT(CASE WHEN status = 'late' THEN 1 END) as late,
        COUNT(*) as total
      FROM attendance
      WHERE date = date('now')
    `).get();
    
    res.json({
      users: userCounts.reduce((acc, u) => { acc[u.role] = u.count; return acc; }, {}),
      classes: classCount,
      enrollments: enrollmentCount,
      revenue: {
        total: revenue.total_revenue,
        last_30_days: revenue.last_30_days
      },
      pending_fees: pendingFees.total,
      attendance: todayAttendance
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ ENROLLMENT REPORTS ============

router.get('/enrollments', auth, adminOrTeacher, (req, res) => {
  try {
    const { start_date, end_date, class_id, academic_year } = req.query;
    
    let query = `
      SELECT 
        e.id,
        u.first_name || ' ' || u.last_name as student_name,
        u.email,
        c.name as class_name,
        e.roll_number,
        e.admission_date,
        e.status,
        e.academic_year
      FROM enrollments e
      JOIN users u ON e.student_id = u.id
      JOIN classes c ON e.class_id = c.id
      WHERE e.is_deleted = 0
    `;
    const params = [];
    
    if (start_date) {
      query += ' AND e.admission_date >= ?';
      params.push(start_date);
    }
    if (end_date) {
      query += ' AND e.admission_date <= ?';
      params.push(end_date);
    }
    if (class_id) {
      query += ' AND e.class_id = ?';
      params.push(class_id);
    }
    if (academic_year) {
      query += ' AND e.academic_year = ?';
      params.push(academic_year);
    }
    
    query += ' ORDER BY e.admission_date DESC';
    
    const enrollments = getDb().prepare(query).all(...params);
    res.json(enrollments);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ FINANCIAL REPORTS ============

router.get('/financial', auth, adminOnly, (req, res) => {
  try {
    const { start_date, end_date, group_by } = req.query;
    
    let dateFilter = '1=1';
    const params = [];
    
    if (start_date) {
      dateFilter += ' AND p.payment_date >= ?';
      params.push(start_date);
    }
    if (end_date) {
      dateFilter += ' AND p.payment_date <= ?';
      params.push(end_date);
    }
    
    // Payment summary
    const payments = getDb().prepare(`
      SELECT 
        COALESCE(SUM(p.amount), 0) as total_payments,
        COUNT(*) as transaction_count,
        AVG(p.amount) as average_payment
      FROM payments p
      WHERE ${dateFilter} AND p.is_deleted = 0
    `).get(...params);
    
    // By payment method
    const byMethod = getDb().prepare(`
      SELECT 
        payment_method,
        COUNT(*) as count,
        COALESCE(SUM(amount), 0) as total
      FROM payments
      WHERE ${dateFilter} AND is_deleted = 0
      GROUP BY payment_method
    `).all(...params);
    
    // Fee collection status
    const feeStatus = getDb().prepare(`
      SELECT 
        status,
        COUNT(*) as count,
        COALESCE(SUM(amount), 0) as total_amount,
        COALESCE(SUM(paid_amount), 0) as total_paid
      FROM student_fees
      WHERE is_deleted = 0
      GROUP BY status
    `).all();
    
    // Expenses summary
    const expenses = getDb().prepare(`
      SELECT 
        COALESCE(SUM(amount), 0) as total_expenses,
        COUNT(*) as transaction_count
      FROM expenses
      WHERE ${dateFilter} AND is_deleted = 0
    `).get(...params);
    
    res.json({
      payments,
      by_payment_method: byMethod,
      fee_status: feeStatus,
      expenses
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ ATTENDANCE REPORTS ============

router.get('/attendance', auth, adminOrTeacher, (req, res) => {
  try {
    const { start_date, end_date, class_id, student_id } = req.query;
    
    let query = `
      SELECT 
        a.id,
        u.first_name || ' ' || u.last_name as student_name,
        c.name as class_name,
        a.date,
        a.status,
        a.remarks
      FROM attendance a
      JOIN users u ON a.student_id = u.id
      LEFT JOIN classes c ON a.class_id = c.id
      WHERE a.is_deleted = 0
    `;
    const params = [];
    
    if (start_date) {
      query += ' AND a.date >= ?';
      params.push(start_date);
    }
    if (end_date) {
      query += ' AND a.date <= ?';
      params.push(end_date);
    }
    if (class_id) {
      query += ' AND a.class_id = ?';
      params.push(class_id);
    }
    if (student_id) {
      query += ' AND a.student_id = ?';
      params.push(student_id);
    }
    
    query += ' ORDER BY a.date DESC LIMIT 500';
    
    const records = getDb().prepare(query).all(...params);
    res.json(records);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ GRADE REPORTS ============

router.get('/grades', auth, adminOrTeacher, (req, res) => {
  try {
    const { class_id, subject_id, exam_type, academic_year, term } = req.query;
    
    let query = `
      SELECT 
        g.id,
        u.first_name || ' ' || u.last_name as student_name,
        s.name as subject_name,
        c.name as class_name,
        g.exam_type,
        g.marks,
        g.total_marks,
        g.grade,
        g.remarks,
        g.graded_at
      FROM grades g
      JOIN users u ON g.student_id = u.id
      JOIN subjects s ON g.subject_id = s.id
      LEFT JOIN classes c ON s.class_id = c.id
      WHERE g.is_deleted = 0
    `;
    const params = [];
    
    if (class_id) {
      query += ' AND s.class_id = ?';
      params.push(class_id);
    }
    if (subject_id) {
      query += ' AND g.subject_id = ?';
      params.push(subject_id);
    }
    if (exam_type) {
      query += ' AND g.exam_type = ?';
      params.push(exam_type);
    }
    if (academic_year) {
      query += ' AND g.academic_year = ?';
      params.push(academic_year);
    }
    if (term) {
      query += ' AND g.term = ?';
      params.push(term);
    }
    
    query += ' ORDER BY g.graded_at DESC LIMIT 500';
    
    const grades = getDb().prepare(query).all(...params);
    res.json(grades);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Subject performance summary
router.get('/grades/subject-performance', auth, adminOrTeacher, (req, res) => {
  try {
    const { class_id } = req.query;
    
    let query = `
      SELECT 
        s.id,
        s.name as subject_name,
        c.name as class_name,
        COUNT(*) as exam_count,
        AVG(g.marks / g.total_marks * 100) as average_percentage,
        MIN(g.marks / g.total_marks * 100) as lowest_percentage,
        MAX(g.marks / g.total_marks * 100) as highest_percentage
      FROM grades g
      JOIN subjects s ON g.subject_id = s.id
      LEFT JOIN classes c ON s.class_id = c.id
      WHERE g.is_deleted = 0
    `;
    const params = [];
    
    if (class_id) {
      query += ' AND s.class_id = ?';
      params.push(class_id);
    }
    
    query += ' GROUP BY s.id ORDER BY average_percentage DESC';
    
    const performance = getDb().prepare(query).all(...params);
    res.json(performance);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ COURSE/ENROLLMENT ENGAGEMENT ============

router.get('/engagement', auth, adminOrTeacher, (req, res) => {
  try {
    const { class_id } = req.query;
    
    // Enrollments vs completions by class
    const classEngagement = getDb().prepare(`
      SELECT 
        c.id,
        c.name,
        COUNT(DISTINCT e.id) as enrollments,
        SUM(CASE WHEN EXISTS (
          SELECT 1 FROM grades g 
          WHERE g.student_id = e.student_id 
          AND g.subject_id IN (SELECT id FROM subjects WHERE class_id = c.id)
          AND g.is_deleted = 0
        ) THEN 1 ELSE 0 END) as with_grades
      FROM classes c
      LEFT JOIN enrollments e ON c.id = e.class_id AND e.status = 'active' AND e.is_deleted = 0
      WHERE c.is_deleted = 0
      GROUP BY c.id
    `).all();
    
    res.json(classEngagement);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ EXPORT ============

router.get('/export/:type', auth, adminOnly, (req, res) => {
  try {
    const { type } = req.params;
    const { format = 'json' } = req.query;
    
    let data;
    
    switch (type) {
      case 'users':
        data = getDb().prepare(`
          SELECT id, uid, email, role, first_name, last_name, phone, is_active, created_at
          FROM users WHERE is_deleted = 0
        `).all();
        break;
      case 'enrollments':
        data = getDb().prepare(`
          SELECT e.*, u.first_name || ' ' || u.last_name as student_name, c.name as class_name
          FROM enrollments e
          JOIN users u ON e.student_id = u.id
          JOIN classes c ON e.class_id = c.id
          WHERE e.is_deleted = 0
        `).all();
        break;
      case 'grades':
        data = getDb().prepare(`
          SELECT g.*, u.first_name || ' ' || u.last_name as student_name, s.name as subject_name
          FROM grades g
          JOIN users u ON g.student_id = u.id
          JOIN subjects s ON g.subject_id = s.id
          WHERE g.is_deleted = 0
        `).all();
        break;
      case 'attendance':
        data = getDb().prepare(`
          SELECT a.*, u.first_name || ' ' || u.last_name as student_name
          FROM attendance a
          JOIN users u ON a.student_id = u.id
          WHERE a.is_deleted = 0
          ORDER BY a.date DESC LIMIT 1000
        `).all();
        break;
      default:
        return res.status(400).json({ error: 'Invalid export type' });
    }
    
    if (format === 'csv') {
      // Convert to CSV
      if (data.length === 0) {
        return res.status(404).json({ error: 'No data to export' });
      }
      
      const headers = Object.keys(data[0]);
      const csvRows = [headers.join(',')];
      for (const row of data) {
        csvRows.push(headers.map(h => {
          const val = row[h];
          if (val === null || val === undefined) return '';
          return typeof val === 'string' && val.includes(',') ? `"${val}"` : val;
        }).join(','));
      }
      
      res.setHeader('Content-Type', 'text/csv');
      res.setHeader('Content-Disposition', `attachment; filename=${type}_export_${Date.now()}.csv`);
      return res.send(csvRows.join('\n'));
    }
    
    res.json(data);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Admin-only middleware
function adminOnly(req, res, next) {
  if (req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Admin access required' });
  }
  next();
}

module.exports = router;