const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const User = require('../models/User');
const Otp = require('../models/Otp');
const sendEmail = require('../utils/sendEmail');
const Store = require('../models/Store');
const DeliveryBoy = require('../models/DeliveryBoy');
const { BadRequestError, UnauthorizedError } = require('../utils/errors');
const AppError = require('../utils/appError');

// Helper function to send token response
const sendTokenResponse = (user, statusCode, res) => {
  // Create token
  const token = user.getSignedJwtToken();

  const options = {
    expires: new Date(
      Date.now() + process.env.JWT_COOKIE_EXPIRE * 24 * 60 * 60 * 1000
    ),
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production'
  };

  // Remove password from output
  user.password = undefined;

  res.status(statusCode).json({
    success: true,
    token,
    user
  });
};

// @desc    Send OTP to phone number
// @route   POST /api/v1/auth/send-otp
// @access  Public
exports.sendOtp = async (req, res, next) => {
  try {
    console.log('Send OTP request received:', req.body);
    
    let { phone } = req.body;

    if (!phone) {
      console.error('Phone number is required');
      throw new BadRequestError('Phone number is required');
    }

    // Clean the phone number (remove any non-digit characters)
    phone = phone.replace(/\D/g, '');
    console.log('Cleaned phone number:', phone);

    // Validate phone number length (10 digits for India without country code)
    if (phone.length !== 10 && !(phone.length === 12 && phone.startsWith('91'))) {
      console.error('Invalid phone number length:', phone.length);
      throw new BadRequestError('Please enter a valid 10-digit mobile number');
    }

    // Generate a 6-digit OTP
    const otp = Math.floor(100000 + Math.random() * 900000).toString();
    console.log(`Generated OTP for ${phone}: ${otp}`);
    
    // Save OTP to database with the original phone number (without country code)
    const phoneToStore = phone.length === 12 ? phone.substring(2) : phone;
    console.log('Saving OTP to database for phone:', phoneToStore);
    
    try {
      const otpDoc = await Otp.findOneAndUpdate(
        { phone: phoneToStore },
        { 
          otp: otp,
          expiresAt: new Date(Date.now() + 5 * 60 * 1000), // 5 minutes expiry
          verified: false
        },
        { 
          upsert: true, 
          new: true, 
          setDefaultsOnInsert: true 
        }
      );
      console.log('OTP saved to database:', otpDoc);
    } catch (dbError) {
      console.error('Database error when saving OTP:', dbError);
      throw new Error('Failed to save OTP. Please try again.');
    }

    const response = {
      success: true,
      message: 'OTP sent successfully',
      // In development, include OTP for testing
      ...(process.env.NODE_ENV !== 'production' && { 
        otp: otp,
        debug: {
          phoneEntered: req.body.phone,
          phoneStored: phoneToStore,
          timestamp: new Date().toISOString()
        }
      })
    };

    console.log('Sending response:', response);
    res.status(200).json(response);
  } catch (error) {
    console.error('Error in sendOtp:', error);
    next(error);
  }
};

