<?php

namespace App\Traits;

use Illuminate\Support\Str;

use App\Models\Page;
use App\Models\Blog;
use App\Models\Announcement;
use App\Models\Course;
use App\Models\PageSlug;
use App\Utilities\Slug;

trait SlugTrait
{
    abstract public function getFullSlugAttribute();

    public function getTextFromSlug($slug)
    {
        if (strpos($slug, '/') !== false) {
            $slug = Str::afterLast($slug, '/');
        }
        $words = str_replace(['-'], ' ', $slug);
        return Str::title($words);
    }

    public function findByFullSlug($slug)
    {
        $cache_name = cache_name('slug-'.Str::kebab($slug));

        $remove_editing_from_session = false;
        if (auth()->check() && request('editing') && !editing()) {
            $remove_editing_from_session = true;
            auth()->user()->enableEditing();
        }

        if (editing()) {
            $cache_name .= '-editing';
        }

        $slug_page = cache()->tags(['slugs'])->rememberForever($cache_name, function () use ($slug) {
            $words = collect(explode(' ', $this->getTextFromSlug($slug)))->filter(function ($word) {
                return strlen($word) > 2 || is_numeric($word);
            });

            $pages = $this->withoutTrashed()->whereHas('versions', function ($query) use ($words) {
                $first = true;
                foreach ($words as $word) {
                    if ($first) {
                        $query->where('name', 'like', '%'.$word.'%')
                            ->orWhere('slug', 'like', '%'.$word.'%');
                        $first = false;
                    } else {
                        $query->orWhere('name', 'like', '%'.$word.'%')
                            ->orWhere('slug', 'like', '%'.$word.'%');
                    }
                }
            })
            ->get();

            if (!$pages->count()) {
                $pages = $this->withoutTrashed()->get();
            }

            $page = $pages->filter(function ($page) use ($slug) {
                return $page->full_slug === $slug;
            })->last();

            if ($page) {
                return $page->load('contentElements', 'publishedVersion', 'versions');
            }

            // look for any pageSlugs (aliases)

            if (strpos($slug, '/') !== false) {
                $split = preg_split('~/(?=[^/]*$)~', $slug);

                $parent_slug = $split[0];
                $alias = $split[1];
            } else {
                $parent_slug = null;
                $alias = $slug;
            }

            $page_slug = PageSlug::where('slug', $alias)
                ->get()
                ->filter(function ($page_slug) use ($parent_slug) {
                    if ($parent_slug) {
                        return $page_slug->pageable->parent_slug === $parent_slug;
                    } else {
                        return true;
                    }
                })->first();

            if ($page_slug) {
                return $page_slug->pageable;
            }

            return null;
        });

        if ($remove_editing_from_session) {
            auth()->user()->disableEditing();
        }

        if ($slug_page) {
            return $slug_page;
        } else {
            return null;
        }
    }

    public function getSlug()
    {
        // dont cache this, it breaks things
        $version = $this->version;

        if ($this instanceof Course && auth()->user()?->can('viewAny', Course::class)) {
            $version = $this->versions->last();
        }

        if ($this instanceof Blog && auth()->user()?->can('viewAny', Blog::class)) {
            $version = $this->versions->last();
        }

        if ($this instanceof Announcement && auth()->user()?->can('viewAny', Announcement::class)) {
            $version = $this->versions->last();
        }

        if (!$version) {
            return null;
        }

        if ($this instanceof Page && $this->id === 1) {
            return '/';
        }

        if ($version->slug) {
            $slug = $version->slug;
        } else {
            $slug = $version->name;
        }

        $slug = Str::lower($slug);
        $slug = str_replace([' '], '-', $slug);
        $slug = preg_replace("/[^A-Za-z0-9\-]/", '', $slug);
        //$slug = Str::kebab($slug);
        return $slug;
    }

    public function pageSlugs()
    {
        return $this->morphMany(PageSlug::class, 'pageable');
    }

    public function getParentSlugAttribute()
    {
        if ($this instanceof Page && $this->id > 1) {
            if (!$this->version) {
                return null;
            }
            if (!$this->version->parentPage) {
                return null;
            }
            return $this->version->parentPage->full_slug;
        }
        return null;
    }

    public function getBreadcrumbsAttribute()
    {
        return $this->getBreadcrumbs();
    }

    public function getBreadcrumbs()
    {
        return collect();
    }
}
