/**
 * Messages Controller
 * Internal messaging system
 */

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' });
  }
};

// ============ MESSAGES CRUD ============

// List messages (inbox)
router.get('/', auth, (req, res) => {
  try {
    const { folder = 'inbox', unread_only, sender_id } = req.query;
    
    let query;
    const params = [req.user.id];
    
    if (folder === 'sent') {
      query = `
        SELECT m.*, u.first_name || ' ' || u.last_name as recipient_name, u.email as recipient_email
        FROM messages m
        LEFT JOIN users u ON m.recipient_id = u.id
        WHERE m.sender_id = ? AND m.is_deleted = 0
        ORDER BY m.created_at DESC
      `;
    } else {
      query = `
        SELECT m.*, u.first_name || ' ' || u.last_name as sender_name, u.email as sender_email
        FROM messages m
        LEFT JOIN users u ON m.sender_id = u.id
        WHERE m.recipient_id = ? AND m.is_deleted = 0
        ORDER BY m.created_at DESC
      `;
    }
    
    if (unread_only === 'true') {
      query = query.replace('is_deleted = 0', 'is_deleted = 0 AND m.is_read = 0');
    }
    
    if (sender_id && folder === 'inbox') {
      query = query.replace('is_deleted = 0', 'is_deleted = 0 AND m.sender_id = ?');
      params.unshift(sender_id);
    }
    
    const messages = getDb().prepare(query).all(...params);
    res.json(messages);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get unread count
router.get('/unread/count', auth, (req, res) => {
  try {
    const result = getDb().prepare(`
      SELECT COUNT(*) as count FROM messages WHERE recipient_id = ? AND is_read = 0 AND is_deleted = 0
    `).get(req.user.id);
    
    res.json({ count: result.count });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get single message
router.get('/:id', auth, (req, res) => {
  try {
    const message = getDb().prepare(`
      SELECT m.*, 
        s.first_name || ' ' || s.last_name as sender_name,
        r.first_name || ' ' || r.last_name as recipient_name
      FROM messages m
      LEFT JOIN users s ON m.sender_id = s.id
      LEFT JOIN users r ON m.recipient_id = r.id
      WHERE m.id = ? AND m.is_deleted = 0
    `).get(req.params.id);
    
    if (!message) {
      return res.status(404).json({ error: 'Message not found' });
    }
    
    // Check access
    if (message.sender_id !== req.user.id && message.recipient_id !== req.user.id && req.user.role !== 'admin') {
      return res.status(403).json({ error: 'Access denied' });
    }
    
    // Mark as read
    if (message.recipient_id === req.user.id && message.is_read === 0) {
      getDb().prepare('UPDATE messages SET is_read = 1, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(req.params.id);
      message.is_read = 1;
    }
    
    res.json(message);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Send message
router.post('/', auth, (req, res) => {
  try {
    const { recipient_id, subject, body, priority, is_announcement } = req.body;
    
    if (!recipient_id || !subject || !body) {
      return res.status(400).json({ error: 'recipient_id, subject, and body are required' });
    }
    
    const uid = uuidv4();
    
    const result = getDb().prepare(`
      INSERT INTO messages (uid, sender_id, recipient_id, subject, body, priority, is_announcement)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `).run(uid, req.user.id, recipient_id, subject, body, priority || 'normal', is_announcement ? 1 : 0);
    
    const message = getDb().prepare(`
      SELECT m.*, u.first_name || ' ' || u.last_name as recipient_name
      FROM messages m
      LEFT JOIN users u ON m.recipient_id = u.id
      WHERE m.id = ?
    `).get(result.lastInsertRowid);
    
    res.status(201).json(message);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Reply to message
router.post('/:id/reply', auth, (req, res) => {
  try {
    const { body } = req.body;
    
    if (!body) {
      return res.status(400).json({ error: 'Body is required' });
    }
    
    const original = getDb().prepare(`
      SELECT * FROM messages WHERE id = ? AND is_deleted = 0
    `).get(req.params.id);
    
    if (!original) {
      return res.status(404).json({ error: 'Original message not found' });
    }
    
    // Can only reply to messages addressed to you
    if (original.recipient_id !== req.user.id) {
      return res.status(403).json({ error: 'Cannot reply to this message' });
    }
    
    const uid = uuidv4();
    
    const result = getDb().prepare(`
      INSERT INTO messages (uid, sender_id, recipient_id, subject, body, priority)
      VALUES (?, ?, ?, ?, ?, ?)
    `).run(uid, req.user.id, original.sender_id, `Re: ${original.subject}`, body, original.priority);
    
    const message = getDb().prepare('SELECT * FROM messages WHERE id = ?').get(result.lastInsertRowid);
    res.status(201).json(message);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Update message (mark read/unread)
router.put('/:id', auth, (req, res) => {
  try {
    const { is_read } = req.body;
    
    const message = getDb().prepare('SELECT * FROM messages WHERE id = ?').get(req.params.id);
    
    if (!message) {
      return res.status(404).json({ error: 'Message not found' });
    }
    
    // Only recipient can update
    if (message.recipient_id !== req.user.id && req.user.role !== 'admin') {
      return res.status(403).json({ error: 'Access denied' });
    }
    
    if (is_read !== undefined) {
      getDb().prepare('UPDATE messages SET is_read = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(is_read ? 1 : 0, req.params.id);
    }
    
    const updated = getDb().prepare('SELECT * FROM messages WHERE id = ?').get(req.params.id);
    res.json(updated);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Delete message (soft delete)
router.delete('/:id', auth, (req, res) => {
  try {
    const message = getDb().prepare('SELECT * FROM messages WHERE id = ?').get(req.params.id);
    
    if (!message) {
      return res.status(404).json({ error: 'Message not found' });
    }
    
    // Can delete if you're sender or recipient
    if (message.sender_id !== req.user.id && message.recipient_id !== req.user.id && req.user.role !== 'admin') {
      return res.status(403).json({ error: 'Access denied' });
    }
    
    // Soft delete
    getDb().prepare('UPDATE messages SET is_deleted = 1, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(req.params.id);
    
    res.json({ success: true, message: 'Message deleted' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ ANNOUNCEMENTS ============

// Get announcements
router.get('/announcements', auth, (req, res) => {
  try {
    const announcements = getDb().prepare(`
      SELECT m.*, u.first_name || ' ' || u.last_name as sender_name
      FROM messages m
      LEFT JOIN users u ON m.sender_id = u.id
      WHERE m.is_announcement = 1 AND m.is_deleted = 0
      ORDER BY m.created_at DESC
      LIMIT 50
    `).all();
    
    res.json(announcements);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Send announcement
router.post('/announcements', auth, (req, res) => {
  if (req.user.role !== 'admin' && req.user.role !== 'teacher') {
    return res.status(403).json({ error: 'Admin or Teacher access required' });
  }
  
  try {
    const { recipient_id, subject, body, priority } = req.body;
    
    if (!subject || !body) {
      return res.status(400).json({ error: 'Subject and body are required' });
    }
    
    const uid = uuidv4();
    
    const result = getDb().prepare(`
      INSERT INTO messages (uid, sender_id, recipient_id, subject, body, priority, is_announcement)
      VALUES (?, ?, ?, ?, ?, ?, 1)
    `).run(uid, req.user.id, recipient_id || null, subject, body, priority || 'normal');
    
    const announcement = getDb().prepare('SELECT * FROM messages WHERE id = ?').get(result.lastInsertRowid);
    res.status(201).json(announcement);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ CONTACTS ============

// Get user contacts (for messaging)
router.get('/contacts', auth, (req, res) => {
  try {
    const { search, role } = req.query;
    
    let query = `
      SELECT id, first_name, last_name, email, role, profile_image
      FROM users
      WHERE is_deleted = 0 AND is_active = 1 AND id != ?
    `;
    const params = [req.user.id];
    
    if (search) {
      query += ' AND (first_name LIKE ? OR last_name LIKE ? OR email LIKE ?)';
      const searchTerm = `%${search}%`;
      params.push(searchTerm, searchTerm, searchTerm);
    }
    
    if (role) {
      query += ' AND role = ?';
      params.push(role);
    }
    
    query += ' ORDER BY last_name, first_name LIMIT 100';
    
    const contacts = getDb().prepare(query).all(...params);
    res.json(contacts);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ CONVERSATIONS ============

// Get conversation with a specific user
router.get('/conversation/:userId', auth, (req, res) => {
  try {
    const otherUserId = parseInt(req.params.userId);
    
    const messages = getDb().prepare(`
      SELECT m.*, 
        CASE WHEN m.sender_id = ? THEN 'sent' ELSE 'received' END as direction,
        u.first_name || ' ' || u.last_name as other_user_name
      FROM messages m
      LEFT JOIN users u ON CASE WHEN m.sender_id = ? THEN m.recipient_id ELSE m.sender_id END = u.id
      WHERE ((m.sender_id = ? AND m.recipient_id = ?) OR (m.sender_id = ? AND m.recipient_id = ?))
        AND m.is_deleted = 0
      ORDER BY m.created_at DESC
      LIMIT 100
    `).all(req.user.id, req.user.id, req.user.id, otherUserId, otherUserId, req.user.id);
    
    // Mark as read
    getDb().prepare(`
      UPDATE messages SET is_read = 1, updated_at = CURRENT_TIMESTAMP
      WHERE recipient_id = ? AND sender_id = ? AND is_read = 0
    `).run(req.user.id, otherUserId);
    
    res.json(messages);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get recent conversations
router.get('/conversations', auth, (req, res) => {
  try {
    const conversations = getDb().prepare(`
      SELECT 
        other_user_id,
        other_user_name,
        last_message,
        last_message_at,
        unread_count
      FROM (
        SELECT 
          CASE WHEN m.sender_id = ? THEN m.recipient_id ELSE m.sender_id END as other_user_id,
          u.first_name || ' ' || u.last_name as other_user_name,
          m.body as last_message,
          m.created_at as last_message_at,
          (SELECT COUNT(*) FROM messages WHERE sender_id = other_user_id AND recipient_id = ? AND is_read = 0) as unread_count,
          ROW_NUMBER() OVER (PARTITION BY other_user_id ORDER BY m.created_at DESC) as rn
        FROM messages m
        LEFT JOIN users u ON CASE WHEN m.sender_id = ? THEN m.recipient_id ELSE m.sender_id END = u.id
        WHERE (m.sender_id = ? OR m.recipient_id = ?) AND m.is_deleted = 0
      ) sub
      WHERE rn = 1
      ORDER BY last_message_at DESC
    `).all(req.user.id, req.user.id, req.user.id, req.user.id, req.user.id);
    
    res.json(conversations);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;