// @desc    Verify OTP and register/login user
// @route   POST /api/v1/auth/verify-otp
// @access  Public
exports.verifyOtp = async (req, res, next) => {
  // Only use transactions in production or if explicitly enabled
  const useTransactions = process.env.USE_MONGO_TRANSACTIONS === 'true';
  const session = useTransactions ? await mongoose.startSession() : null;
  
  if (useTransactions) {
    await session.startTransaction();
  }
  
  try {
    console.log('Verify OTP request received:', req.body);
    const { phone, otp, name, email, role = 'customer' } = req.body;

    if (!phone || !otp) {
      console.error('Missing phone or OTP in request');
      throw new BadRequestError('Phone number and OTP are required');
    }

    console.log(`Looking for OTP for phone: ${phone}`);
    
    // Find OTP record
    const query = Otp.findOne({ phone, otp });
    if (useTransactions) query.session(session);
    const otpRecord = await query;
    
    if (!otpRecord) {
      console.error('No OTP record found for phone:', phone);
      throw new UnauthorizedError('Invalid OTP');
    }

    // Check if OTP is expired
    if (otpRecord.expiresAt < new Date()) {
      console.error('OTP expired for phone:', phone);
      await Otp.deleteOne({ _id: otpRecord._id });
      throw new UnauthorizedError('OTP has expired');
    }

    // Check if user exists
    let userQuery = User.findOne({ phone });
    if (useTransactions) userQuery.session(session);
    let user = await userQuery;
    const isNewUser = !user;

    if (!user) {
      console.log('Creating new user for phone:', phone);
      // Register new user if not exists
      if (!name || !email) {
        throw new BadRequestError('Name and email are required for registration');
      }

      // Check if email is already registered
      const existingEmail = await User.findOne({ email });
      if (existingEmail) {
        throw new BadRequestError('Email is already registered');
      }

      const userData = {
        name,
        email,
        phone,
        role,
        isPhoneVerified: true,
        lastLogin: Date.now()
      };

      if (useTransactions) {
        user = (await User.create([userData], { session }))[0];
      } else {
        user = await User.create(userData);
      }
      
      console.log('New user created:', user._id);
    } else {
      console.log('Existing user found:', user._id);
      // Update last login for existing user
      user.lastLogin = Date.now();
      await user.save(useTransactions ? { session } : undefined);
    }

    // Mark OTP as verified and delete it
    otpRecord.verified = true;
    await otpRecord.save();
    await Otp.deleteOne({ _id: otpRecord._id });
    console.log('OTP record deleted for phone:', phone);

    // Generate token
    const token = user.getSignedJwtToken();
    console.log('JWT token generated for user:', user._id);

    const responseData = {
      success: true,
      token,
      user: {
        id: user._id,
        name: user.name,
        email: user.email,
        phone: user.phone,
        role: user.role
      },
      isNewUser
    };

    // Commit the transaction if using transactions
    if (useTransactions) {
      await session.commitTransaction();
      session.endSession();
    }

    console.log('Sending success response for user:', user._id);
    res.status(200).json(responseData);
  } catch (error) {
    console.error('Error in verifyOtp:', error);
    
    // Abort transaction if using transactions
    if (session) {
      await session.abortTransaction();
      session.endSession();
    }
    
    next(error);
  }
};


// @desc    Register a new user
// @route   POST /api/v1/auth/register
// @access  Public
exports.register = async (req, res, next) => {
  try {
    const { name, email, phone, password, passwordConfirm } = req.body;

    // Check if passwords match
    if (password !== passwordConfirm) {
      return next(new AppError('Passwords do not match', 400));
    }

    // Check if user already exists
    const existingUser = await User.findOne({ $or: [{ email }, { phone }] });
    if (existingUser) {
      return next(new AppError('User already exists with this email or phone', 400));
    }

    // Create new user
    const user = await User.create({
      name,
      email,
      phone,
      password,
      role: 'customer', // Default role
      status: true
    });

    // Generate token
    const token = user.getSignedJwtToken();

    res.status(201).json({
      success: true,
      token,
      user: {
        id: user._id,
        name: user.name,
        email: user.email,
        phone: user.phone,
        role: user.role
      }
    });
  } catch (err) {
    console.error('Registration error:', err);
    next(err);
  }
};

