const Ride = require('../models/Ride');
const User = require('../models/user');
const RideRequest = require('../models/RideRequest');

/**
 * @desc    Crea un nuovo viaggio (offerta o richiesta)
 * @route   POST /api/trasporti/rides
 * @access  Private
 */
const createRide = async (req, res) => {
  try {
    const { idapp } = req.body;
    const userId = req.user._id;

    const {
      type,
      departure,
      destination,
      waypoints,
      dateTime,
      flexibleTime,
      flexibleMinutes,
      recurrence,
      passengers,
      seatsNeeded,
      vehicle,
      preferences,
      contribution,
      notes
    } = req.body;

    // Validazione base
    if (!type || !['offer', 'request'].includes(type)) {
      return res.status(400).json({
        success: false,
        message: 'Tipo viaggio non valido. Usa "offer" o "request"'
      });
    }

    if (!departure || !departure.city || !departure.coordinates) {
      return res.status(400).json({
        success: false,
        message: 'Città di partenza richiesta con coordinate'
      });
    }

    if (!destination || !destination.city || !destination.coordinates) {
      return res.status(400).json({
        success: false,
        message: 'Città di destinazione richiesta con coordinate'
      });
    }

    if (!dateTime) {
      return res.status(400).json({
        success: false,
        message: 'Data e ora di partenza richieste'
      });
    }

    // Validazioni specifiche per offerta
    if (type === 'offer') {
      if (!passengers || !passengers.max || passengers.max < 1) {
        return res.status(400).json({
          success: false,
          message: 'Numero massimo passeggeri richiesto per le offerte'
        });
      }
    }

    // Ordina waypoints se presenti
    let orderedWaypoints = [];
    if (waypoints && waypoints.length > 0) {
      orderedWaypoints = waypoints.map((wp, index) => ({
        ...wp,
        order: wp.order !== undefined ? wp.order : index + 1
      }));
    }

    // Prepara i dati del viaggio
    const rideData = {
      idapp,
      userId,
      type,
      departure,
      destination,
      waypoints: orderedWaypoints,
      dateTime: new Date(dateTime),
      flexibleTime: flexibleTime || false,
      flexibleMinutes: flexibleMinutes || 30,
      recurrence: recurrence || { type: 'once' },
      preferences: preferences || {},
      contribution: contribution || { contribTypes: [] },
      notes,
      status: 'active'
    };

    // Aggiungi campi specifici per tipo
    if (type === 'offer') {
      rideData.passengers = {
        available: passengers.max,
        max: passengers.max
      };
      rideData.vehicle = vehicle || {};
    } else {
      rideData.seatsNeeded = seatsNeeded || 1;
    }

    const ride = new Ride(rideData);
    await ride.save();

    // Aggiorna profilo utente come driver se è un'offerta
    if (type === 'offer') {
      await User.findByIdAndUpdate(userId, {
        'profile.driverProfile.isDriver': true
      });
    }

    // Popola i dati per la risposta
    await ride.populate('userId', 'username name surname profile.img profile.driverProfile.averageRating');

    res.status(201).json({
      success: true,
      message: type === 'offer' ? 'Offerta passaggio creata!' : 'Richiesta passaggio creata!',
      data: ride
    });

  } catch (error) {
    console.error('Errore creazione viaggio:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante la creazione del viaggio',
      error: error.message
    });
  }
};

/**
 * @desc    Ottieni lista viaggi con filtri
 * @route   GET /api/trasporti/rides
 * @access  Public
 */
const getRides = async (req, res) => {
  try {
    const { idapp } = req.query;
    
    const {
      type,
      departureCity,
      destinationCity,
      date,
      dateFrom,
      dateTo,
      passingThrough,
      minSeats,
      preferences,
      contribTypes,
      status,
      page = 1,
      limit = 20,
      sortBy = 'dateTime',
      sortOrder = 'asc'
    } = req.query;

    // Costruisci query
    const query = {
      idapp,
      status: status ? status : { $in: ['active', 'full'] },
      dateTime: { $gte: new Date() }
    };

    // Filtro tipo
    if (type && ['offer', 'request'].includes(type)) {
      query.type = type;
    }

    // Filtro città partenza
    if (departureCity) {
      query['departure.city'] = new RegExp(departureCity, 'i');
    }

    // Filtro città destinazione
    if (destinationCity) {
      query['destination.city'] = new RegExp(destinationCity, 'i');
    }

    // Filtro data specifica
    if (date) {
      const startOfDay = new Date(date);
      startOfDay.setHours(0, 0, 0, 0);
      const endOfDay = new Date(date);
      endOfDay.setHours(23, 59, 59, 999);
      query.dateTime = { $gte: startOfDay, $lte: endOfDay };
    }

    // Filtro range date
    if (dateFrom || dateTo) {
      query.dateTime = {};
      if (dateFrom) query.dateTime.$gte = new Date(dateFrom);
      if (dateTo) query.dateTime.$lte = new Date(dateTo);
    }

    // Filtro posti minimi disponibili
    if (minSeats) {
      query['passengers.available'] = { $gte: parseInt(minSeats) };
    }

    // Filtro preferenze
    if (preferences) {
      try {
        const prefs = JSON.parse(preferences);
        if (prefs.smoking !== undefined) {
          query['preferences.smoking'] = prefs.smoking;
        }
        if (prefs.pets) {
          query['preferences.pets'] = { $in: ['all', prefs.pets] };
        }
        if (prefs.packages !== undefined) {
          query['preferences.packages'] = prefs.packages;
        }
      } catch (e) {
        // Ignora errori parsing preferenze
      }
    }

    // Paginazione
    const skip = (parseInt(page) - 1) * parseInt(limit);
    const sortOptions = {};
    sortOptions[sortBy] = sortOrder === 'desc' ? -1 : 1;

    // Query per città di passaggio (più complessa)
    let rides;
    if (passingThrough) {
      const cityRegex = new RegExp(passingThrough, 'i');
      query.$or = [
        { 'departure.city': cityRegex },
        { 'destination.city': cityRegex },
        { 'waypoints.location.city': cityRegex }
      ];
    }

    rides = await Ride.find(query)
      .populate('userId', 'username name surname profile.img profile.driverProfile.averageRating profile.driverProfile.ridesCompletedAsDriver')
      .populate('contribution.contribTypes.contribTypeId')
      .sort(sortOptions)
      .skip(skip)
      .limit(parseInt(limit));

    // Conta totale per paginazione
    const total = await Ride.countDocuments(query);

    res.status(200).json({
      success: true,
      data: rides,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / parseInt(limit))
      }
    });

  } catch (error) {
    console.error('Errore recupero viaggi:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante il recupero dei viaggi',
      error: error.message
    });
  }
};

