const { catchAsyncErrors } = require('../middlewares/catchAsyncErrors.js');
const { zoneValidation } = require('../validation/super.validation.js');
const ErrorHandler = require('../utils/ErrorHandler.js');
const zoneService = require('../services/zone.service.js');
const isValidMongooseId = require('../helper/mongooseIdValidation.js');

// CREATE Zone
exports.createZone = catchAsyncErrors(async (req, res) => {
  console.log("....create zone api working ")
  const { error } = zoneValidation.validate(req.body);
  if (error) return res.status(400).json({ message: error.details[0].message });

  try {
    const result = await zoneService.createZone(req.body, req.user._id);
    return res.status(201).json({
      message: "Zone created successfully",
      zone: result.zone,
      zoneAdmin: {
        fullName: result.zoneAdmin.fullName,
        email: result.zoneAdmin.email,
        phone: result.zoneAdmin.phone,
      }
    });
  } catch (error) {
    console.error(error);
    return res.status(error.statusCode || 500).json({ message: error.message || "Internal Server Error" });
  }
});

// GET All Zones (combined with filter functionality)
exports.getAllZones = catchAsyncErrors(async (req, res, next) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;

    // Check if any filter parameters are provided
    const { startDate, endDate, zoneName, isActive, minFare, maxFare, minRating, zoneAdmin, city } = req.query;
    const hasFilters = startDate || endDate || zoneName || isActive !== undefined || minFare || maxFare || minRating || zoneAdmin || city;

    if (hasFilters) {
      // Use filtered query
      const filters = await zoneService.buildZoneFilters(req.query);

      // Validate date range if both provided
      if (startDate && endDate) {
        if (new Date(startDate) > new Date(endDate)) {
          return res.status(400).json({ message: "End date must be greater than start date" });
        }
      }

      const result = await zoneService.getFilteredZones(filters, { page, limit });

      return res.status(200).json({
        zones: result.zones,
        pagination: { page, limit, total: result.total, pages: result.pages }
      });
    } else {
      // No filters - return all zones
      const result = await zoneService.getAllZones({ page, limit });

      return res.status(200).json({
        zones: result.zones,
        pagination: { page, limit, total: result.total, pages: result.pages }
      });
    }
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: "Internal Server Error" });
  }
});


// GET Zone by ID
exports.getZoneById = catchAsyncErrors(async (req, res, _) => {
  try {
    isValidMongooseId(req.params.id);
    if (req.user.role === 'zone-admin') {
      if (req.user._id.toString() !== req.params.id) {
        return res.status(403).json({ message: 'Access denied. You can only view your assigned zone.' });
      }
    }
    const zone = await zoneService.getZoneById(req.params.id);
    res.status(200).json({ zone });
  } catch (error) {
    console.error(error);
    return res.status(error.statusCode || 500).json({ message: error.message || "Internal Server Error" });
  }
});

// GET Zones for Dropdown
exports.getAllZonesForDropdown = catchAsyncErrors(async (req, res, _) => {
  try {
    const zones = await zoneService.getAllZonesForDropdown();
    res.status(200).json({ zones, count: zones.length });
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: "Internal Server Error" });
  }
});

// UPDATE Zone
exports.updateZone = catchAsyncErrors(async (req, res, _) => {
  try {
    const zone = await zoneService.updateZone(req.params.id, req.body);
    res.status(200).json({ message: "Zone updated successfully" });
  } catch (error) {
    console.error(error);
    return res.status(error.statusCode || 500).json({ message: error.message || "Internal Server Error" });
  }
});

// UPDATE Zone Admin
exports.updateZoneAdmin = catchAsyncErrors(async (req, res, next) => {
  try {
    const result = await zoneService.updateZoneAdmin(req.params.id, req.body);
    return res.status(200).json({ success: true, message: `Admin updated for ${result.zone.zoneName} zone` });
  } catch (error) {
    console.error(error);
    return next(new ErrorHandler(error.message || "Internal Server Error", error.statusCode || 500));
  }
});