// @route   POST /api/v1/auth/login
// @access  Public
exports.login = async (req, res, next) => {
  try {
    console.log('Login attempt:', req.body);

    const { email, password } = req.body;

    // Validate email & password
    if (!email || !password) {
      console.log('Missing email or password');
      return next(new BadRequestError('Please provide both email and password'));
    }

    // Get user with password for verification
    let user;
    let isMatch = false;
    let userRole = '';

    try {
      // 1. Check in User collection first
      const standardUser = await User.findOne({ email, role: { $in: ['user', 'admin', 'pharmacist', 'customer', 'picker_packer'] } }).select('+password');
      if (standardUser) {
        console.log('Found user in User collection.');
        console.log('Checking password for user role:', standardUser.role);
        console.log('Entered password length:', password.length);
        console.log('Stored password exists:', !!standardUser.password);
        
        // Always try to match password for all user types
        isMatch = await standardUser.matchPassword(password);
        console.log('Password match result:', isMatch);
        
        if (isMatch) {
          user = standardUser;
          userRole = standardUser.role;
          
          // If this is a pharmacist, get their pharmacist record
          if (userRole === 'pharmacist') {
            try {
              const Pharmacist = mongoose.model('Pharmacist');
              const pharmacist = await Pharmacist.findOne({ email });
              if (pharmacist) {
                console.log('Found linked pharmacist record');
                user._doc.pharmacist = pharmacist;
              }
            } catch (error) {
              console.error('Error fetching pharmacist record:', error);
            }
          }
          // If this is a picker_packer, get their picker packer record
          else if (userRole === 'picker_packer') {
            try {
              const PickerPacker = mongoose.model('PickerPacker');
              const pickerPacker = await PickerPacker.findOne({ email })
                .populate('store', 'name _id');
              if (pickerPacker) {
                console.log('Found linked picker packer record');
                user._doc.pickerPacker = pickerPacker;
                // Add store to user object for easier access
                user._doc.store = pickerPacker.store;
              }
            } catch (error) {
              console.error('Error fetching picker packer record:', error);
            }
          }
        } else {
          console.log('Password mismatch in User collection');
        }
      }

      // 2. If not found or password doesn't match, check in Store collection
      if (!user) {
        console.log('User not found or password mismatch in User collection, checking Store collection...');
        const storeUser = await Store.findOne({ email }).select('+password');
        if (storeUser) {
          console.log('Found user in Store collection.');
          isMatch = await storeUser.comparePassword(password);
          if (isMatch) {
            user = storeUser;
            userRole = 'store_manager'; // Assign role explicitly
          }
        }
      }

      // 3. If still not found, check in DeliveryBoy collection
      if (!user) {
        console.log('User not found in Store collection, checking DeliveryBoy collection...');
        const deliveryBoy = await DeliveryBoy.findOne({ email }).select('+password');
        if (deliveryBoy) {
          console.log('Found user in DeliveryBoy collection.');
          isMatch = await deliveryBoy.matchPassword(password);
          if (isMatch) {
            user = deliveryBoy;
            userRole = 'delivery_boy'; // Assign role explicitly
          }
        }
      }

      // 4. If still not found, check in PickerPacker collection
      if (!user) {
        console.log('User not found in standard collections, checking PickerPacker collection...');
        try {
          const PickerPacker = mongoose.model('PickerPacker');
          // Find picker packer by email and ensure password is selected
          const pickerPacker = await PickerPacker.findOne({ email }).select('+password');
          
          if (pickerPacker) {
            console.log('Found user in PickerPacker collection.');
            console.log('PickerPacker found with email:', pickerPacker.email);
            
            // Check if password exists and is a string
            if (!pickerPacker.password || typeof pickerPacker.password !== 'string') {
              console.log('No valid password found for picker packer, creating one...');
              // Set a default password if none exists
              pickerPacker.password = '123456'; // This will be hashed by the pre-save hook
              await pickerPacker.save();
            }
            
            // Check password
            console.log('Checking password for picker packer...');
            isMatch = await pickerPacker.matchPassword(password);
            console.log('Password match result for picker packer:', isMatch);
            
            if (isMatch) {
              console.log('Password matched for picker packer');
              
              // Check if there's a linked user account
              if (pickerPacker.user) {
                console.log('Found linked user account for picker packer');
                const userAccount = await User.findById(pickerPacker.user);
                if (userAccount) {
                  user = userAccount;
                  userRole = 'picker_packer';
                  user._doc.pickerPacker = pickerPacker;
                  user._doc.store = pickerPacker.store;
                }
              } else {
                // If no linked user account, create a user-like object
                console.log('No linked user account, creating user-like object');
                user = {
                  _id: pickerPacker._id,
                  name: pickerPacker.name,
                  email: pickerPacker.email,
                  phone: pickerPacker.phone,
                  role: 'picker_packer',
                  _doc: {
                    pickerPacker: pickerPacker,
                    store: pickerPacker.store,
                    ...pickerPacker._doc
                  },
                  save: async function() {
                    // Dummy save function to prevent errors
                    return Promise.resolve(this);
                  }
                };
                userRole = 'picker_packer';
              }
              
              // Update last login
              pickerPacker.lastLogin = new Date();
              await pickerPacker.save();
            }
          }
        } catch (error) {
          console.error('Error checking picker packer login:', error);
        }
      }

      // 5. If still not found, check in Pharmacist collection (for backward compatibility)
      if (!user) {
        console.log('User not found in PickerPacker collection, checking Pharmacist collection...');
        try {
          const Pharmacist = mongoose.model('Pharmacist');
          // Explicitly select password field for comparison
          const pharmacist = await Pharmacist.findOne({ email }).select('+password');
          
          if (pharmacist) {
            console.log('Found user in Pharmacist collection.');
            
            // Check password against Pharmacist model
            console.log('Checking password against Pharmacist model...');
            isMatch = await pharmacist.matchPassword(password);
            
            if (isMatch) {
              console.log('Password matched for pharmacist:', pharmacist.email);
              user = pharmacist;
              userRole = 'pharmacist';
              
              // If pharmacist has a linked user account, use that ID
              if (user.user) {
                const userAccount = await User.findById(user.user);
                if (userAccount) {
                  user._doc.userAccount = userAccount;
                }
              }
            } else {
              console.log('Password mismatch for pharmacist:', pharmacist.email);
            }
          }
        } catch (error) {
          console.error('Error checking pharmacist login:', error);
        }
      }
    } catch (dbError) {
      console.error('Database error during login:', dbError);
      return next(new Error('Authentication service unavailable'));
    }

    // 3. Final check for user and password match
    if (!user || !isMatch) {
      console.log('Invalid credentials for email:', email);
      console.log('User found:', !!user);
      console.log('Password match:', isMatch);
      return next(new UnauthorizedError('Invalid credentials'));
    }

    // 4. Create token and send response
    try {
      const token = jwt.sign(
        { id: user._id, role: userRole },
        process.env.JWT_SECRET,
        { expiresIn: process.env.JWT_EXPIRE || '30d' }
      );

      console.log('Login successful for user:', user._id, 'with role:', userRole);

      // Update last login time if user has save method
      if (typeof user.save === 'function') {
        user.lastLogin = new Date();
        try {
          const saveOptions = { validateBeforeSave: false };
          await user.save(saveOptions);
        } catch (saveError) {
          console.error('Error saving last login time:', saveError);
          // Continue even if saving last login fails
        }
      }

      // Construct a clean user object for the frontend
      const userObj = user.toObject();
      
      // Handle location data
      let location = {};
      if (userObj.location) {
        location = {
          address: userObj.location.address,
          city: userObj.location.city,
          state: userObj.location.state,
          country: userObj.location.country,
          coordinates: userObj.location.coordinates?.coordinates || [0, 0],
          pincode: userObj.location.pincode
        };
      }

      // Handle store manager, pharmacist, and picker packer information
      let storeManager = null;
      let store = null;
      let userId = user._id;
      
      // If user is a picker packer, get their store information
      if (userRole === 'picker_packer') {
        if (user._doc?.pickerPacker?.store) {
          store = {
            _id: user._doc.pickerPacker.store._id,
            name: user._doc.pickerPacker.store.name
          };
        } else if (user._doc?.store) {
          // If store is already populated in the user object
          store = {
            _id: user._doc.store._id,
            name: user._doc.store.name
          };
        }
      }
      
      if (userRole === 'store_manager') {
        // For store managers, find their store using the storeManager field
        const storeData = await Store.findOne({ storeManager: user._id });
        if (storeData) {
          store = {
            _id: storeData._id,
            name: storeData.name,
            logo: storeData.logo
          };
          storeManager = user._id;
        }
      } else if (userRole === 'pharmacist') {
        // For pharmacists, get their assigned store and user account
        if (user.store) {
          const storeData = await Store.findById(user.store);
          if (storeData) {
            store = {
              _id: storeData._id,
              name: storeData.name,
              logo: storeData.logo
            };
          }
        }
        
        // Use the user account ID if available (from user._doc.userAccount)
        if (user._doc?.userAccount?._id) {
          userId = user._doc.userAccount._id;
        }
      } else if (user.storeManager) {
        // If user has a storeManager reference, include it
        storeManager = user.storeManager;
      }

      const responseUser = {
        id: user._id,
        name: user.name,
        email: user.email,
        role: { name: userRole },
        phone: user.mobile || user.phone,
        status: user.status,
        avatar: user.avatar?.url || user.store?.logo,
        location,
        store, // Include store details if available
        storeManager // Include storeManager in the response
      };
      
      console.log('User response data:', {
        userId: user._id,
        role: userRole,
        store,
        storeManager
      });
      
      console.log('User login successful:', { userId: user._id, role: userRole });

      return res.status(200).json({
        success: true,
        token,
        user: responseUser
      });
    } catch (error) {
      console.error('Error in login controller:', error);
      return next(error);
    }
  } catch (error) {
    console.error('Unexpected error in login:', error);
    return next(error);
  }
};