/**
 * @desc    Ottieni singolo viaggio per ID
 * @route   GET /api/trasporti/rides/:id
 * @access  Public
 */
const getRideById = async (req, res) => {
  try {
    const { id } = req.params;
    const { idapp } = req.query;

    const ride = await Ride.findOne({ _id: id, idapp })
      .populate('userId', 'username name surname profile.img profile.Biografia profile.driverProfile')
      .populate('confirmedPassengers.userId', 'username name surname profile.img')
      .populate('contribution.contribTypes.contribTypeId');

    if (!ride) {
      return res.status(404).json({
        success: false,
        message: 'Viaggio non trovato'
      });
    }

    // Incrementa visualizzazioni
    ride.views += 1;
    await ride.save();

    res.status(200).json({
      success: true,
      data: ride
    });

  } catch (error) {
    console.error('Errore recupero viaggio:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante il recupero del viaggio',
      error: error.message
    });
  }
};

/**
 * @desc    Aggiorna un viaggio
 * @route   PUT /api/trasporti/rides/:id
 * @access  Private
 */
const updateRide = async (req, res) => {
  try {
    const { id } = req.params;
    const userId = req.user._id;
    const { idapp, ...updateData } = req.body;

    // Trova il viaggio
    const ride = await Ride.findOne({ _id: id, idapp });

    if (!ride) {
      return res.status(404).json({
        success: false,
        message: 'Viaggio non trovato'
      });
    }

    // Verifica proprietario
    if (ride.userId.toString() !== userId) {
      return res.status(403).json({
        success: false,
        message: 'Non sei autorizzato a modificare questo viaggio'
      });
    }

    // Non permettere modifiche se ci sono passeggeri confermati
    if (ride.confirmedPassengers && ride.confirmedPassengers.length > 0) {
      // Permetti solo alcune modifiche
      const allowedFields = ['notes', 'preferences', 'flexibleTime', 'flexibleMinutes'];
      const updateKeys = Object.keys(updateData);
      const hasDisallowedFields = updateKeys.some(key => !allowedFields.includes(key));
      
      if (hasDisallowedFields) {
        return res.status(400).json({
          success: false,
          message: 'Non puoi modificare percorso/orario con passeggeri confermati. Contattali prima.'
        });
      }
    }

    // Campi non modificabili
    delete updateData.userId;
    delete updateData.confirmedPassengers;
    delete updateData.status;

    // Aggiorna waypoints con ordine
    if (updateData.waypoints) {
      updateData.waypoints = updateData.waypoints.map((wp, index) => ({
        ...wp,
        order: wp.order !== undefined ? wp.order : index + 1
      }));
    }

    // Aggiorna posti disponibili se cambiano i max
    if (updateData.passengers && updateData.passengers.max) {
      const bookedSeats = ride.confirmedPassengers.reduce((sum, p) => sum + (p.seats || 1), 0);
      updateData.passengers.available = updateData.passengers.max - bookedSeats;
    }

    const updatedRide = await Ride.findByIdAndUpdate(
      id,
      { $set: updateData },
      { new: true, runValidators: true }
    )
    .populate('userId', 'username name surname profile.img')
    .populate('contribution.contribTypes.contribTypeId');

    res.status(200).json({
      success: true,
      message: 'Viaggio aggiornato con successo',
      data: updatedRide
    });

  } catch (error) {
    console.error('Errore aggiornamento viaggio:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante l\'aggiornamento del viaggio',
      error: error.message
    });
  }
};

/**
 * @desc    Cancella un viaggio
 * @route   DELETE /api/trasporti/rides/:id
 * @access  Private
 */
const deleteRide = async (req, res) => {
  try {
    const { id } = req.params;
    const userId = req.user._id;
    const { idapp, reason } = req.body;

    const ride = await Ride.findOne({ _id: id, idapp });

    if (!ride) {
      return res.status(404).json({
        success: false,
        message: 'Viaggio non trovato'
      });
    }

    // Verifica proprietario
    if (ride.userId.toString() !== userId) {
      return res.status(403).json({
        success: false,
        message: 'Non sei autorizzato a cancellare questo viaggio'
      });
    }

    // Se ci sono passeggeri confermati, notifica invece di eliminare
    if (ride.confirmedPassengers && ride.confirmedPassengers.length > 0) {
      // Aggiorna le richieste associate
      await RideRequest.updateMany(
        { rideId: id, status: 'accepted' },
        { 
          status: 'cancelled',
          cancelledBy: 'driver',
          cancellationReason: reason || 'Viaggio cancellato dal conducente',
          cancelledAt: new Date()
        }
      );
    }

    // Soft delete - cambia stato invece di eliminare
    ride.status = 'cancelled';
    ride.cancellationReason = reason;
    ride.cancelledAt = new Date();
    await ride.save();

    res.status(200).json({
      success: true,
      message: 'Viaggio cancellato con successo'
    });

  } catch (error) {
    console.error('Errore cancellazione viaggio:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante la cancellazione del viaggio',
      error: error.message
    });
  }
};

/**
 * @desc    Ottieni viaggi dell'utente corrente
 * @route   GET /api/trasporti/rides/my
 * @access  Private
 */
