import { Request, Response } from 'express';
import { TrackingService } from '../services/tracking.service';
import { sendSuccess, sendError } from '../utils/response.utils';
import { AuthenticatedRequest } from '../middleware/auth.middleware';

// 1. Public Track Endpoint (No Auth required)
export const trackPublicOrder = async (req: Request, res: Response) => {
  try {
    const query = (req.params.query || req.query.q || req.body.query) as string;
    if (!query) {
      return sendError(res, 'Please provide an Order Number or Tracking Number', null, 400);
    }

    const trackingData = await TrackingService.trackPublic(query);
    return sendSuccess(res, 'Tracking details retrieved successfully', trackingData);
  } catch (error: any) {
    return sendError(res, error.message || 'Tracking information not found', null, 404);
  }
};

// 2. Get Supported Carriers List
export const getCarriers = async (_req: Request, res: Response) => {
  try {
    const carriers = TrackingService.getSupportedCarriers();
    return sendSuccess(res, 'Supported carriers retrieved', { carriers });
  } catch (error: any) {
    return sendError(res, 'Failed to get carrier list', error.message, 500);
  }
};

// 3. Create or Update Shipment (Admin Only)
export const updateShipment = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { orderId, trackingNumber, carrier, carrierSlug, carrierTrackingUrl, status, currentLocation, estimatedDelivery, shippedAt } = req.body;

    const shipment = await TrackingService.createOrUpdateShipment({
      orderId,
      trackingNumber,
      carrier,
      carrierSlug,
      carrierTrackingUrl,
      status,
      currentLocation,
      estimatedDelivery: estimatedDelivery ? new Date(estimatedDelivery) : undefined,
      shippedAt: shippedAt ? new Date(shippedAt) : undefined,
    });

    return sendSuccess(res, 'Shipment & tracking number assigned successfully', { shipment });
  } catch (error: any) {
    return sendError(res, 'Failed to update shipment', error.message, 500);
  }
};

// 4. Add Manual Tracking Event (Admin Only)
export const addTrackingEvent = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { shipmentId, status, title, description, location, timestamp, source } = req.body;

    const event = await TrackingService.addTrackingEvent({
      shipmentId,
      status,
      title,
      description,
      location,
      timestamp: timestamp ? new Date(timestamp) : undefined,
      source: source || 'ADMIN',
    });

    return sendSuccess(res, 'Tracking event added to timeline', { event });
  } catch (error: any) {
    return sendError(res, 'Failed to add tracking event', error.message, 500);
  }
};

// 5. Carrier Webhook Receiver (Delhivery, Shiprocket, BlueDart, DHL, IndiaPost)
export const handleCarrierWebhook = async (req: Request, res: Response) => {
  try {
    const carrierSlug = req.params.carrier;
    const payload = req.body;

    if (!carrierSlug) {
      return sendError(res, 'Carrier identifier missing in webhook route', null, 400);
    }

    const result = await TrackingService.processCarrierWebhook(carrierSlug, payload);
    return sendSuccess(res, 'Carrier webhook processed successfully', result);
  } catch (error: any) {
    // Return 200/400 gracefully so webhook retries or logs don't cascade crash
    return sendError(res, `Webhook processing error: ${error.message}`, null, 400);
  }
};