// @desc    Forgot password
// @route   POST /api/v1/auth/forgot-password
// @access  Public
exports.forgotPassword = async (req, res, next) => {
  try {
    const { email } = req.body;

    if (!email) {
      return next(new BadRequestError('Please provide an email address'));
    }

    const user = await User.findOne({ email });

    if (!user) {
      // For security, don't reveal if the email exists or not
      return res.status(200).json({
        success: true,
        message: 'If an account with that email exists, a reset link has been sent'
      });
    }

    // Generate reset token
    const resetToken = user.getResetPasswordToken();
    await user.save({ validateBeforeSave: false });

    // Create reset URL (frontend URL)
    const resetUrl = `${req.protocol}://${req.get('host')}/reset-password/${resetToken}`;

    try {
      // Send email with password reset link
      await sendEmail.sendPasswordResetEmail(user.email, resetUrl);
      
      res.status(200).json({
        success: true,
        message: 'If an account with that email exists, a reset link has been sent'
      });
    } catch (emailError) {
      console.error('Error sending password reset email:', emailError);
      
      // Reset the token and expiry if email fails
      user.resetPasswordToken = undefined;
      user.resetPasswordExpire = undefined;
      await user.save({ validateBeforeSave: false });
      
      return next(new Error('Email could not be sent'));
    }
  } catch (error) {
    console.error('Forgot password error:', error);
    user.resetPasswordToken = undefined;
    user.resetPasswordExpire = undefined;
    await user.save({ validateBeforeSave: false });
    next(error);
  }
};

