<?php

namespace App\Console\Commands;

use App\Mail\NewVehicleMakesModelsMail;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use App\Master\Models\VehicleMake;
use App\Master\Models\VehicleModel;
use Mtc\VehicleLookup\Drivers\CAP;

class SyncCAPTaxonomies extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'cap:sync-taxonomies';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Pull Taxonomy data from CAP (makes/models)';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(protected CAP $service)
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $makes = collect($this->service->getMakes())
            ->filter(fn ($make) => !empty($make['name']) && !Str::contains($make['name'], ["'", '+', '!', '=', '.']))
            ->map(function (array $make) {
                $vehicleMake = VehicleMake::query()
                    ->whereRaw('LOWER(name) = ?', [strtolower((string) $make['name'])])
                    ->first();

                if ($vehicleMake) {
                    $vehicleMake->update([
                        'cap_id' => $make['id'] ?? null,
                        'lcv_cap_id' => $make['lcv_id'] ?? null,
                    ]);
                } else {
                    $vehicleMake = VehicleMake::query()->create([
                        'name' => $make['name'],
                        'cap_id' => $make['id'] ?? null,
                        'lcv_cap_id' => $make['lcv_id'] ?? null,
                    ]);
                }

                return $vehicleMake;
            });

        $this->info($makes->count() . ' fetched');

        $makes->each(fn (VehicleMake $make) => $this->syncModels($make));
        $this->notifyOnAdditions();

        return 0;
    }

    /**
     * Sync model data for a make
     *
     * @param $makeId
     * @param $all_makes
     */
    protected function syncModels($make)
    {
        collect($this->service->getModels($make))
            ->filter(fn ($model) => !empty($model['name']))
            ->each(function (array $model) use ($make) {
                $existing = VehicleModel::query()
                    ->where('make_id', $make->id)
                    ->whereRaw(
                        'LOWER(REPLACE(name, "-", " ")) = ?',
                        [strtolower(str_replace('-', ' ', $model['name']))]
                    )
                    ->first();

                if (!$existing) {
                    VehicleModel::query()->create([
                        'cap_id' => $model['id'] ?? null,
                        'lcv_cap_id' => $model['lcv_id'] ?? null,
                        'name' => $model['name'],
                        'make_id' => $make->id,
                        'type' => $model['type'] ?? null,
                    ]);
                } else {
                    $existing->update([
                        'cap_id' => $model['id'] ?? null,
                        'lcv_cap_id' => $model['lcv_id'] ?? null,
                        'type' => $this->mergeTypes($existing->type, $model['type'] ?? null),
                    ]);
                }
            });
    }

    private function mergeTypes(?string $existingType, ?string $newType): ?string
    {
        if (empty($newType)) {
            return $existingType;
        }

        if (empty($existingType)) {
            return $newType;
        }

        $types = explode('-', $existingType);
        if (!in_array($newType, $types, true)) {
            $types[] = $newType;
            sort($types);
        }

        return implode('-', $types);
    }

    /**
     * Notify on new additions
     *
     * @return void
     */
    private function notifyOnAdditions()
    {
        $recentMakes = VehicleMake::query()
            ->whereNotNull('cap_id')
            ->where('created_at', '>', Carbon::now()->startOfDay())
            ->get();

        $recentModels = VehicleModel::query()
            ->whereNotNull('cap_id')
            ->where('created_at', '>', Carbon::now()->startOfDay())
            ->get();

        if ($recentMakes->isEmpty() && $recentModels->isEmpty()) {
            return;
        }

        Mail::to(config('mail.developers'))
            ->send(new NewVehicleMakesModelsMail($recentMakes, $recentModels));
    }
}
