// controllers/meetingController.js
const Meeting = require('../models/meetingSchema'); // Adjust the path as necessary
const jwt = require('jsonwebtoken');

// Create a new meeting
// exports.createMeeting = async (req, res) => {
//   try {
//     const { roomName, ownerName, description, scheduledTime, validityDuration } = req.body;

//     // Validate required fields
//     if (!roomName || !ownerName || !scheduledTime || !validityDuration) {
//       return res.status(400).json({ 
//         message: 'Room name, owner name, scheduled time, and validity duration are required' 
//       });
//     }

//     // Generate unique room ID
//     const roomId = `room_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

//     // Calculate expiry time
//     const scheduledDate = new Date(scheduledTime);
//     const expiryTime = new Date(scheduledDate.getTime() + (validityDuration * 60 * 1000));

//     // Create meeting
//     const meeting = new Meeting({
//       roomName: roomName.trim(),
//       roomId,
//       ownerName: ownerName.trim(),
//       description: description ? description.trim() : '',
//       scheduledTime: scheduledDate,
//       validityDuration: parseInt(validityDuration),
//       expiryTime,
//       status: 'scheduled'
//     });

//     await meeting.save();

//     // Generate JWT token for Jitsi access (optional - for secure meetings)
//     const jwtPayload = {
//       room: roomId,
//       user: ownerName,
//       exp: Math.floor(expiryTime.getTime() / 1000), // JWT expiry matches meeting expiry
//       aud: 'jitsi',
//       iss: 'your-app-name'
//     };

//     const token = jwt.sign(jwtPayload, process.env.JWT_SECRET || 'fallback-secret');

//     res.status(201).json({
//       success: true,
//       message: 'Meeting created successfully',
//       data: {
//         ...meeting.toObject(),
//         token, // Include token for frontend link generation
//         meetingLink: `${process.env.FRONTEND_URL || 'http://localhost:3000'}/join/${roomId}?token=${token}`
//       }
//     });

//   } catch (error) {
//     console.error('Error creating meeting:', error);
//     res.status(500).json({ 
//       success: false,
//       message: 'Failed to create meeting',
//       error: error.message 
//     });
//   }
// };
const { generateJitsiJWT, validateJitsiJWT } = require('../utils/jwtUtils');