// @desc    Get current logged in user
// @route   GET /api/v1/auth/me
// @access  Private
exports.getMe = async (req, res, next) => {
  try {
    const user = await User.findById(req.user.id)
      .select('-password -__v')  // Only exclude password and __v
      .populate([
        {
          path: 'storeManager',
          select: 'name email phone status',
          model: 'Store'
        },
        {
          path: 'deliveryBoy',
          select: 'name phone status',
          model: 'DeliveryBoy'
        }
      ]);

    if (!user) {
      return next(new Error('User not found'));
    }

    // Convert to plain JavaScript object
    let userObj = user.toObject();
    
    // Format dates to ISO strings for consistency
    if (userObj.createdAt) userObj.createdAt = userObj.createdAt.toISOString();
    if (userObj.updatedAt) userObj.updatedAt = userObj.updatedAt.toISOString();
    if (userObj.lastLogin) userObj.lastLogin = userObj.lastLogin.toISOString();
    
    // Handle location data
    if (userObj.location) {
      if (userObj.location.lastUpdated) {
        userObj.location.lastUpdated = userObj.location.lastUpdated.toISOString();
      }
      // Ensure coordinates is in the right format
      if (userObj.location.coordinates && userObj.location.coordinates.coordinates) {
        userObj.location.coordinates = {
          type: userObj.location.coordinates.type || 'Point',
          coordinates: userObj.location.coordinates.coordinates
        };
      }
    }

    // Handle storeManager reference
    if (user.role === 'store_manager') {
      // If user is a store manager, use their ID as storeManager
      userObj.storeManager = user._id.toString();
    } else if (user.storeManager) {
      // If user has a storeManager reference, use it
      userObj.storeManager = user.storeManager._id ? 
        user.storeManager._id.toString() : 
        user.storeManager.toString();
    } else if (userObj.storeManager) {
      // Fallback to the raw storeManager field if it exists
      userObj.storeManager = userObj.storeManager._id ? 
        userObj.storeManager._id.toString() : 
        userObj.storeManager.toString();
    } else if (user.storeManagerId) {
      // Check for storeManagerId as an alternative field
      userObj.storeManager = user.storeManagerId.toString();
    } else {
      // If no store manager reference exists, try to find it in the database
      try {
        const store = await mongoose.model('Store').findOne({ manager: user._id });
        if (store) {
          userObj.storeManager = store._id.toString();
        } else {
          userObj.storeManager = null;
        }
      } catch (error) {
        console.error('Error finding store manager:', error);
        userObj.storeManager = null;
      }
    }
    
    // Handle deliveryBoy reference
    if (user.deliveryBoy) {
      userObj.deliveryBoy = user.deliveryBoy._id ? 
        user.deliveryBoy._id.toString() : 
        user.deliveryBoy.toString();
    } else if (userObj.deliveryBoy) {
      userObj.deliveryBoy = userObj.deliveryBoy._id ? 
        userObj.deliveryBoy._id.toString() : 
        userObj.deliveryBoy.toString();
    } else {
      // If no delivery boy reference exists, try to find it in the database
      try {
        const deliveryBoy = await mongoose.model('DeliveryBoy').findOne({ user: user._id });
        if (deliveryBoy) {
          userObj.deliveryBoy = deliveryBoy._id.toString();
        } else {
          userObj.deliveryBoy = null;
        }
      } catch (error) {
        console.error('Error finding delivery boy:', error);
        userObj.deliveryBoy = null;
      }
    }

    // Remove any mongoose-specific fields
    delete userObj.__v;
    delete userObj._id; // We'll use id instead
    
    // Add id field if not present
    if (!userObj.id) {
      userObj.id = user._id.toString();
    }

    res.status(200).json({
      success: true,
      data: userObj
    });
  } catch (error) {
    console.error('Error in getMe:', error);
    next(error);
  }
};

