const Address = require('../models/Address');
const { validationResult } = require('express-validator');

// @desc    Get all addresses for a user
// @route   GET /api/addresses
// @access  Private
exports.getUserAddresses = async (req, res) => {
  try {
    // Assuming req.user.id is set by authentication middleware
    const addresses = await Address.getUserAddresses(req.user.id);
    res.json({ success: true, data: addresses });
  } catch (error) {
    console.error('Error fetching user addresses:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

// @desc    Create or update address for a user
// @route   POST /api/addresses
// @access  Private
exports.createOrUpdateAddress = async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ success: false, errors: errors.array() });
  }

  try {
    // Prepare address data
    const addressData = {
      name: req.body.name,
      contactNumber: req.body.contactNumber,
      country: req.body.country || 'India',
      state: req.body.state,
      city: req.body.city,
      postcode: req.body.postcode,
      address: req.body.address,
      landmark: req.body.landmark || '',
      type: req.body.type || 'home',
      isDefault: req.body.isDefault || false,
      location: {
        type: 'Point',
        coordinates: [
          parseFloat(req.body.longitude || 0),
          parseFloat(req.body.latitude || 0)
        ]
      }
    };

    // Create or update address for the user
    const newAddress = await Address.createOrUpdateAddress(req.user.id, addressData);

    // If this is set as default, update other addresses
    if (newAddress.isDefault) {
      await Address.setDefaultAddress(req.user.id, newAddress._id);
    }

    res.status(201).json({ 
      success: true, 
      data: newAddress,
      msg: newAddress._id ? 'Address updated successfully' : 'Address created successfully'
    });
  } catch (error) {
    console.error('Error creating/updating address:', error);
    res.status(500).json({ 
      success: false, 
      msg: 'Error creating/updating address',
      error: process.env.NODE_ENV === 'development' ? error.message : undefined
    });
  }
};

// @desc    Set default address
// @route   PUT /api/addresses/:id/default
// @access  Private
exports.setDefaultAddress = async (req, res) => {
  try {
    const address = await Address.findById(req.params.id);
    
    if (!address || address.user.toString() !== req.user.id) {
      return res.status(404).json({ success: false, msg: 'Address not found' });
    }
    
    const updatedAddress = await Address.setDefaultAddress(req.user.id, req.params.id);
    
    res.json({ 
      success: true, 
      data: updatedAddress,
      msg: 'Default address updated successfully' 
    });
  } catch (error) {
    console.error('Error setting default address:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

// @desc    Get all addresses
// @route   GET /api/addresses
// @access  Private/Admin
exports.getAddresses = async (req, res) => {
  try {
    const addresses = await Address.findAll();
    res.json({ success: true, data: addresses });
  } catch (error) {
    console.error('Error fetching addresses:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

// @desc    Get single address by ID
// @route   GET /api/addresses/:id
// @access  Private
exports.getAddress = async (req, res) => {
  try {
    const address = await Address.findById(req.params.id);
    
    if (!address) {
      return res.status(404).json({ success: false, msg: 'Address not found' });
    }
    
    res.json({ success: true, data: address });
  } catch (error) {
    console.error('Error fetching address:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

// @desc    Create new address
// @route   POST /api/addresses
// @access  Private
exports.createAddress = async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ success: false, errors: errors.array() });
  }

  try {
    const newAddress = await Address.create(req.body);
    res.status(201).json({ success: true, data: newAddress });
  } catch (error) {
    console.error('Error creating address:', error);
    res.status(500).json({ success: false, msg: 'Error creating address' });
  }
};

// @desc    Update address
// @route   PUT /api/addresses/:id
// @access  Private
exports.updateAddress = async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ success: false, errors: errors.array() });
  }

  try {
    const address = await Address.findById(req.params.id);
    
    if (!address) {
      return res.status(404).json({ success: false, msg: 'Address not found' });
    }
    
    const updated = await Address.update(req.params.id, req.body);
    
    if (!updated) {
      return res.status(400).json({ success: false, msg: 'Error updating address' });
    }
    
    const updatedAddress = await Address.findById(req.params.id);
    res.json({ success: true, data: updatedAddress });
  } catch (error) {
    console.error('Error updating address:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

// @desc    Delete address
// @route   DELETE /api/addresses/:id
// @access  Private/Admin
exports.deleteAddress = async (req, res) => {
  try {
    const address = await Address.findById(req.params.id);
    
    if (!address) {
      return res.status(404).json({ success: false, msg: 'Address not found' });
    }
    
    await Address.delete(req.params.id);
    
    res.json({ success: true, msg: 'Address removed' });
  } catch (error) {
    console.error('Error deleting address:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};