// DELETE Zone
exports.deleteZone = catchAsyncErrors(async (req, res, _) => {
  try {
    await zoneService.deleteZone(req.params.id);
    res.status(200).json({ success: true, message: "Zone deleted successfully" });
  } catch (error) {
    console.error(error);
    return res.status(error.statusCode || 500).json({ success: false, message: error.message || "Internal Server Error" });
  }
});

// UPDATE Zone Status
exports.changeZoneStatus = catchAsyncErrors(async (req, res, _) => {
  try {
    const zone = await zoneService.changeZoneStatus(req.params.id, req.body.isActive);
    res.status(200).json({ message: `status updated successfully for zone ${zone.zoneName}` });
  } catch (error) {
    console.error(error);
    return res.status(error.statusCode || 500).json({ message: error.message || "Internal Server Error" });
  }
});

// GET Zones by City
exports.getZonesByCity = catchAsyncErrors(async (req, res, _) => {
  try {
    const Zone = require('../models/zone.model');
    const zones = await Zone.find({
      'zoneAddress.city': { $regex: req.params.city, $options: 'i' }
    }).populate('zoneAdmin', 'fullName email phone');
    res.status(200).json({ zones, count: zones.length });
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: "Internal Server Error" });
  }
});

// GET Zone Statistics (placeholder)
exports.getZoneStatistics = catchAsyncErrors(async (req, res, _) => {
  try {
    const Zone = require('../models/zone.model');
    const totalZones = await Zone.countDocuments();
    const activeZones = await Zone.countDocuments({ isActive: true });

    res.status(200).json({
      success: true,
      stats: {
        total: totalZones,
        active: activeZones,
        inactive: totalZones - activeZones
      }
    });
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: "Internal Server Error" });
  }
});

// GET Zone Analytics (detailed zone report)
exports.getZoneAnalytics = catchAsyncErrors(async (req, res, _) => {
  try {
    const zoneId = req.params.id;
    const { startDate, endDate } = req.query;

    // Validate zone exists
    const zone = await zoneService.getZoneById(zoneId);
    if (!zone) {
      return res.status(404).json({ message: "Zone not found" });
    }

    // Get analytics data
    const analytics = await zoneService.getZoneAnalytics(zoneId, { startDate, endDate });

    res.status(200).json({
      success: true,
      zone: {
        id: zone._id,
        name: zone.zoneName,
        city: zone.zoneAddress?.city,
        isActive: zone.isActive
      },
      analytics
    });
  } catch (error) {
    console.error(error);
    return res.status(error.statusCode || 500).json({ message: error.message || "Internal Server Error" });
  }
});

// GET Zones Overview (for super admin dashboard)
exports.getZonesOverview = catchAsyncErrors(async (req, res, _) => {
  try {
    const overview = await zoneService.getZonesOverview();
    res.status(200).json({
      success: true,
      ...overview
    });
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: "Internal Server Error" });
  }
});


// GET Order percentage by status  for perticuler zone
exports.getOrdersByStatusForZone = catchAsyncErrors(async (req, res, _) => {
  try {
    const zoneId = req.params.id;

    // Validate zone exists
    const zone = await zoneService.getZoneById(zoneId);
    if (!zone) {
      return res.status(404).json({ message: "Zone not found" });
    }

    if (req.user.role === 'zone-admin' && req.user._id.toString() !== zone.zoneAdmin.toString()) {
      return res.status(404).json({ message: "You are not authorized to view this zone" });
    }
    // Get orders by status for the zone
    const orders = await zoneService.getOrdersByStatusForZone(zoneId);

    res.status(200).json({
      success: true,
      orders
    });
  } catch (error) {
    console.error(error);
    return res.status(error.statusCode || 500).json({ message: error.message || "Internal Server Error" });
  }
});