const getMyRides = async (req, res) => {
  try {
    const userId = req.user._id;
    const { idapp, type, role, status, page = 1, limit = 20 } = req.query;

    let query = { idapp };
    
    if (role === 'driver') {
      // Viaggi dove sono il conducente
      query.userId = userId;
    } else if (role === 'passenger') {
      // Viaggi dove sono passeggero confermato
      query['confirmedPassengers.userId'] = userId;
    } else {
      // Tutti i miei viaggi (come driver o passenger)
      query.$or = [
        { userId },
        { 'confirmedPassengers.userId': userId }
      ];
    }

    if (type) {
      query.type = type;
    }

    if (status) {
      query.status = status;
    }

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

    const rides = await Ride.find(query)
      .populate('userId', 'username name surname profile.img profile.driverProfile.averageRating')
      .populate('confirmedPassengers.userId', 'username name surname profile.img')
      .populate('contribution.contribTypes.contribTypeId')
      .sort({ dateTime: -1 })
      .skip(skip)
      .limit(parseInt(limit));

    const total = await Ride.countDocuments(query);

    // Separa in passati e futuri
    const now = new Date();
    const upcoming = rides.filter(r => new Date(r.dateTime) >= now);
    const past = rides.filter(r => new Date(r.dateTime) < now);

    res.status(200).json({
      success: true,
      data: {
        all: rides,
        upcoming,
        past
      },
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / parseInt(limit))
      }
    });

  } catch (error) {
    console.error('Errore recupero miei viaggi:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante il recupero dei tuoi viaggi',
      error: error.message
    });
  }
};

/**
 * @desc    Cerca viaggi con match intelligente
 * @route   GET /api/trasporti/rides/search
 * @access  Public
 */
const searchRides = async (req, res) => {
  try {
    const { idapp } = req.query;
    
    const {
      from,
      to,
      date,
      seats = 1,
      type = 'offer',
      radius = 20, // km di raggio per ricerca geografica
      page = 1,
      limit = 20
    } = req.query;

    if (!from && !to) {
      return res.status(400).json({
        success: false,
        message: 'Specifica almeno una città di partenza o destinazione'
      });
    }

    const query = {
      idapp,
      type,
      status: 'active',
      dateTime: { $gte: new Date() }
    };

    // Costruisci condizioni di ricerca
    const orConditions = [];

    if (from) {
      const fromRegex = new RegExp(from, 'i');
      orConditions.push({ 'departure.city': fromRegex });
      orConditions.push({ 'waypoints.location.city': fromRegex });
    }

    if (to) {
      const toRegex = new RegExp(to, 'i');
      orConditions.push({ 'destination.city': toRegex });
      orConditions.push({ 'waypoints.location.city': toRegex });
    }

    // Se ci sono condizioni OR
    if (orConditions.length > 0) {
      if (from && to) {
        // Deve matchare sia partenza che destinazione (anche waypoints)
        const fromRegex = new RegExp(from, 'i');
        const toRegex = new RegExp(to, 'i');
        query.$and = [
          {
            $or: [
              { 'departure.city': fromRegex },
              { 'waypoints.location.city': fromRegex }
            ]
          },
          {
            $or: [
              { 'destination.city': toRegex },
              { 'waypoints.location.city': toRegex }
            ]
          }
        ];
      } else {
        query.$or = orConditions;
      }
    }

    // Filtro data
    if (date) {
      const startOfDay = new Date(date);
      startOfDay.setHours(0, 0, 0, 0);
      const endOfDay = new Date(date);
      endOfDay.setHours(23, 59, 59, 999);
      query.dateTime = { $gte: startOfDay, $lte: endOfDay };
    }

    // Filtro posti
    if (type === 'offer') {
      query['passengers.available'] = { $gte: parseInt(seats) };
    }

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

    const rides = await Ride.find(query)
      .populate('userId', 'username name surname profile.img profile.driverProfile.averageRating profile.driverProfile.ridesCompletedAsDriver')
      .populate('contribution.contribTypes.contribTypeId')
      .sort({ dateTime: 1 })
      .skip(skip)
      .limit(parseInt(limit));

    const total = await Ride.countDocuments(query);

    res.status(200).json({
      success: true,
      data: rides,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / parseInt(limit))
      }
    });

  } catch (error) {
    console.error('Errore ricerca viaggi:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante la ricerca dei viaggi',
      error: error.message
    });
  }
};

/**
 * @desc    Completa un viaggio
 * @route   POST /api/trasporti/rides/:id/complete
 * @access  Private
 */
const completeRide = async (req, res) => {
  try {
    const { id } = req.params;
    const userId = req.user._id;
    const { idapp } = req.body;

    const ride = await Ride.findOne({ _id: id, idapp });

    if (!ride) {
      return res.status(404).json({
        success: false,
        message: 'Viaggio non trovato'
      });
    }

    if (ride.userId.toString() !== userId) {
      return res.status(403).json({
        success: false,
        message: 'Solo il conducente può completare il viaggio'
      });
    }

    ride.status = 'completed';
    await ride.save();

    // Aggiorna contatori utente
    await User.findByIdAndUpdate(userId, {
      $inc: { 'profile.driverProfile.ridesCompletedAsDriver': 1 }
    });

    // Aggiorna contatori passeggeri
    const passengerIds = ride.confirmedPassengers.map(p => p.userId);
    await User.updateMany(
      { _id: { $in: passengerIds } },
      { $inc: { 'profile.driverProfile.ridesCompletedAsPassenger': 1 } }
    );

    // Aggiorna richieste associate
    await RideRequest.updateMany(
      { rideId: id, status: 'accepted' },
      { status: 'completed', completedAt: new Date() }
    );

    res.status(200).json({
      success: true,
      message: 'Viaggio completato! Ora puoi lasciare un feedback.',
      data: ride
    });

  } catch (error) {
    console.error('Errore completamento viaggio:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante il completamento del viaggio',
      error: error.message
    });
  }
};

/**
 * @desc    Ottieni statistiche viaggi per homepage widget
 * @route   GET /api/trasporti/rides/stats
 * @access  Private
 */
