const { Booking, User, GymClass } = require('../models');

// @desc    Get all bookings
// @route   GET /api/bookings
// @access  Public
exports.getBookings = async (req, res) => {
  try {
    const bookings = await Booking.findAll({
      include: [
        {
          model: User,
          attributes: ['id', 'name', 'email']
        },
        {
          model: GymClass
        }
      ]
    });
    
    res.status(200).json(bookings);
  } catch (error) {
    console.error('Error in getBookings:', error);
    res.status(500).json({
      message: 'Error retrieving bookings',
      error: error.message
    });
  }
};

// @desc    Get bookings by user ID
// @route   GET /api/bookings/user/:userId
// @access  Public
exports.getBookingsByUser = async (req, res) => {
  try {
    const bookings = await Booking.findAll({
      where: { userId: req.params.userId },
      include: [
        {
          model: User,
          attributes: ['id', 'name', 'email']
        },
        {
          model: GymClass
        }
      ]
    });
    
    res.status(200).json(bookings);
  } catch (error) {
    console.error('Error in getBookingsByUser:', error);
    res.status(500).json({
      message: 'Error retrieving user bookings',
      error: error.message
    });
  }
};

// @desc    Create new booking
// @route   POST /api/bookings
// @access  Public
exports.createBooking = async (req, res) => {
  try {
    const { userId, gymClassId } = req.body;
    
    // Check if user exists
    const user = await User.findByPk(userId);
    if (!user) {
      return res.status(404).json({
        message: 'User not found'
      });
    }
    
    // Check if class exists
    const gymClass = await GymClass.findByPk(gymClassId);
    if (!gymClass) {
      return res.status(404).json({
        message: 'Class not found'
      });
    }
    
    // Check if class has available capacity
    if (gymClass.currentBookings >= gymClass.maxCapacity) {
      return res.status(409).json({
        message: 'No hay plazas disponibles'
      });
    }
    
    // Create booking
    const booking = await Booking.create({
      userId,
      gymClassId,
      status: 'confirmed',
      bookingDate: new Date()
    });
    
    // Update class capacity
    gymClass.currentBookings += 1;
    await gymClass.save();
    
    // Return booking with associations
    const fullBooking = await Booking.findByPk(booking.id, {
      include: [
        {
          model: User,
          attributes: ['id', 'name', 'email']
        },
        {
          model: GymClass
        }
      ]
    });
    
    res.status(201).json(fullBooking);
  } catch (error) {
    console.error('Error in createBooking:', error);
    res.status(500).json({
      message: 'Error creating booking',
      error: error.message
    });
  }
};

// @desc    Cancel booking
// @route   PUT /api/bookings/:id/cancel
// @access  Public
exports.cancelBooking = async (req, res) => {
  try {
    const booking = await Booking.findByPk(req.params.id);
    
    if (!booking) {
      return res.status(404).json({
        message: 'Booking not found'
      });
    }
    
    // Check if booking is already canceled
    if (booking.status !== 'confirmed') {
      return res.status(400).json({
        message: 'Booking is not in confirmed status'
      });
    }
    
    // Update booking status
    booking.status = 'cancelled';
    await booking.save();
    
    // Update class capacity
    const gymClass = await GymClass.findByPk(booking.gymClassId);
    if (gymClass) {
      gymClass.currentBookings -= 1;
      await gymClass.save();
    }
    
    // Return updated booking with associations
    const updatedBooking = await Booking.findByPk(booking.id, {
      include: [
        {
          model: User,
          attributes: ['id', 'name', 'email']
        },
        {
          model: GymClass
        }
      ]
    });
    
    res.status(200).json(updatedBooking);
  } catch (error) {
    console.error('Error in cancelBooking:', error);
    res.status(500).json({
      message: 'Error cancelling booking',
      error: error.message
    });
  }
};