/**
 * Departments Controller
 * Class/Department management with subject associations
 */

const express = require('express');
const router = express.Router();
const { v4: uuidv4 } = require('uuid');

// 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-only middleware
const adminOnly = (req, res, next) => {
  if (req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Admin access required' });
  }
  next();
};

// ============ DEPARTMENTS (CLASSES) CRUD ============

// List all departments/classes
router.get('/', auth, (req, res) => {
  try {
    const { search, teacher_id } = req.query;
    
    let query = `
      SELECT c.*, 
        (SELECT COUNT(*) FROM enrollments WHERE class_id = c.id AND status = 'active' AND is_deleted = 0) as student_count,
        (SELECT COUNT(*) FROM subjects WHERE class_id = c.id AND is_deleted = 0) as subject_count,
        t.first_name || ' ' || t.last_name as class_teacher_name
      FROM classes c
      LEFT JOIN users t ON c.class_teacher_id = t.id
      WHERE c.is_deleted = 0
    `;
    const params = [];
    
    if (search) {
      query += ' AND (c.name LIKE ? OR c.section LIKE ?)';
      const searchTerm = `%${search}%`;
      params.push(searchTerm, searchTerm);
    }
    
    if (teacher_id) {
      query += ' AND c.class_teacher_id = ?';
      params.push(teacher_id);
    }
    
    query += ' ORDER BY c.name, c.section';
    
    const departments = getDb().prepare(query).all(...params);
    res.json(departments);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get single department by ID
router.get('/:id', auth, (req, res) => {
  try {
    const department = getDb().prepare(`
      SELECT c.*,
        (SELECT COUNT(*) FROM enrollments WHERE class_id = c.id AND status = 'active' AND is_deleted = 0) as student_count,
        (SELECT COUNT(*) FROM subjects WHERE class_id = c.id AND is_deleted = 0) as subject_count,
        t.first_name || ' ' || t.last_name as class_teacher_name
      FROM classes c
      LEFT JOIN users t ON c.class_teacher_id = t.id
      WHERE c.id = ? AND c.is_deleted = 0
    `).get(req.params.id);
    
    if (!department) {
      return res.status(404).json({ error: 'Department not found' });
    }
    
    // Get subjects
    const subjects = getDb().prepare(`
      SELECT s.*, t.first_name || ' ' || t.last_name as teacher_name
      FROM subjects s
      LEFT JOIN users t ON s.teacher_id = t.id
      WHERE s.class_id = ? AND s.is_deleted = 0
      ORDER BY s.name
    `).all(req.params.id);
    
    // Get students
    const students = getDb().prepare(`
      SELECT u.id, u.uid, u.first_name, u.last_name, u.email, u.phone, e.roll_number
      FROM enrollments e
      JOIN users u ON e.student_id = u.id
      WHERE e.class_id = ? AND e.status = 'active' AND e.is_deleted = 0 AND u.is_deleted = 0
      ORDER BY e.roll_number, u.last_name
    `).all(req.params.id);
    
    res.json({ ...department, subjects, students });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Create department
router.post('/', auth, adminOnly, (req, res) => {
  try {
    const { name, section, capacity, class_teacher_id, description } = req.body;
    
    if (!name) {
      return res.status(400).json({ error: 'Department name is required' });
    }
    
    const uid = uuidv4();
    
    const result = getDb().prepare(`
      INSERT INTO classes (uid, name, section, capacity, class_teacher_id, description)
      VALUES (?, ?, ?, ?, ?, ?)
    `).run(uid, name, section, capacity || 40, class_teacher_id, description);
    
    const department = getDb().prepare('SELECT * FROM classes WHERE id = ?').get(result.lastInsertRowid);
    res.status(201).json(department);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Update department
router.put('/:id', auth, adminOnly, (req, res) => {
  try {
    const { name, section, capacity, class_teacher_id, description } = req.body;
    
    getDb().prepare(`
      UPDATE classes SET
        name = COALESCE(?, name),
        section = COALESCE(?, section),
        capacity = COALESCE(?, capacity),
        class_teacher_id = COALESCE(?, class_teacher_id),
        description = COALESCE(?, description),
        updated_at = CURRENT_TIMESTAMP,
        sync_status = 'pending'
      WHERE id = ? AND is_deleted = 0
    `).run(name, section, capacity, class_teacher_id, description, req.params.id);
    
    const updated = getDb().prepare('SELECT * FROM classes WHERE id = ?').get(req.params.id);
    
    if (!updated) {
      return res.status(404).json({ error: 'Department not found' });
    }
    
    res.json(updated);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Delete department (soft delete)
router.delete('/:id', auth, adminOnly, (req, res) => {
  try {
    // Check if department has students
    const studentCount = getDb().prepare('SELECT COUNT(*) as count FROM enrollments WHERE class_id = ? AND is_deleted = 0').get(req.params.id).count;
    
    if (studentCount > 0) {
      return res.status(400).json({ error: 'Cannot delete department with active students. Transfer students first.' });
    }
    
    getDb().prepare(`
      UPDATE classes SET is_deleted = 1, updated_at = CURRENT_TIMESTAMP, sync_status = 'pending'
      WHERE id = ?
    `).run(req.params.id);
    
    res.json({ success: true, message: 'Department deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ SUBJECTS CRUD (within departments) ============

// List subjects
router.get('/:id/subjects', auth, (req, res) => {
  try {
    const subjects = getDb().prepare(`
      SELECT s.*, t.first_name || ' ' || t.last_name as teacher_name
      FROM subjects s
      LEFT JOIN users t ON s.teacher_id = t.id
      WHERE s.class_id = ? AND s.is_deleted = 0
      ORDER BY s.name
    `).all(req.params.id);
    
    res.json(subjects);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Add subject to department
router.post('/:id/subjects', auth, adminOnly, (req, res) => {
  try {
    const { name, code, teacher_id, description, credit_hours } = req.body;
    
    if (!name) {
      return res.status(400).json({ error: 'Subject name is required' });
    }
    
    const uid = uuidv4();
    
    const result = getDb().prepare(`
      INSERT INTO subjects (uid, name, code, class_id, teacher_id, description, credit_hours)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `).run(uid, name, code, req.params.id, teacher_id, description, credit_hours || 1);
    
    const subject = getDb().prepare('SELECT * FROM subjects WHERE id = ?').get(result.lastInsertRowid);
    res.status(201).json(subject);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Update subject
router.put('/:id/subjects/:subjectId', auth, adminOnly, (req, res) => {
  try {
    const { name, code, teacher_id, description, credit_hours } = req.body;
    
    getDb().prepare(`
      UPDATE subjects SET
        name = COALESCE(?, name),
        code = COALESCE(?, code),
        teacher_id = COALESCE(?, teacher_id),
        description = COALESCE(?, description),
        credit_hours = COALESCE(?, credit_hours),
        updated_at = CURRENT_TIMESTAMP,
        sync_status = 'pending'
      WHERE id = ? AND is_deleted = 0
    `).run(name, code, teacher_id, description, credit_hours, req.params.subjectId);
    
    const updated = getDb().prepare('SELECT * FROM subjects WHERE id = ?').get(req.params.subjectId);
    
    if (!updated) {
      return res.status(404).json({ error: 'Subject not found' });
    }
    
    res.json(updated);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Delete subject
router.delete('/:id/subjects/:subjectId', auth, adminOnly, (req, res) => {
  try {
    getDb().prepare(`
      UPDATE subjects SET is_deleted = 1, updated_at = CURRENT_TIMESTAMP, sync_status = 'pending'
      WHERE id = ?
    `).run(req.params.subjectId);
    
    res.json({ success: true, message: 'Subject deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ STATS ============

// Get department statistics
router.get('/stats/overview', auth, (req, res) => {
  try {
    const stats = getDb().prepare(`
      SELECT 
        COUNT(*) as total_departments,
        SUM(CASE WHEN (SELECT COUNT(*) FROM enrollments WHERE class_id = classes.id AND status = 'active') > 0 THEN 1 ELSE 0 END) as departments_with_students,
        SUM((SELECT COUNT(*) FROM enrollments WHERE class_id = classes.id AND status = 'active')) as total_students,
        SUM((SELECT COUNT(*) FROM subjects WHERE class_id = classes.id)) as total_subjects
      FROM classes
      WHERE is_deleted = 0
    `).get();
    
    res.json(stats);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get student distribution by department
router.get('/stats/distribution', auth, (req, res) => {
  try {
    const distribution = getDb().prepare(`
      SELECT 
        c.id,
        c.name,
        c.section,
        COUNT(e.id) as student_count
      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
      ORDER BY student_count DESC
    `).all();
    
    const total = distribution.reduce((sum, d) => sum + d.student_count, 0);
    
    res.json(distribution.map(d => ({
      ...d,
      percentage: total > 0 ? ((d.student_count / total) * 100).toFixed(1) : 0
    })));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;