const getRidesStats = async (req, res) => {
  try {
    const { idapp } = req.query;
    const userId = req.user._id;

    const now = new Date();

    // Statistiche generali
    const [
      totalActiveOffers,
      totalActiveRequests,
      todayRides,
      myUpcomingAsDriver,
      myUpcomingAsPassenger,
      pendingRequests
    ] = await Promise.all([
      // Offerte attive
      Ride.countDocuments({ idapp, type: 'offer', status: 'active', dateTime: { $gte: now } }),
      // Richieste attive
      Ride.countDocuments({ idapp, type: 'request', status: 'active', dateTime: { $gte: now } }),
      // Viaggi di oggi
      Ride.countDocuments({
        idapp,
        status: { $in: ['active', 'full'] },
        dateTime: {
          $gte: new Date(now.setHours(0, 0, 0, 0)),
          $lte: new Date(now.setHours(23, 59, 59, 999))
        }
      }),
      // I miei prossimi come conducente
      Ride.countDocuments({ idapp, userId, status: { $in: ['active', 'full'] }, dateTime: { $gte: new Date() } }),
      // I miei prossimi come passeggero
      Ride.countDocuments({ idapp, 'confirmedPassengers.userId': userId, status: { $in: ['active', 'full'] }, dateTime: { $gte: new Date() } }),
      // Richieste in attesa per me
      RideRequest.countDocuments({ idapp, driverId: userId, status: 'pending' })
    ]);

    // Ultimi viaggi attivi
    const recentRides = await Ride.find({
      idapp,
      status: 'active',
      dateTime: { $gte: new Date() }
    })
    .populate('userId', 'username name profile.img')
    .sort({ createdAt: -1 })
    .limit(5);

    res.status(200).json({
      success: true,
      data: {
        stats: {
          totalActiveOffers,
          totalActiveRequests,
          todayRides,
          myUpcomingAsDriver,
          myUpcomingAsPassenger,
          pendingRequests
        },
        recentRides
      }
    });

  } catch (error) {
    console.error('Errore recupero statistiche:', error);
    res.status(500).json({
      success: false,
      message: 'Errore durante il recupero delle statistiche',
      error: error.message
    });
  }
};

/**
 * Get aggregated data for dashboard widgets
 * GET /api/trasporti/widget/data
 */
const getWidgetData = async (req, res) => {
  try {
    const userId = req.user._id;
    const now = new Date();
    const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);

    // Parallel queries for efficiency
    const [
      myActiveRides,
      myUpcomingRides,
      myPastRidesCount,
      myActiveRequests,
      pendingRequestsForMyRides,
      recentFeedback,
      unreadMessages
    ] = await Promise.all([
      // Active rides as driver
      Ride.countDocuments({
        driverId: userId,
        status: 'active',
        departureDate: { $gte: now }
      }),

      // Upcoming rides as passenger (accepted requests)
      RideRequest.countDocuments({
        userId: userId,
        status: 'accepted',
        'rideInfo.departureDate': { $gte: now }
      }),

      // Past rides in last 30 days
      Ride.countDocuments({
        $or: [
          { driverId: userId },
          { 'passengers.userId': userId }
        ],
        status: 'completed',
        departureDate: { $gte: thirtyDaysAgo, $lt: now }
      }),

      // My active requests (pending/accepted)
      RideRequest.countDocuments({
        userId: userId,
        status: { $in: ['pending', 'accepted'] }
      }),

      // Pending requests for my rides
      RideRequest.countDocuments({
        driverId: userId,
        status: 'pending'
      }),

      // Recent feedback (last 7 days)
      Feedback.find({
        toUserId: userId,
        createdAt: { $gte: new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000) }
      })
        .select('rating createdAt')
        .sort({ createdAt: -1 })
        .limit(5)
        .lean(),

      // Unread messages count
      Chat.countDocuments({
        participants: userId,
        'lastMessage.senderId': { $ne: userId },
        [`unreadCount.${userId}`]: { $gt: 0 }
      })
    ]);

    // Calculate average recent rating
    const avgRecentRating = recentFeedback.length > 0
      ? recentFeedback.reduce((sum, f) => sum + f.rating, 0) / recentFeedback.length
      : null;

    // Get trending routes (most searched in last 7 days)
    const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
    const trendingRoutes = await Ride.aggregate([
      {
        $match: {
          createdAt: { $gte: sevenDaysAgo },
          status: { $in: ['active', 'completed'] }
        }
      },
      {
        $group: {
          _id: {
            departure: '$departure.city',
            destination: '$destination.city'
          },
          count: { $sum: 1 }
        }
      },
      {
        $sort: { count: -1 }
      },
      {
        $limit: 3
      },
      {
        $project: {
          _id: 0,
          departure: '$_id.departure',
          destination: '$_id.destination',
          count: 1
        }
      }
    ]);

    // Get user stats
    const userStats = await Feedback.aggregate([
      {
        $match: { toUserId: userId }
      },
      {
        $group: {
          _id: null,
          averageRating: { $avg: '$rating' },
          totalFeedbacks: { $sum: 1 }
        }
      }
    ]);

    const stats = userStats[0] || { averageRating: 0, totalFeedbacks: 0 };

    // Prepare widget data
    const widgetData = {
      overview: {
        activeRides: myActiveRides,
        upcomingTrips: myUpcomingRides,
        pastRidesThisMonth: myPastRidesCount,
        activeRequests: myActiveRequests
      },
      notifications: {
        pendingRequests: pendingRequestsForMyRides,
        unreadMessages: unreadMessages,
        newFeedbacks: recentFeedback.length
      },
      userStats: {
        averageRating: stats.averageRating ? parseFloat(stats.averageRating.toFixed(1)) : null,
        totalFeedbacks: stats.totalFeedbacks,
        recentRating: avgRecentRating ? parseFloat(avgRecentRating.toFixed(1)) : null
      },
      trending: {
        routes: trendingRoutes
      },
      quickActions: {
        hasVehicle: false, // Will be populated if vehicle model exists
        canCreateRide: myActiveRides < 5, // Limit active rides
        hasCompletedProfile: true // Could check user profile completeness
      }
    };

    // Optional: Check if user has a vehicle (if Vehicle model exists)
    try {
      const Vehicle = require('../models/Vehicle');
      const hasVehicle = await Vehicle.exists({ userId: userId });
      widgetData.quickActions.hasVehicle = !!hasVehicle;
    } catch (err) {
      // Vehicle model doesn't exist or error - skip
    }

    return res.status(200).json({
      success: true,
      data: widgetData
    });

  } catch (error) {
    console.error('Error getting widget data:', error);
    return res.status(500).json({
      success: false,
      message: 'Errore nel caricamento dei dati del widget',
      error: error.message
    });
  }
};

