<?php

namespace App\Console\Commands;

use App\Master\Models\VehicleMake;
use App\Master\Models\VehicleModel;
use App\TaxonomyMap;
use Illuminate\Console\Command;
use Mtc\MercuryDataModels\Franchise;
use Mtc\MercuryDataModels\NewCar;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleOffer;
use Mtc\MercuryDataModels\VehicleTrim;

class VehicleMakeMerge extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'vehicle-make:merge';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Merge two vehicle make entries (from different providers) into one';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $name = $this->ask('Enter make name for lookup:');
        $makes =  VehicleMake::query()->where('name', 'like', "$name%")->get()->keyBy('id');
        $columns = ['id', 'slug', 'name', 'autotrader_id', 'cap_id', 'lv_cap_id'];
        $this->table($columns, $makes->map(fn($make) => $make->only($columns)));

        $toReplace = $this->choice('Please select the ID of make to replace', $makes->pluck('id')->toArray());

        $replaceWith = $this->choice(
            'Please select the ID of make that will be the replacement',
            $makes->pluck('id')->toArray()
        );

        $this->output->warning("This will remove [{$makes[$toReplace]->name}] and all its models. "
            .  "AutoTrader/CAP ids will be moved over if exist. "
            .  "Vehicles/Offers/NewCar/Trim records on all sites will be adjusted. "
            .  "Taxonomy mapping referencing this make and its model will be moved.");

        if (!$this->output->confirm('Are you sure you sure you want to perform this action?')) {
            $this->info('Action cancelled');
        }

        $this->info('Let the action commence...');
        $originMake = VehicleMake::query()->find($toReplace);
        $replacementMake = VehicleMake::query()->find($replaceWith);

        $originMake->models()
            ->get()
            ->each(fn(VehicleModel $model) => $this->moveModelData($model, $replacementMake))
            ->each(fn(VehicleModel $model) => $model->delete());

        TaxonomyMap::query()
            ->whereIn('taxonomy_type', ['make', 'master-make'])
            ->where('taxonomy_id', $originMake->id)
            ->update(['taxonomy_id' => $replacementMake->id]);

        tenancy()->runForMultiple(null, function () use ($originMake, $replacementMake) {
            Franchise::query()
                ->where('make_id', $originMake->id)
                ->update(['make_id' => $replacementMake->id]);
            VehicleTrim::query()
                ->where('make_id', $originMake->id)
                ->update(['make_id' => $replacementMake->id]);
            VehicleTrim::query()
                ->where('make_id', $originMake->id)
                ->update(['make_id' => $replacementMake->id]);
            NewCar::query()
                ->where('make_id', $originMake->id)
                ->update(['make_id' => $replacementMake->id]);
            Vehicle::query()
                ->where('make_id', $originMake->id)
                ->update(['make_id' => $replacementMake->id]);
            VehicleOffer::query()
                ->where('make_id', $originMake->id)
                ->update(['make_id' => $replacementMake->id]);
        });

        $replacementMake->update([
            'autotrader_id' => $replacementMake->autotrader_id ?? $originMake->autotrader_id,
            'cap_id' => $replacementMake->cap_id ?? $originMake->cap_id,
            'lc_cap_id' => $replacementMake->lc_cap_id ?? $originMake->lc_cap_id,
        ]);
        $originMake->delete();

        $this->call('tenants:sync-taxonomies');
    }

    private function moveModelData(VehicleModel $model, VehicleMake $replacementMake): void
    {
        $this->output->info("Processing model '$model->name'");
        $replacementModel = $replacementMake->models()->where('name', $model->name)->first();
        if (!$replacementModel) {
            $this->output
                ->warning("Replacement model not found via name match for '$model->name'. Is name in this list?");
            $models = $replacementMake->models()->select(['id', 'name'])->get()->toArray();
            $this->output->table(['id', 'name'], $models);
            if ($this->confirm('Yes, item is in list')) {
                $modelId = $this->choice('Select model ID', collect($models)->pluck('id')->toArray());
                $replacementModel = $replacementMake->models()->find($modelId);
            } elseif ($this->confirm('Do you want to move this model over?')) {
                $model->update(['make_id' => $replacementMake->id]);
                return;
            } else {
                return;
            }
        }
        $replacementModel->update([
            'autotrader_id' => $replacementModel->autotrader_id ?? $model->autotrader_id,
            'cap_id' => $replacementModel->cap_id ?? $model->cap_id,
            'lc_cap_id' => $replacementModel->lc_cap_id ?? $model->lc_cap_id,
        ]);

        TaxonomyMap::query()
            ->whereIn('taxonomy_type', ['model', 'master-model'])
            ->where('taxonomy_id', $model->id)
            ->update(['taxonomy_id' => $replacementModel->id]);

        tenancy()->runForMultiple(null, function () use ($model, $replacementModel) {
            VehicleTrim::query()
                ->where('model_id', $model->id)
                ->update(['model_id' => $replacementModel->id]);
            VehicleTrim::query()
                ->where('model_id', $model->id)
                ->update(['model_id' => $replacementModel->id]);
            NewCar::query()
                ->where('model_id', $model->id)
                ->update(['model_id' => $replacementModel->id]);
            Vehicle::query()
                ->where('model_id', $model->id)
                ->update(['model_id' => $replacementModel->id]);
            VehicleOffer::query()
                ->where('model_id', $model->id)
                ->update(['model_id' => $replacementModel->id]);
        });
    }
}
