<?php

namespace App\Jobs;

use App\Exceptions\CarrierCreateFailedException;
use App\Models\Shipment;
use App\Services\Carriers\CarrierServiceFactory;
use Illuminate\Support\Facades\Log;
use App\Models\WhatsappTemplates;
use App\Models\User;
use App\Utility\WhatsappUtility;

class ProcessShipmentJob
{
    /**
     * Create a new instance.
     */
    public function __construct(
        public Shipment $shipment,
        public array $formData = []
    ) {
        //
    }

    /**
     * Execute the shipment processing.
     */
    public function execute(): void
    {
        try {
            // Reload shipment to ensure we have latest data
            $shipment = $this->shipment->fresh(['carrier', 'order']);

            if (!$shipment) {
                Log::error('ProcessShipmentJob: Shipment not found', [
                    'shipment_id' => $this->shipment->id,
                ]);
                return;
            }

            // Update status to processing
            $shipment->update(['status' => Shipment::STATUS_PENDING]);

            // Get carrier service
            $carrierService = CarrierServiceFactory::makeFromModel($shipment->carrier);

            // Create shipment via carrier API
            $result = $carrierService->createShipment($shipment->order, $this->formData);

            $trackingId = $result['tracking_id'] ?? null;
            if ($trackingId === null || $trackingId === '') {
                $shipment->update([
                    'status' => Shipment::STATUS_FAILED,
                    'raw_response' => $result['raw_response'] ?? [
                        'error' => 'No AWB/tracking_id returned from carrier',
                        'result' => $result,
                    ],
                ]);

                Log::error('ProcessShipmentJob: Shipment create failed (no AWB)', [
                    'shipment_id' => $shipment->id,
                    'order_id' => $shipment->order_id,
                    'result' => $result,
                ]);
                return;
            }

            // Update shipment with results
            $shipment->update([
                'tracking_id' => $trackingId,
                'status' => Shipment::STATUS_CREATED,
                'label_url' => $result['label_url'] ?? null,
                'raw_response' => $result['raw_response'] ?? null,
                'metadata' => $result['metadata'] ?? null,
            ]);

            // Update order status to shipped if shipment was created successfully
            if ($shipment->order->status === \App\Models\Order::STATUS_PACKED) {
                $shipment->order->update([
                    'status' => \App\Models\Order::STATUS_AWAITING_PICKUP,
                    'delhivery_awb' => $trackingId,
                    'delhivery_label_url' => $result['label_url'] ?? null,
                ]);

                $WhatsAppTemplate = WhatsappTemplates::where('identifier', 'order_tracking_details')->first();
                if ($WhatsAppTemplate && $WhatsAppTemplate->is_active == 1) {
                    try {
                        $order = $shipment->order;
                        $customer = User::findOrFail($order->user_id); 
                        
                        if ($customer) {
                            WhatsappUtility::order_tracking_details($customer, $order);
                        }
                    } catch (\Exception $e) {
                        Log::error('WhatsApp order_tracking_details sending failed: ' . $e->getMessage());
                    }
                }
            }

            Log::info('ProcessShipmentJob: Shipment processed successfully', [
                'shipment_id' => $shipment->id,
                'tracking_id' => $trackingId,
            ]);
        } catch (CarrierCreateFailedException $e) {
            $rawResponse = $e->getRawResponse();
            $failureReason = $e->getFailureReason();
            $this->shipment->update([
                'status' => Shipment::STATUS_FAILED,
                'raw_response' => !empty($rawResponse) ? $rawResponse : ['error' => $e->getMessage()],
                'metadata' => array_merge($this->shipment->metadata ?? [], [
                    'failure_reason' => $failureReason,
                ]),
            ]);

            Log::error('ProcessShipmentJob: Shipment create failed (carrier)', [
                'shipment_id' => $this->shipment->id,
                'error' => $e->getMessage(),
                'failure_reason' => $failureReason,
            ]);

            throw $e;
        } catch (\Exception $e) {
            // Update shipment status to failed
            $this->shipment->update([
                'status' => Shipment::STATUS_FAILED,
                'raw_response' => [
                    'error' => $e->getMessage(),
                    'trace' => $e->getTraceAsString(),
                ],
            ]);

            Log::error('ProcessShipmentJob: Failed to process shipment', [
                'shipment_id' => $this->shipment->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            throw $e;
        }
    }
}