/**
 * Get comprehensive statistics summary for user
 * GET /api/trasporti/stats/summary
 */
const getStatsSummary = async (req, res) => {
  try {
    const userId = req.user._id;
    const now = new Date();
    
    // Time periods
    const thisMonth = new Date(now.getFullYear(), now.getMonth(), 1);
    const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
    const thisYear = new Date(now.getFullYear(), 0, 1);
    const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);

    // Parallel queries for all statistics
    const [
      ridesAsDriver,
      ridesAsPassenger,
      totalDistance,
      feedback,
      monthlyRides,
      yearlyRides,
      recentActivity,
      vehicleStats,
      savingsEstimate
    ] = await Promise.all([
      // Rides as driver
      Ride.aggregate([
        {
          $match: {
            driverId: userId,
            status: 'completed'
          }
        },
        {
          $group: {
            _id: null,
            total: { $sum: 1 },
            thisMonth: {
              $sum: {
                $cond: [{ $gte: ['$departureDate', thisMonth] }, 1, 0]
              }
            },
            lastMonth: {
              $sum: {
                $cond: [
                  {
                    $and: [
                      { $gte: ['$departureDate', lastMonth] },
                      { $lt: ['$departureDate', thisMonth] }
                    ]
                  },
                  1,
                  0
                ]
              }
            },
            totalPassengers: { $sum: '$currentPassengers' }
          }
        }
      ]),

      // Rides as passenger
      RideRequest.aggregate([
        {
          $match: {
            userId: userId,
            status: 'completed'
          }
        },
        {
          $group: {
            _id: null,
            total: { $sum: 1 },
            thisMonth: {
              $sum: {
                $cond: [{ $gte: ['$createdAt', thisMonth] }, 1, 0]
              }
            }
          }
        }
      ]),

      // Total distance traveled
      Ride.aggregate([
        {
          $match: {
            $or: [
              { driverId: userId },
              { 'passengers.userId': userId }
            ],
            status: 'completed',
            distance: { $exists: true, $gt: 0 }
          }
        },
        {
          $group: {
            _id: null,
            totalKm: { $sum: '$distance' },
            avgDistance: { $avg: '$distance' }
          }
        }
      ]),

      // Feedback statistics
      Feedback.aggregate([
        {
          $match: { toUserId: userId }
        },
        {
          $facet: {
            overall: [
              {
                $group: {
                  _id: null,
                  avgRating: { $avg: '$rating' },
                  total: { $sum: 1 },
                  fiveStars: {
                    $sum: { $cond: [{ $eq: ['$rating', 5] }, 1, 0] }
                  },
                  fourStars: {
                    $sum: { $cond: [{ $eq: ['$rating', 4] }, 1, 0] }
                  },
                  threeStars: {
                    $sum: { $cond: [{ $eq: ['$rating', 3] }, 1, 0] }
                  }
                }
              }
            ],
            asDriver: [
              {
                $match: { toUserRole: 'driver' }
              },
              {
                $group: {
                  _id: null,
                  avgRating: { $avg: '$rating' },
                  total: { $sum: 1 }
                }
              }
            ],
            asPassenger: [
              {
                $match: { toUserRole: 'passenger' }
              },
              {
                $group: {
                  _id: null,
                  avgRating: { $avg: '$rating' },
                  total: { $sum: 1 }
                }
              }
            ],
            recent: [
              {
                $match: {
                  createdAt: { $gte: thirtyDaysAgo }
                }
              },
              {
                $group: {
                  _id: null,
                  avgRating: { $avg: '$rating' },
                  total: { $sum: 1 }
                }
              }
            ]
          }
        }
      ]),

      // Monthly breakdown (last 6 months)
      Ride.aggregate([
        {
          $match: {
            $or: [
              { driverId: userId },
              { 'passengers.userId': userId }
            ],
            status: 'completed',
            departureDate: {
              $gte: new Date(now.getFullYear(), now.getMonth() - 5, 1)
            }
          }
        },
        {
          $group: {
            _id: {
              year: { $year: '$departureDate' },
              month: { $month: '$departureDate' }
            },
            count: { $sum: 1 },
            asDriver: {
              $sum: {
                $cond: [{ $eq: ['$driverId', userId] }, 1, 0]
              }
            },
            asPassenger: {
              $sum: {
                $cond: [{ $ne: ['$driverId', userId] }, 1, 0]
              }
            }
          }
        },
        {
          $sort: { '_id.year': 1, '_id.month': 1 }
        }
      ]),

      // Yearly summary
      Ride.aggregate([
        {
          $match: {
            $or: [
              { driverId: userId },
              { 'passengers.userId': userId }
            ],
            status: 'completed',
            departureDate: { $gte: thisYear }
          }
        },
        {
          $group: {
            _id: null,
            total: { $sum: 1 },
            asDriver: {
              $sum: {
                $cond: [{ $eq: ['$driverId', userId] }, 1, 0]
              }
            },
            asPassenger: {
              $sum: {
                $cond: [{ $ne: ['$driverId', userId] }, 1, 0]
              }
            }
          }
        }
      ]),

      // Recent activity (last 30 days)
      Ride.find({
        $or: [
          { driverId: userId },
          { 'passengers.userId': userId }
        ],
        status: { $in: ['completed', 'active'] },
        departureDate: { $gte: thirtyDaysAgo }
      })
        .select('departure.city destination.city departureDate status')
        .sort({ departureDate: -1 })
        .limit(10)
        .lean(),

      // Vehicle statistics (if vehicle exists)
      (async () => {
        try {
          const Vehicle = require('../models/Vehicle');
          const vehicles = await Vehicle.find({ userId: userId }).lean();
          
          if (vehicles.length === 0) return null;

          const vehicleRides = await Ride.aggregate([
            {
              $match: {
                driverId: userId,
                vehicleId: { $exists: true },
                status: 'completed'
              }
            },
            {
              $group: {
                _id: '$vehicleId',
                totalRides: { $sum: 1 },
                totalKm: { $sum: '$distance' }
              }
            }
          ]);

          return {
            totalVehicles: vehicles.length,
            ridesPerVehicle: vehicleRides
          };
        } catch (err) {
          return null;
        }
      })(),

      // Estimated savings (CO2 and money)
      Ride.aggregate([
        {
          $match: {
            'passengers.userId': userId,
            status: 'completed',
            distance: { $exists: true, $gt: 0 }
          }
        },
        {
          $group: {
            _id: null,
            totalKm: { $sum: '$distance' },
            totalRides: { $sum: 1 }
          }
        }
      ])
    ]);

    // Process results
    const driverStats = ridesAsDriver[0] || { 
      total: 0, 
      thisMonth: 0, 
      lastMonth: 0, 
      totalPassengers: 0 
    };
    
    const passengerStats = ridesAsPassenger[0] || { 
      total: 0, 
      thisMonth: 0 
    };
    
    const distanceStats = totalDistance[0] || { 
      totalKm: 0, 
      avgDistance: 0 
    };
    
    const feedbackData = feedback[0] || {
      overall: [{ avgRating: 0, total: 0, fiveStars: 0, fourStars: 0, threeStars: 0 }],
      asDriver: [{ avgRating: 0, total: 0 }],
      asPassenger: [{ avgRating: 0, total: 0 }],
      recent: [{ avgRating: 0, total: 0 }]
    };

    const yearlyStats = yearlyRides[0] || { total: 0, asDriver: 0, asPassenger: 0 };

    // Calculate savings (assumptions: 0.15€/km fuel, 120g CO2/km)
    const savingsData = savingsEstimate[0] || { totalKm: 0, totalRides: 0 };
    const estimatedCO2Saved = Math.round(savingsData.totalKm * 120); // grams
    const estimatedMoneySaved = Math.round(savingsData.totalKm * 0.15 * 100) / 100; // euros

    // Calculate growth percentage
    const monthGrowth = driverStats.lastMonth > 0
      ? Math.round(((driverStats.thisMonth - driverStats.lastMonth) / driverStats.lastMonth) * 100)
      : 0;

    // Build response
    const summary = {
      overview: {
        totalRides: driverStats.total + passengerStats.total,
        asDriver: driverStats.total,
        asPassenger: passengerStats.total,
        totalPassengersTransported: driverStats.totalPassengers,
        totalDistance: Math.round(distanceStats.totalKm),
        avgDistance: Math.round(distanceStats.avgDistance)
      },

      thisMonth: {
        ridesAsDriver: driverStats.thisMonth,
        ridesAsPassenger: passengerStats.thisMonth,
        total: driverStats.thisMonth + passengerStats.thisMonth,
        growth: monthGrowth
      },

      thisYear: {
        total: yearlyStats.total,
        asDriver: yearlyStats.asDriver,
        asPassenger: yearlyStats.asPassenger
      },

      ratings: {
        overall: {
          average: feedbackData.overall[0]?.avgRating 
            ? parseFloat(feedbackData.overall[0].avgRating.toFixed(2)) 
            : 0,
          total: feedbackData.overall[0]?.total || 0,
          distribution: {
            fiveStars: feedbackData.overall[0]?.fiveStars || 0,
            fourStars: feedbackData.overall[0]?.fourStars || 0,
            threeStars: feedbackData.overall[0]?.threeStars || 0
          }
        },
        asDriver: {
          average: feedbackData.asDriver[0]?.avgRating 
            ? parseFloat(feedbackData.asDriver[0].avgRating.toFixed(2)) 
            : 0,
          total: feedbackData.asDriver[0]?.total || 0
        },
        asPassenger: {
          average: feedbackData.asPassenger[0]?.avgRating 
            ? parseFloat(feedbackData.asPassenger[0].avgRating.toFixed(2)) 
            : 0,
          total: feedbackData.asPassenger[0]?.total || 0
        },
        recent: {
          average: feedbackData.recent[0]?.avgRating 
            ? parseFloat(feedbackData.recent[0].avgRating.toFixed(2)) 
            : 0,
          total: feedbackData.recent[0]?.total || 0
        }
      },

      monthlyBreakdown: monthlyRides.map(m => ({
        month: m._id.month,
        year: m._id.year,
        total: m.count,
        asDriver: m.asDriver,
        asPassenger: m.asPassenger
      })),

      recentActivity: recentActivity.map(ride => ({
        id: ride._id,
        route: `${ride.departure.city} → ${ride.destination.city}`,
        date: ride.departureDate,
        status: ride.status
      })),

      impact: {
        co2Saved: estimatedCO2Saved, // grams
        moneySaved: estimatedMoneySaved, // euros
        ridesShared: savingsData.totalRides
      },

      vehicles: vehicleStats
    };

    return res.status(200).json({
      success: true,
      data: summary
    });

  } catch (error) {
    console.error('Error getting stats summary:', error);
    return res.status(500).json({
      success: false,
      message: 'Errore nel caricamento delle statistiche',
      error: error.message
    });
  }
};

