<?php

namespace App\Jobs;

use App\Models\ImportCondition;
use App\Traits\ImportChecksConditions;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mtc\MercuryDataModels\Media;
use Mtc\MercuryDataModels\Vehicle;

/**
 * Applies an import condition to vehicles that already exist in the system,
 * mirroring what the condition would do at import time:
 *  - do_not_import  => the matching vehicle is removed (with its media)
 *  - do_not_publish => the matching vehicle is unpublished
 */
class RunImportConditionJob implements ShouldQueue
{
    use Dispatchable;
    use ImportChecksConditions;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    public int $timeout = 600;

    public function __construct(private readonly int $conditionId)
    {
        $this->onQueue('sync');
    }

    public function handle(): void
    {
        $condition = ImportCondition::query()
            ->with('rules')
            ->find($this->conditionId);

        // No rules means "applies to all" — too destructive to run retroactively, so skip.
        if (!$condition || $condition->rules->isEmpty()) {
            return;
        }

        if (!$condition->do_not_import && !$condition->do_not_publish) {
            return;
        }

        Vehicle::query()
            ->with('attributeValues')
            ->when($condition->provider, fn ($query) => $query->where('stock_provider', $condition->provider))
            ->chunkById(200, fn ($vehicles) => $vehicles->each(
                fn (Vehicle $vehicle) => $this->applyToVehicle($condition, $vehicle)
            ));
    }

    private function applyToVehicle(ImportCondition $condition, Vehicle $vehicle): void
    {
        if (!$this->conditionMatchesVehicle($condition, $vehicle)) {
            return;
        }

        if ($condition->do_not_import) {
            $this->removeVehicleWithMedia($vehicle);
            return;
        }

        if ($condition->do_not_publish && $vehicle->is_published) {
            $vehicle->is_published = false;
            $vehicle->save();
        }
    }

    private function removeVehicleWithMedia(Vehicle $vehicle): void
    {
        $ids = $vehicle->mediaUses()->pluck('media_id');
        $vehicle->mediaUses()->delete();
        $vehicle->delete();
        Media::query()->whereIn('id', $ids)->whereDoesntHave('uses')->delete();
    }
}
