<?php

namespace App\Listeners;

use Mtc\MercuryDataModels\Enums\VehicleSubscriptionEventType;
use App\Events\VehiclePriceChangedDuringStockSync;
use App\Events\VehicleUpdated;
use App\Facades\Feature;
use App\Jobs\SendVehicleSubscriptionNotificationJob;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleSubscription;

class NotifySubscribersOnPriceChange implements ShouldQueue
{
    public string $queue = 'emails';

    public function handle(VehiclePriceChangedDuringStockSync|VehicleUpdated $event): void
    {
        if (!Feature::isEnabled('vehicle-subscriptions')) {
            return;
        }

        $vehicle = $this->getVehicle($event);

        if (!$vehicle) {
            return;
        }

        // Only process for used vehicles (not new)
        if ($vehicle->is_new) {
            return;
        }

        // Determine previous price
        $previousPrice = $this->getPreviousPrice($event, $vehicle);

        if (!$previousPrice || $previousPrice <= 0) {
            return;
        }

        // Only notify for price drops (not increases)
        if ($vehicle->price >= $previousPrice) {
            return;
        }

        Log::info('Price drop detected for vehicle', [
            'vehicle_id' => $vehicle->id,
            'old_price' => $previousPrice,
            'new_price' => $vehicle->price,
        ]);

        $subscriptions = VehicleSubscription::query()
            ->where('vehicle_id', $vehicle->id)
            ->where('event_type', VehicleSubscriptionEventType::PRICE_DROP->value)
            ->get();

        if ($subscriptions->isEmpty()) {
            return;
        }

        Log::info('Dispatching price drop notifications', [
            'vehicle_id' => $vehicle->id,
            'subscription_count' => $subscriptions->count(),
        ]);

        foreach ($subscriptions as $subscription) {
            SendVehicleSubscriptionNotificationJob::dispatch(
                $subscription,
                VehicleSubscriptionEventType::PRICE_DROP,
                [
                    'old_price' => $previousPrice,
                    'new_price' => $vehicle->price,
                ]
            );
        }
    }

    private function getVehicle(VehiclePriceChangedDuringStockSync|VehicleUpdated $event): ?Vehicle
    {
        return $event->getVehicle();
    }

    private function getPreviousPrice(
        VehiclePriceChangedDuringStockSync|VehicleUpdated $event,
        Vehicle $vehicle
    ): ?float {
        // For stock sync events, the previous_price field should be updated
        if ($event instanceof VehiclePriceChangedDuringStockSync) {
            return $vehicle->previous_price;
        }

        // For manual updates (VehicleUpdated), use the previous price from the event
        if ($event instanceof VehicleUpdated && $event->getPreviousPrice() !== null) {
            return $event->getPreviousPrice();
        }

        // Fall back to previous_price if available
        return $vehicle->previous_price;
    }
}