/**
 * Get city suggestions for autocomplete
 * GET /api/trasporti/cities/suggestions?q=query
 */
const getCitySuggestions = async (req, res) => {
  try {
    const { q } = req.query;

    // Validate query
    if (!q || q.trim().length < 2) {
      return res.status(200).json({
        success: true,
        data: {
          suggestions: [],
          message: 'Inserisci almeno 2 caratteri per la ricerca'
        }
      });
    }

    const searchQuery = q.trim();
    const regex = new RegExp(`^${searchQuery}`, 'i'); // Case insensitive, starts with

    // Get popular cities from completed rides
    const popularCities = await Ride.aggregate([
      {
        $match: {
          status: { $in: ['active', 'completed'] },
          $or: [
            { 'departure.city': regex },
            { 'destination.city': regex }
          ]
        }
      },
      {
        $facet: {
          departures: [
            {
              $match: { 'departure.city': regex }
            },
            {
              $group: {
                _id: {
                  city: '$departure.city',
                  region: '$departure.region',
                  country: '$departure.country'
                },
                count: { $sum: 1 }
              }
            }
          ],
          destinations: [
            {
              $match: { 'destination.city': regex }
            },
            {
              $group: {
                _id: {
                  city: '$destination.city',
                  region: '$destination.region',
                  country: '$destination.country'
                },
                count: { $sum: 1 }
              }
            }
          ]
        }
      },
      {
        $project: {
          combined: {
            $concatArrays: ['$departures', '$destinations']
          }
        }
      },
      {
        $unwind: '$combined'
      },
      {
        $group: {
          _id: {
            city: '$combined._id.city',
            region: '$combined._id.region',
            country: '$combined._id.country'
          },
          totalCount: { $sum: '$combined.count' }
        }
      },
      {
        $sort: { totalCount: -1 }
      },
      {
        $limit: 10
      },
      {
        $project: {
          _id: 0,
          city: '$_id.city',
          region: '$_id.region',
          country: '$_id.country',
          popularity: '$totalCount'
        }
      }
    ]);

    // Italian cities database (fallback/supplement)
    const italianCities = [
      // Major cities
      { city: 'Roma', region: 'Lazio', country: 'Italia', type: 'major' },
      { city: 'Milano', region: 'Lombardia', country: 'Italia', type: 'major' },
      { city: 'Napoli', region: 'Campania', country: 'Italia', type: 'major' },
      { city: 'Torino', region: 'Piemonte', country: 'Italia', type: 'major' },
      { city: 'Palermo', region: 'Sicilia', country: 'Italia', type: 'major' },
      { city: 'Genova', region: 'Liguria', country: 'Italia', type: 'major' },
      { city: 'Bologna', region: 'Emilia-Romagna', country: 'Italia', type: 'major' },
      { city: 'Firenze', region: 'Toscana', country: 'Italia', type: 'major' },
      { city: 'Bari', region: 'Puglia', country: 'Italia', type: 'major' },
      { city: 'Catania', region: 'Sicilia', country: 'Italia', type: 'major' },
      { city: 'Venezia', region: 'Veneto', country: 'Italia', type: 'major' },
      { city: 'Verona', region: 'Veneto', country: 'Italia', type: 'major' },
      { city: 'Messina', region: 'Sicilia', country: 'Italia', type: 'major' },
      { city: 'Padova', region: 'Veneto', country: 'Italia', type: 'major' },
      { city: 'Trieste', region: 'Friuli-Venezia Giulia', country: 'Italia', type: 'major' },
      { city: 'Brescia', region: 'Lombardia', country: 'Italia', type: 'major' },
      { city: 'Parma', region: 'Emilia-Romagna', country: 'Italia', type: 'major' },
      { city: 'Prato', region: 'Toscana', country: 'Italia', type: 'major' },
      { city: 'Modena', region: 'Emilia-Romagna', country: 'Italia', type: 'major' },
      { city: 'Reggio Calabria', region: 'Calabria', country: 'Italia', type: 'major' },
      
      // Regional capitals
      { city: 'Ancona', region: 'Marche', country: 'Italia', type: 'capital' },
      { city: 'Aosta', region: 'Valle d\'Aosta', country: 'Italia', type: 'capital' },
      { city: 'Cagliari', region: 'Sardegna', country: 'Italia', type: 'capital' },
      { city: 'Campobasso', region: 'Molise', country: 'Italia', type: 'capital' },
      { city: 'Catanzaro', region: 'Calabria', country: 'Italia', type: 'capital' },
      { city: 'L\'Aquila', region: 'Abruzzo', country: 'Italia', type: 'capital' },
      { city: 'Perugia', region: 'Umbria', country: 'Italia', type: 'capital' },
      { city: 'Potenza', region: 'Basilicata', country: 'Italia', type: 'capital' },
      { city: 'Trento', region: 'Trentino-Alto Adige', country: 'Italia', type: 'capital' },
      
      // Other important cities
      { city: 'Bergamo', region: 'Lombardia', country: 'Italia', type: 'city' },
      { city: 'Bolzano', region: 'Trentino-Alto Adige', country: 'Italia', type: 'city' },
      { city: 'Como', region: 'Lombardia', country: 'Italia', type: 'city' },
      { city: 'Cremona', region: 'Lombardia', country: 'Italia', type: 'city' },
      { city: 'Ferrara', region: 'Emilia-Romagna', country: 'Italia', type: 'city' },
      { city: 'Forlì', region: 'Emilia-Romagna', country: 'Italia', type: 'city' },
      { city: 'Latina', region: 'Lazio', country: 'Italia', type: 'city' },
      { city: 'Lecce', region: 'Puglia', country: 'Italia', type: 'city' },
      { city: 'Livorno', region: 'Toscana', country: 'Italia', type: 'city' },
      { city: 'Lucca', region: 'Toscana', country: 'Italia', type: 'city' },
      { city: 'Mantova', region: 'Lombardia', country: 'Italia', type: 'city' },
      { city: 'Monza', region: 'Lombardia', country: 'Italia', type: 'city' },
      { city: 'Novara', region: 'Piemonte', country: 'Italia', type: 'city' },
      { city: 'Pavia', region: 'Lombardia', country: 'Italia', type: 'city' },
      { city: 'Pesaro', region: 'Marche', country: 'Italia', type: 'city' },
      { city: 'Pescara', region: 'Abruzzo', country: 'Italia', type: 'city' },
      { city: 'Piacenza', region: 'Emilia-Romagna', country: 'Italia', type: 'city' },
      { city: 'Pisa', region: 'Toscana', country: 'Italia', type: 'city' },
      { city: 'Ravenna', region: 'Emilia-Romagna', country: 'Italia', type: 'city' },
      { city: 'Reggio Emilia', region: 'Emilia-Romagna', country: 'Italia', type: 'city' },
      { city: 'Rimini', region: 'Emilia-Romagna', country: 'Italia', type: 'city' },
      { city: 'Salerno', region: 'Campania', country: 'Italia', type: 'city' },
      { city: 'Sassari', region: 'Sardegna', country: 'Italia', type: 'city' },
      { city: 'Siena', region: 'Toscana', country: 'Italia', type: 'city' },
      { city: 'Siracusa', region: 'Sicilia', country: 'Italia', type: 'city' },
      { city: 'Taranto', region: 'Puglia', country: 'Italia', type: 'city' },
      { city: 'Terni', region: 'Umbria', country: 'Italia', type: 'city' },
      { city: 'Treviso', region: 'Veneto', country: 'Italia', type: 'city' },
      { city: 'Udine', region: 'Friuli-Venezia Giulia', country: 'Italia', type: 'city' },
      { city: 'Varese', region: 'Lombardia', country: 'Italia', type: 'city' },
      { city: 'Vicenza', region: 'Veneto', country: 'Italia', type: 'city' }
    ];

    // Filter Italian cities by query
    const matchingItalianCities = italianCities
      .filter(c => c.city.toLowerCase().startsWith(searchQuery.toLowerCase()))
      .map(c => ({
        ...c,
        popularity: 0,
        source: 'database'
      }));

    // Merge results - prioritize cities from actual rides
    const cityMap = new Map();

    // Add popular cities from rides first
    popularCities.forEach(city => {
      const key = `${city.city}-${city.region}`.toLowerCase();
      cityMap.set(key, {
        ...city,
        source: 'rides',
        verified: true
      });
    });

    // Add Italian cities that aren't already in the map
    matchingItalianCities.forEach(city => {
      const key = `${city.city}-${city.region}`.toLowerCase();
      if (!cityMap.has(key)) {
        cityMap.set(key, city);
      }
    });

    // Convert to array and sort
    let suggestions = Array.from(cityMap.values());

    // Sort by: verified rides first, then by type (major > capital > city), then alphabetically
    suggestions.sort((a, b) => {
      // Prioritize cities from actual rides
      if (a.source === 'rides' && b.source !== 'rides') return -1;
      if (a.source !== 'rides' && b.source === 'rides') return 1;

      // Then by popularity
      if (a.popularity !== b.popularity) {
        return b.popularity - a.popularity;
      }

      // Then by type
      const typeOrder = { major: 0, capital: 1, city: 2 };
      const aType = typeOrder[a.type] ?? 3;
      const bType = typeOrder[b.type] ?? 3;
      if (aType !== bType) return aType - bType;

      // Finally alphabetically
      return a.city.localeCompare(b.city, 'it');
    });

    // Limit to 10 suggestions
    suggestions = suggestions.slice(0, 10);

    // Format suggestions
    const formattedSuggestions = suggestions.map(s => ({
      city: s.city,
      region: s.region,
      country: s.country || 'Italia',
      fullName: `${s.city}, ${s.region}`,
      popularity: s.popularity || 0,
      verified: s.verified || false
    }));

    return res.status(200).json({
      success: true,
      data: {
        query: searchQuery,
        suggestions: formattedSuggestions,
        count: formattedSuggestions.length
      }
    });

  } catch (error) {
    console.error('Error getting city suggestions:', error);
    return res.status(500).json({
      success: false,
      message: 'Errore nel caricamento dei suggerimenti',
      error: error.message
    });
  }
};

