<?php

namespace App\Console\Commands;

use App\Facades\Settings;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Mtc\ContentManager\Facades\Media;
use Mtc\MercuryDataModels\MediaUse;
use Mtc\MercuryDataModels\Vehicle;

class DeleteNonAutoTraderVehicleImages extends Command
{
    private const KEEP_PROVIDER = 'auto-trader';

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'vehicles:delete-non-autotrader-images';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Delete vehicle images that did not come from AutoTrader (keeps image_provider = auto-trader)';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        // Safety: never strip non-AutoTrader images unless AutoTrader is the active stock source,
        // otherwise we could delete the only images a vehicle has.
        if (!(Settings::get('stock-auto-trader-enabled', false) ?? false)) {
            $this->output->info('AutoTrader stock import is not enabled - skipping.');
            return self::SUCCESS;
        }

        $this->output->info('Deleting non-AutoTrader images for in-stock vehicles');

        // Process published vehicles first so the most visible inventory is cleaned up soonest.
        $vehicles = Vehicle::query()->orderByDesc('is_published');

        $progress = $this->output->createProgressBar($vehicles->clone()->count());
        $progress->start();

        $ownerType = (new Vehicle())->getMorphClass();

        $vehicles
            ->select('id', 'is_published')
            ->chunk(250, function (Collection $collection) use ($progress, $ownerType) {
                // Fetch every relevant media use for the whole chunk in a single query rather than
                // running one correlated query per vehicle (the previous N+1 source of slowness).
                $uses = MediaUse::query()
                    ->where('owner_type', $ownerType)
                    ->whereIn('owner_id', $collection->modelKeys())
                    ->with('media.uses')
                    ->whereHas('media', fn ($query) => $query
                        ->where(fn ($query) => $query
                            ->whereNull('image_provider')
                            ->orWhere('image_provider', '!=', self::KEEP_PROVIDER)))
                    ->get();

                $this->removeMediaUses($uses);

                $progress->advance($collection->count());
            });

        $progress->finish();
        $this->output->newLine();

        return self::SUCCESS;
    }

    private function removeMediaUses(Collection $uses): void
    {
        // with other uses, can't remove file, only use itself
        $uses->filter(fn ($use) => is_null($use->media) || $use->media->uses->count() > 1)
            ->each(fn ($use) => $use->delete());

        $without_other_uses = $uses
            ->filter(fn ($use) => $use->media?->uses->count() <= 1)
            ->pluck('media_id')
            ->toArray();
        if (!empty($without_other_uses)) {
            Media::destroyMedia($without_other_uses);
        }
    }
}