// @desc    Reset password
// @route   PUT /api/v1/auth/reset-password/:token
// @access  Public
exports.resetPassword = async (req, res, next) => {
  try {
    // Get hashed token
    const resetPasswordToken = crypto
      .createHash('sha256')
      .update(req.params.token)
      .digest('hex');

    const user = await User.findOne({
      resetPasswordToken,
      resetPasswordExpire: { $gt: Date.now() }
    });

    if (!user) {
      return next(new BadRequestError('Invalid or expired token'));
    }

    // Set new password
    user.password = req.body.password;
    user.resetPasswordToken = undefined;
    user.resetPasswordExpire = undefined;
    
    await user.save();

    sendTokenResponse(user, 200, res);
  } catch (error) {
    next(error);
  }
};

// @desc    Update user password
// @route   PUT /api/v1/auth/update-password
// @access  Private
exports.updatePassword = async (req, res, next) => {
  try {
    // Get user from the token
    const user = await User.findById(req.user.id).select('+password');

    // Check current password
    if (!(await user.matchPassword(req.body.currentPassword))) {
      return next(new UnauthorizedError('Current password is incorrect'));
    }

    // Update password
    user.password = req.body.newPassword;
    await user.save();

    sendTokenResponse(user, 200, res);
  } catch (error) {
    next(error);
  }
};

