<?php

namespace App\Filter;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Mtc\Filter\Contracts\FilterIndexContract;
use Mtc\Filter\Contracts\IsFilter;
use Mtc\MercuryDataModels\BodyStyleType;

class FilterIndex extends FilterIndexContract
{
    /**
     * Index a model
     *
     * @param string $filter_type
     * @param Model $model
     * @param IsFilter $filter
     * @throws \RuntimeException
     */
    #[\Override]
    public static function index(string $filter_type, Model $model, IsFilter $filter): void
    {
        if ($model instanceof BodyStyleType && $model->has_subcategories) {
            self::indexWithSubTypes($filter_type, $model, $filter);
            return;
        }

        $type = $filter_type;
        $id = $model->getAttribute($filter->getIdAttribute(true));
        $name = $model->getAttribute($filter->getNameAttribute(true));
        $slug = trim(Str::slug($filter->modelSlug($model)));

        if (empty($id)) {
            return;
        }

        if (empty($slug) && $slug !== '0') {
            return;
        }

        if (!in_array($type, ['model', 'make']) && self::checkExisting($type, $id, $slug)) {
            $slug = self::uniqueSlug($type, $id, $slug);
        }

        self::query()
            ->updateOrCreate([
                'filter_type' => $type,
                'filter_id' => $id,
            ], [
                'slug' => $slug,
                'name' => $name
            ]);
    }
    private static function indexWithSubTypes(string $filter_type, BodyStyleType $model, IsFilter $filter)
    {

        $type = $filter_type;
        $id = $model->getAttribute($filter->getIdAttribute(true));
        $name = $model->getAttribute($filter->getNameAttribute(true));
        $slug_small = Str::slug('small-' . $filter->modelSlug($model));
        $slug_medium = Str::slug('medium-' . $filter->modelSlug($model));
        $slug_large = Str::slug('large-' . $filter->modelSlug($model));

        if ($id === null || empty(trim($id))) {
            return;
        }

        self::query()
            ->updateOrCreate([
                'filter_type' => $type,
                'filter_id' => $id,
                'slug' => $slug_small,
            ], [
                'name' => 'Small ' . $name
            ]);

        self::query()
            ->updateOrCreate([
                'filter_type' => $type,
                'filter_id' => $id,
                'slug' => $slug_medium,
            ], [
                'name' => 'Medium ' . $name
            ]);

        self::query()
            ->updateOrCreate([
                'filter_type' => $type,
                'filter_id' => $id,
                'slug' => $slug_large,
            ], [
                'name' => 'Large ' . $name
            ]);
    }

    /**
     * Check if slug is not already used
     *
     * @param string $type
     * @param $id
     * @param string $slug
     * @return bool
     */
    #[\Override]
    protected static function checkExisting(string $type, $id, string $slug): bool
    {
        $safe_id = DB::getPdo()->quote($id);
        $safe_type = DB::getPdo()->quote($type);
        return self::query()
            ->where('filter_type', $type)
            ->where('slug', $slug)
            ->whereRaw(DB::raw("NOT ( `filter_id` = $safe_id and `filter_type` = $safe_type)"))
            ->exists();
    }
}
