<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;

trait HasSortsTrait
{
    public function scopeWhereOperadores(Builder $query, $isOperador)
    {
        if ($isOperador) {
            $query->where('operadores', true);
        } else {
            $query->where('operadores', false);
        }
    }

    public function scopeApplySorts(Builder $query, $sort, $default_order = 'id')
    {
        if (is_null($sort)) {
            //$query->orderBy($default_order, 'desc');
            return;
        }

        $sortsFields = Str::of($sort)->explode(',');

        foreach ($sortsFields as $sortField) {
            $direction = 'asc';

            if (Str::of($sortField)->startsWith('-')) {
                $direction = 'desc';
                $sortField = Str::of($sortField)->substr(1);
            }

            if (!collect($this->allowedSorts)->contains($sortField)) {
                abort(400, "Parametro de orden {$sortField} inválido");
            }

            $query->orderBy($sortField, $direction);
        }
    }

    public function scopeFilterLike(Builder $query, $filter = [])
    {
        $query->where(function ($query1) use ($filter) {
            foreach ($filter as $filter => $value) {
                $query1->where($filter, 'like', '%' . $value . '%');
            }
        });
    }

    //* Make Avatar => Crea avatars para que tenga una imagen
    private function makeAvatar(String $text)
    {
        return 'https://ui-avatars.com/api/?background=random&size=500&name=' . urlencode($text);
    }

    public function scopeCreateOrGet(Builder $query, $data, $buscado = 'slug')
    {
        $query2 = $query;
        $first = $query->where($buscado, $data[$buscado])
            ->first();
        if ($first) return $first;

        return $query2->create($data);
    }

    public function scopeCreateOrUpdate(Builder $query, $data, $buscado = 'id')
    {
        $query2 = $query;
        $datatype = gettype($data);

        $valor = null;
        switch (strtolower($datatype)) {
            case ('array'):
                $valor = $data[$buscado];
                break;
            case ('object'):
                $valor = $data->{$buscado};
                break;
            default:
                return false;
                break;
        }

        $first = $query->where($buscado, $valor)
            ->first();

        if ($first) {
            $result = $query2->find($first->id);
            $result->fill($data)->save();
            return $result;
        }

        return $query2->create($data);
    }

    public function scopeSelectFillable(Builder $query, String $alias = null)
    {
        $fillable = array_merge($this->fillable, ['id', 'updated_at']);
        if ($alias && isset($alias)) {
            foreach ($fillable as $k => $f) {
                $fillable[$k] = trim($alias) . '.' . $f;
            }
        }
        return $query->select($fillable);
    }

    public function scopeSelectFillableAnd(Builder $query, array $other = [], String $alias = null)
    {
        $fillable = array_merge($this->fillable, ['id', 'updated_at'], $other);
        if ($alias && isset($alias)) {
            foreach ($fillable as $k => $f) {
                $fillable[$k] = trim($alias) . '.' . $f;
            }
        }
        return $query->select($fillable);
    }

    public function scopeSlug($query, string $slug, string $column_name = 'slug')
    {
        return $query->where($column_name, trim($slug));
    }

    public function scopeActivo($query, string $column = 'estado')
    {
        return $query->where($column, 1);
    }

    public function scopeOrdenar($query, string $column = 'orden')
    {
        $existColumn = $query->getQuery()
            ->getConnection()
            ->getSchemaBuilder()
            ->hasColumn($this->getTable(), $column);

        if (!$existColumn) {
            return $query->order('id', 'desc');
        }

        return $query->orderByRaw('ISNULL(orden)')
            ->orderBy('orden', 'ASC')
            ->orderBy('id', 'desc');
    }
}