// @desc    Logout user / clear cookie
// @route   POST /api/v1/auth/logout
// @access  Private
exports.logout = async (req, res, next) => {
  try {
    // In a token-based auth system, logout is handled client-side by removing the token
    // This endpoint is provided for consistency and to handle any server-side cleanup if needed
    
    res.status(200).json({
      success: true,
      data: {}
    });
  } catch (error) {
    next(error);
  }
};

// @desc    Register a new delivery boy
// @route   POST /api/v1/auth/delivery-boy/register
// @access  Public
exports.deliveryBoyRegister = async (req, res, next) => {
  try {
    const { name, email, phone, password, store, address } = req.body;

    // Check if delivery boy already exists
    const existingDeliveryBoy = await DeliveryBoy.findOne({ 
      $or: [{ email }, { phone }] 
    });

    if (existingDeliveryBoy) {
      return next(new BadRequestError('Delivery boy with this email or phone already exists'));
    }

    // Create delivery boy
    const deliveryBoy = await DeliveryBoy.create({
      name,
      email,
      phone,
      password,
      store,
      address,
      status: 'pending', // Default status is pending until approved by admin
      isAvailable: false
    });

    // Create token
    const token = deliveryBoy.getSignedJwtToken();

    res.status(201).json({
      success: true,
      token,
      data: {
        id: deliveryBoy._id,
        name: deliveryBoy.name,
        email: deliveryBoy.email,
        phone: deliveryBoy.phone,
        status: deliveryBoy.status,
        isAvailable: deliveryBoy.isAvailable
      }
    });
  } catch (error) {
    next(error);
  }
};

// @desc    Login delivery boy
// @route   POST /api/v1/auth/delivery-boy/login
// @access  Public
exports.deliveryBoyLogin = async (req, res, next) => {
  try {
    const { email, password } = req.body;

    // Validate email & password
    if (!email || !password) {
      return next(new BadRequestError('Please provide email and password'));
    }

    // Check for delivery boy
    const deliveryBoy = await DeliveryBoy.findOne({ email }).select('+password');

    if (!deliveryBoy) {
      return next(new UnauthorizedError('Invalid credentials'));
    }

    // Check if password matches
    const isMatch = await deliveryBoy.matchPassword(password);

    if (!isMatch) {
      return next(new UnauthorizedError('Invalid credentials'));
    }

    // Check if delivery boy is approved
    if (deliveryBoy.status !== 'approved') {
      return next(new UnauthorizedError('Your account is not approved yet. Please contact admin.'));
    }

    // Update last online
    deliveryBoy.lastOnline = Date.now();
    await deliveryBoy.save({ validateBeforeSave: false });

    // Create token
    const token = deliveryBoy.getSignedJwtToken();

    res.status(200).json({
      success: true,
      token,
      data: {
        id: deliveryBoy._id,
        name: deliveryBoy.name,
        email: deliveryBoy.email,
        phone: deliveryBoy.phone,
        status: deliveryBoy.status,
        isAvailable: deliveryBoy.isAvailable
      }
    });
  } catch (error) {
    next(error);
  }
};

// @desc    Get current logged in delivery boy
// @route   GET /api/v1/auth/delivery-boy/me
// @access  Private/DeliveryBoy
exports.getDeliveryBoyMe = async (req, res, next) => {
  try {
    const deliveryBoy = await DeliveryBoy.findById(req.user.id).select('-password');
    
    if (!deliveryBoy) {
      return next(new UnauthorizedError('No delivery boy found with this ID'));
    }

    // Update last online
    deliveryBoy.lastOnline = Date.now();
    await deliveryBoy.save({ validateBeforeSave: false });

    res.status(200).json({
      success: true,
      data: deliveryBoy
    });
  } catch (error) {
    next(error);
  }
};
