const express = require('express');
const db = require('../config/database');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const router = express.Router();

// Middleware to verify JWT token
const verifyToken = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) {
    return res.status(401).json({ message: 'No token provided' });
  }
  
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(401).json({ message: 'Invalid token' });
  }
};

// Static API key middleware for location endpoints
const authenticateLocationKey = (req, res, next) => {
  const apiKey = req.headers['x-api-key'] || req.headers['authorization']?.replace('Bearer ', '');
  const expectedKey = process.env.LOCATION_STATIC_API_KEY || 'GPSV2_STATIC_LOCATION_KEY_2025';
  
  if (!apiKey || apiKey !== expectedKey) {
    return res.status(401).json({ message: 'Invalid API key' });
  }
  
  next();
};

// Get all schools (filtered by user's school if not super admin)
router.get('/schools', verifyToken, async (req, res) => {
  try {
    let query = 'SELECT * FROM schools';
    let params = [];
    
    // Check if user is super admin or school admin
    const [userRows] = await db.execute('SELECT user_type, school_id FROM users WHERE id = ?', [req.user.id]);
    
    if (userRows.length > 0 && userRows[0].user_type === 'school' && userRows[0].school_id) {
      // School admin - only show their school
      query += ' WHERE id = ?';
      params.push(userRows[0].school_id);
    }
    
    query += ' ORDER BY created_at DESC';
    
    const [rows] = await db.execute(query, params);
    
    const schoolsWithCounts = rows.map(school => ({
      ...school,
      total_students: 0,
      total_devices: 0,
      plan_name: 'Basic'
    }));
    
    res.json(schoolsWithCounts);
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Create new school
router.post('/schools', verifyToken, async (req, res) => {
  try {
    const { name, email, phone, address, contact_person } = req.body;
    
    const [result] = await db.execute(`
      INSERT INTO schools (name, email, phone, address, status)
      VALUES (?, ?, ?, ?, 'active')
    `, [name, email, phone, address]);
    
    res.json({ message: 'School created successfully', school_id: result.insertId });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Update school
router.put('/schools/:id', verifyToken, async (req, res) => {
  try {
    const { id } = req.params;
    const { name, email, phone, address } = req.body;
    
    await db.execute(`
      UPDATE schools 
      SET name = ?, email = ?, phone = ?, address = ?
      WHERE id = ?
    `, [name, email, phone, address, id]);
    
    res.json({ message: 'School updated successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Get all devices with school info (admin only)
router.get('/devices', verifyToken, async (req, res) => {
  try {
    const query = `
      SELECT d.*, s.name as school_name,
        CASE 
          WHEN d.school_id IS NULL THEN 'unassigned'
          ELSE 'assigned'
        END as assignment_status
      FROM devices d
      LEFT JOIN schools s ON d.school_id = s.id
      ORDER BY d.created_at DESC
    `;
    
    const [rows] = await db.execute(query);
    res.json(rows);
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Add new device (admin only)
router.post('/devices', verifyToken, async (req, res) => {
  try {
    const { device_id, type, imei_number, sim_number, model, manufacturer } = req.body;
    
    // Check if device_id already exists
    const [existing] = await db.execute('SELECT id FROM devices WHERE device_id = ?', [device_id]);
    if (existing.length > 0) {
      return res.status(400).json({ message: 'Device ID already exists' });
    }
    
    const uniqueId = `DEV_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    
    const [result] = await db.execute(`
      INSERT INTO devices (id, device_id, type, imei_number, sim_number, model, manufacturer, status, battery_level, created_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, 'active', 85, NOW())
    `, [uniqueId, device_id, type || 'GPS Tracker', imei_number, sim_number, model, manufacturer]);
    
    res.json({ message: 'Device added successfully', device_id: result.insertId });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Assign device to school (admin only)
router.post('/devices/:deviceId/assign', verifyToken, async (req, res) => {
  try {
    const { deviceId } = req.params;
    const { school_id } = req.body;
    
    await db.execute('UPDATE devices SET school_id = ? WHERE id = ?', [school_id, deviceId]);
    
    res.json({ message: 'Device assigned to school successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Unassign device from school (admin only)
router.post('/devices/:deviceId/unassign', verifyToken, async (req, res) => {
  try {
    const { deviceId } = req.params;
    
    await db.execute('UPDATE devices SET school_id = NULL WHERE id = ?', [deviceId]);
    
    res.json({ message: 'Device unassigned from school successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Delete device (admin only)
router.delete('/devices/:deviceId', verifyToken, async (req, res) => {
  try {
    const { deviceId } = req.params;
    
    // Check if device exists
    const [device] = await db.execute('SELECT device_id, school_id FROM devices WHERE device_id = ?', [deviceId]);
    if (device.length === 0) {
      return res.status(404).json({ message: 'Device not found' });
    }
    
    // Check if device is assigned to any children
    const [children] = await db.execute('SELECT id, first_name, last_name FROM children WHERE device_id = ?', [deviceId]);
    if (children.length > 0) {
      return res.status(400).json({ 
        message: 'Cannot delete device. It is assigned to students.',
        assigned_students: children.map(c => ({ id: c.id, name: `${c.first_name} ${c.last_name}` }))
      });
    }
    
    // Delete device location history
    await db.execute('DELETE FROM device_locations WHERE device_id = ?', [deviceId]);
    
    // Delete the device
    const [result] = await db.execute('DELETE FROM devices WHERE device_id = ?', [deviceId]);
    
    if (result.affectedRows === 0) {
      return res.status(404).json({ message: 'Device not found or already deleted' });
    }
    
    res.json({ message: 'Device deleted successfully', device_id: deviceId });
  } catch (error) {
    console.error('Error deleting device:', error);
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Assign all existing devices to school_id = 1 (admin only)
router.post('/devices/assign-all-to-school-1', verifyToken, async (req, res) => {
  try {
    const [result] = await db.execute('UPDATE devices SET school_id = 1 WHERE school_id IS NULL OR school_id != 1');
    
    res.json({ 
      message: 'All devices assigned to school ID 1 successfully',
      affected_rows: result.affectedRows
    });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Get analytics data
router.get('/analytics', verifyToken, async (req, res) => {
  try {
    const [schoolCount] = await db.execute('SELECT COUNT(*) as count FROM schools');
    const [deviceCount] = await db.execute('SELECT COUNT(*) as count FROM devices');
    
    res.json({
      totalSchools: schoolCount[0].count,
      totalDevices: deviceCount[0].count,
      activeDevices: deviceCount[0].count,
      monthlyRevenue: 0,
      openTickets: 0
    });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Get all users (filtered by user's school if not super admin)
router.get('/users', verifyToken, async (req, res) => {
  try {
    let query = `
      SELECT u.*, s.name as school_name
      FROM users u
      LEFT JOIN schools s ON u.school_id = s.id
    `;
    let params = [];
    
    // Check if user is super admin or school admin
    const [userRows] = await db.execute('SELECT user_type, school_id FROM users WHERE id = ?', [req.user.id]);
    
    if (userRows.length > 0 && userRows[0].user_type === 'school' && userRows[0].school_id) {
      // School admin - only show users from their school
      query += ' WHERE (u.school_id = ? OR u.user_type = "parent")';
      params.push(userRows[0].school_id);
    }
    
    query += ' ORDER BY u.created_at DESC';
    
    const [rows] = await db.execute(query, params);
    res.json(rows);
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Create new user
router.post('/users', verifyToken, async (req, res) => {
  try {
    const { email, first_name, last_name, user_type, school_id, password } = req.body;
    
    console.log('Creating user with data:', { email, first_name, last_name, user_type, school_id });
    
    if (!email || !first_name || !last_name || !user_type || !password) {
      return res.status(400).json({ message: 'All required fields must be provided' });
    }
    
    const hashedPassword = await bcrypt.hash(password, 10);
    
    const username = email.split('@')[0] + '_' + Date.now();
    
    const [result] = await db.execute(`
      INSERT INTO users (email, username, password_hash, first_name, last_name, user_type, school_id, status)
      VALUES (?, ?, ?, ?, ?, ?, ?, 'active')
    `, [email, username, hashedPassword, first_name, last_name, user_type, school_id || null]);
    
    res.json({ message: 'User created successfully', user_id: result.insertId });
  } catch (error) {
    console.error('Error creating user:', error);
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Update user
router.put('/users/:id', verifyToken, async (req, res) => {
  try {
    const { id } = req.params;
    const { email, first_name, last_name, user_type, school_id, password } = req.body;
    
    let updateQuery = `
      UPDATE users 
      SET email = ?, first_name = ?, last_name = ?, user_type = ?, school_id = ?
    `;
    let params = [email, first_name, last_name, user_type, school_id || null];
    
    if (password && password.trim() !== '') {
      const hashedPassword = await bcrypt.hash(password, 10);
      updateQuery += ', password_hash = ?';
      params.push(hashedPassword);
    }
    
    updateQuery += ' WHERE id = ?';
    params.push(id);
    
    await db.execute(updateQuery, params);
    
    res.json({ message: 'User updated successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Delete user
router.delete('/users/:id', verifyToken, async (req, res) => {
  try {
    const { id } = req.params;

    if (!id) {
      return res.status(400).json({ message: 'User ID is required' });
    }

    if (String(req.user.id) === String(id)) {
      return res.status(400).json({ message: 'You cannot delete your own account' });
    }

    // Determine requester scope
    const [requesterRows] = await db.execute('SELECT user_type, school_id FROM users WHERE id = ?', [req.user.id]);
    if (requesterRows.length === 0) {
      return res.status(403).json({ message: 'Access denied' });
    }

    const requesterType = requesterRows[0].user_type;
    const requesterSchoolId = requesterRows[0].school_id;

    // Load target user
    const [targetRows] = await db.execute('SELECT id, user_type, school_id FROM users WHERE id = ?', [id]);
    if (targetRows.length === 0) {
      return res.status(404).json({ message: 'User not found' });
    }

    const targetUser = targetRows[0];

    // Authorization rules:
    // - Super admin (user_type === 'admin') can delete any user.
    // - School admin (user_type === 'school') can delete users within their school.
    if (requesterType === 'school') {
      if (!requesterSchoolId) {
        return res.status(403).json({ message: 'Access denied' });
      }

      if (String(targetUser.school_id) !== String(requesterSchoolId)) {
        return res.status(403).json({ message: 'Access denied' });
      }
    } else if (requesterType !== 'admin') {
      return res.status(403).json({ message: 'Access denied' });
    }

    await db.query('START TRANSACTION');

    try {
      if (targetUser.user_type === 'parent') {
        await db.execute('UPDATE children SET parent_id = 0 WHERE parent_id = ?', [id]);
        await db.execute('DELETE FROM parent_details WHERE user_id = ?', [id]);
      }

      await db.execute('DELETE FROM users WHERE id = ?', [id]);

      await db.query('COMMIT');
      return res.json({ message: 'User deleted successfully' });
    } catch (error) {
      await db.query('ROLLBACK');
      throw error;
    }
  } catch (error) {
    console.error('Error deleting user:', error);
    return res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Update or insert device status
router.post('/device-status', authenticateLocationKey, async (req, res) => {
  try {
    const { device_id, status, last_seen, last_ip } = req.body;
    
    if (!device_id || !status) {
      return res.status(400).json({ message: 'device_id and status are required' });
    }
    
    const query = `
      INSERT INTO device_status (device_id, status, last_seen, last_ip)
      VALUES (?, ?, ?, ?)
      ON DUPLICATE KEY UPDATE
        status = VALUES(status),
        last_seen = VALUES(last_seen),
        last_ip = VALUES(last_ip)
    `;
    
    await db.execute(query, [device_id, status, last_seen, last_ip]);
    
    res.json({ message: 'Device status updated successfully' });
  } catch (error) {
    console.error('Error updating device status:', error);
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

module.exports = router;