/**
 * Get recent cities from user's trip history
 * GET /api/trasporti/cities/recent
 */
const getRecentCities = async (req, res) => {
  try {
    const userId = req.user._id;

    // Get last 2 unique departure cities
    const recentDepartures = await Ride.aggregate([
      {
        $match: {
          $or: [
            { driverId: userId },
            { 'passengers.userId': userId }
          ],
          status: 'completed'
        }
      },
      {
        $sort: { departureDate: -1 }
      },
      {
        $group: {
          _id: {
            city: '$departure.city',
            region: '$departure.region',
            country: '$departure.country'
          },
          lat: { $first: '$departure.lat' },
          lng: { $first: '$departure.lng' },
          lastUsed: { $first: '$departureDate' }
        }
      },
      {
        $limit: 2
      },
      {
        $project: {
          _id: 0,
          city: '$_id.city',
          region: '$_id.region',
          country: '$_id.country',
          lat: 1,
          lng: 1,
          lastUsed: 1,
          type: { $literal: 'departure' }
        }
      }
    ]);

    // Get last 2 unique destination cities
    const recentDestinations = await Ride.aggregate([
      {
        $match: {
          $or: [
            { driverId: userId },
            { 'passengers.userId': userId }
          ],
          status: 'completed'
        }
      },
      {
        $sort: { departureDate: -1 }
      },
      {
        $group: {
          _id: {
            city: '$destination.city',
            region: '$destination.region',
            country: '$destination.country'
          },
          lat: { $first: '$destination.lat' },
          lng: { $first: '$destination.lng' },
          lastUsed: { $first: '$departureDate' }
        }
      },
      {
        $limit: 2
      },
      {
        $project: {
          _id: 0,
          city: '$_id.city',
          region: '$_id.region',
          country: '$_id.country',
          lat: 1,
          lng: 1,
          lastUsed: 1,
          type: { $literal: 'destination' }
        }
      }
    ]);

    // Combine and remove duplicates
    const allRecent = [...recentDepartures, ...recentDestinations];
    const uniqueCities = new Map();

    allRecent.forEach(city => {
      const key = `${city.city}-${city.region}`;
      if (!uniqueCities.has(key)) {
        uniqueCities.set(key, city);
      }
    });

    const cities = Array.from(uniqueCities.values())
      .sort((a, b) => new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime())
      .slice(0, 2);

    return res.status(200).json({
      success: true,
      data: {
        cities
      }
    });

  } catch (error) {
    console.error('Error getting recent cities:', error);
    return res.status(500).json({
      success: false,
      message: 'Errore nel caricamento delle città recenti',
      error: error.message
    });
  }
};

module.exports = {
  createRide,
  getRides,
  getRideById,
  updateRide,
  deleteRide,
  getMyRides,
  searchRides,
  completeRide,
  getRidesStats,
  getWidgetData,
  getStatsSummary,
  getCitySuggestions,
  getRecentCities,
};