// Create a new meeting with secure URLs
exports.createMeeting = async (req, res) => {
  try {
    const { roomName, ownerName, description, scheduledTime, validityDuration } = req.body;
    
    // Validation
    if (!roomName || !ownerName || !scheduledTime || !validityDuration) {
      return res.status(400).json({ 
        success: false,
        message: 'Required fields: roomName, ownerName, scheduledTime, validityDuration' 
      });
    }
    
    // Generate unique room ID
    const roomId = `room_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    
    // Calculate dates
    const scheduledDate = new Date(scheduledTime);
    const expiryTime = new Date(scheduledDate.getTime() + (validityDuration * 60 * 1000));
    
    // Validate future date
    if (scheduledDate < new Date()) {
      return res.status(400).json({
        success: false,
        message: 'Scheduled time must be in the future'
      });
    }
    
    // Create meeting first to get ID
    const meeting = new Meeting({
      roomName: roomName.trim(),
      roomId,
      ownerName: ownerName.trim(),
      description: description ? description.trim() : '',
      scheduledTime: scheduledDate,
      validityDuration: parseInt(validityDuration),
      expiryTime,
      status: 'scheduled'
    });
    
    await meeting.save();
    
    // Generate JWT tokens for both roles
    const moderatorToken = generateJitsiJWT(roomId, ownerName, true, meeting._id, expiryTime);
    const participantToken = generateJitsiJWT(roomId, 'Guest', false, meeting._id, expiryTime);
    
    // Generate secure meeting URLs
    const baseUrl = process.env.FRONTEND_URL || 'http://localhost:3000';
    
    const ownerMeetingUrl = `${baseUrl}/meeting?room=${roomId}&name=${encodeURIComponent(ownerName)}&token=${moderatorToken}&role=moderator`;
    const participantMeetingUrl = `${baseUrl}/meeting?room=${roomId}&token=${participantToken}&role=participant`;
    
    // Update meeting with URLs
    meeting.ownerMeetingUrl = ownerMeetingUrl;
    meeting.participantMeetingUrl = participantMeetingUrl;
    meeting.moderatorToken = moderatorToken;
    meeting.participantToken = participantToken;
    await meeting.save();
    
    res.status(201).json({
      success: true,
      message: 'Meeting created successfully',
      data: meeting
    });
    
  } catch (error) {
    console.error('Error creating meeting:', error);
    res.status(500).json({ 
      success: false,
      message: 'Failed to create meeting',
      error: process.env.NODE_ENV === 'development' ? error.message : undefined
    });
  }
};

exports.validateMeeting = async (req, res) => {
  try {
    const { roomId, token } = req.body;
    
    if (!roomId || !token) {
      return res.status(400).json({
        success: false,
        message: 'Room ID and token are required'
      });
    }
    
    // Verify JWT token
    const validation = validateJitsiJWT(token);
    if (!validation.valid) {
      return res.status(403).json({
        success: false,
        message: 'Invalid or expired token'
      });
    }
    
    const decoded = validation.payload;
    
    // Check if token room matches request
    if (decoded.room !== roomId) {
      return res.status(403).json({
        success: false,
        message: 'Token does not match room'
      });
    }
    
    // Get meeting from database
    const meeting = await Meeting.findOne({ roomId });
    if (!meeting) {
      return res.status(404).json({
        success: false,
        message: 'Meeting not found'
      });
    }
    
    // Check if meeting is expired
    if (new Date() > new Date(meeting.expiryTime)) {
      return res.status(410).json({
        success: false,
        message: 'Meeting has expired'
      });
    }
    
    res.json({
      success: true,
      data: meeting,
      role: decoded.context.user.moderator ? 'moderator' : 'participant',
      userName: decoded.context.user.name
    });
    
  } catch (error) {
    console.error('Meeting validation error:', error);
    res.status(500).json({
      success: false,
      message: 'Validation failed'
    });
  }
};

// Get all meetings with optional filtering
exports.getMeetings = async (req, res) => {
  try {
    const { status, page = 1, limit = 20, ownerName } = req.query;
    
    // Build filter object
    const filter = {};
    
    if (status && status !== 'all') {
      // Handle expired meetings dynamically
      if (status === 'expired') {
        filter.expiryTime = { $lt: new Date() };
      } else {
        filter.status = status;
        // Ensure we don't show expired meetings in other status filters
        filter.expiryTime = { $gte: new Date() };
      }
    }
    
    if (ownerName) {
      filter.ownerName = { $regex: ownerName, $options: 'i' }; // Case-insensitive search
    }

    // Calculate pagination
    const skip = (parseInt(page) - 1) * parseInt(limit);

    // Fetch meetings with pagination
    const meetings = await Meeting.find(filter)
      .sort({ createdAt: -1 }) // Most recent first
      .skip(skip)
      .limit(parseInt(limit));

    // Get total count for pagination info
    const total = await Meeting.countDocuments(filter);

    // Update status for expired meetings in the response
    const meetingsWithStatus = meetings.map(meeting => {
      const meetingObj = meeting.toObject();
      if (new Date() > new Date(meeting.expiryTime)) {
        meetingObj.status = 'expired';
      }
      return meetingObj;
    });

    const jwtPayload = {
      room: meetingsWithStatus[0]?.roomId || 'default_room',
      user: ownerName,
      exp: Math.floor(meetingsWithStatus[0]?.expiryTime.getTime() / 1000), // JWT expiry matches meeting expiry
      aud: 'jitsi',
      iss: 'your-app-name'
    };

    const token = jwt.sign(jwtPayload, process.env.JWT_SECRET || 'fallback-secret');

    res.json({
      success: true,
      data: meetingsWithStatus,
      token, // Include token for frontend link generation
      pagination: {
        current: parseInt(page),
        total: Math.ceil(total / parseInt(limit)),
        count: meetings.length,
        totalRecords: total
      }
    });

  } catch (error) {
    console.error('Error fetching meetings:', error);
    res.status(500).json({ 
      success: false,
      message: 'Failed to fetch meetings',
      error: error.message 
    });
  }
};

// Get single meeting by ID or roomId
exports.getMeetingById = async (req, res) => {
  try {
    const { id } = req.params;
    
    // Try to find by MongoDB _id first, then by roomId
    let meeting = await Meeting.findById(id);
    if (!meeting) {
      meeting = await Meeting.findOne({ roomId: id });
    }

    if (!meeting) {
      return res.status(404).json({ 
        success: false,
        message: 'Meeting not found' 
      });
    }

    // Check if expired
    const meetingObj = meeting.toObject();
    if (new Date() > new Date(meeting.expiryTime)) {
      meetingObj.status = 'expired';
    }

    res.json({
      success: true,
      data: meetingObj
    });

  } catch (error) {
    console.error('Error fetching meeting:', error);
    res.status(500).json({ 
      success: false,
      message: 'Failed to fetch meeting',
      error: error.message 
    });
  }
};

// Update meeting status (for when meeting starts/ends)
exports.updateMeetingStatus = async (req, res) => {
  try {
    const { roomId } = req.params;
    const { status, participantCount, recordingUrl } = req.body;

    const updateData = {};
    
    if (status) updateData.status = status;
    if (participantCount !== undefined) updateData.participantCount = participantCount;
    if (recordingUrl) updateData.recordingUrl = recordingUrl;

    const meeting = await Meeting.findOneAndUpdate(
      { roomId },
      updateData,
      { new: true, runValidators: true }
    );

    if (!meeting) {
      return res.status(404).json({ 
        success: false,
        message: 'Meeting not found' 
      });
    }

    res.json({
      success: true,
      message: 'Meeting updated successfully',
      data: meeting
    });

  } catch (error) {
    console.error('Error updating meeting:', error);
    res.status(500).json({ 
      success: false,
      message: 'Failed to update meeting',
      error: error.message 
    });
  }
};

// Delete meeting (admin only)
exports.deleteMeeting = async (req, res) => {
  try {
    const { id } = req.params;

    const meeting = await Meeting.findByIdAndDelete(id);
    
    if (!meeting) {
      return res.status(404).json({ 
        success: false,
        message: 'Meeting not found' 
      });
    }

    res.json({
      success: true,
      message: 'Meeting deleted successfully'
    });

  } catch (error) {
    console.error('Error deleting meeting:', error);
    res.status(500).json({ 
      success: false,
      message: 'Failed to delete meeting',
      error: error.message 
    });
  }
};
