<?php

namespace App\Model;

use Deligoez\LaravelModelHashId\Traits\HasHashId;
use Deligoez\LaravelModelHashId\Traits\HasHashIdRouting;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use App\Traits\QueryCacheable;
use Illuminate\Http\Request;
use Nette\Utils\Html;
use Yajra\DataTables\Facades\DataTables;

class StaticPage extends Model
{
    use HasHashId, HasHashIdRouting, SoftDeletes, QueryCacheable;

    /**
     * Specify the amount of time to cache queries.
     * Do not specify or set it to null to disable caching.
     *
     * @var int|\DateTime
     */
    public $cacheFor = 3600;

    /**
     * The tags for the query cache. Can be useful
     * if flushing cache for specific tags only.
     *
     * @var null|array
     */
    public $cacheTags = ['static_pages'];

    /**
     * Invalidate the cache automatically
     * upon update in the database.
     *
     * @var bool
     */
    protected static $flushCacheOnUpdate = true;

    const TNC_ID = [1, 'term-and-conditions'];
    const PRIVACY_ID = [2, 'privacy-policy'];
    const CONTACT_US_ID = [3, 'contact-us'];
    const ABOUT_US_ID = [4, 'about-us'];

    const FOOTER_SECTION_1 = 'footer_section_1';
    const FOOTER_SECTION_2 = 'footer_section_2';
    const FOOTER_SECTION_3 = 'footer_section_3';

    const TYPE_INNER_PAGE = 'inner page';
    const TYPE_CUSTOM_URL = 'custom url';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'parent_id',
        'slug',
        'icon',
        'title',
        'description',
        'keywords',
        'position',
        'on_menu',
        'on_menu_position',
        'on_footer',
        'on_footer_section',
        'editor_content',
        'plain_content',
        'is_active',
        'page_type',
        'page_url',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        // 'deleted_at',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'updated_at' => 'datetime:Y-m-d H:i:s',
        'created_at' => 'datetime:Y-m-d H:i:s',
        'deleted_at' => 'datetime:Y-m-d H:i:s',
    ];

     /**
     * The relations to eager load on every query.
     *
     * @var array
     */
    protected $with = [
        // 'children'
    ];

    protected static function boot()
    {
        parent::boot();

        self::creating(function ($model) {
            $model->position = self::max('position') + 1;
        });

        self::deleting(function ($model) {
            $model->children()->update(['parent_id' => null]);
        });
    }

    public static function unDeletedPages()
    {
        return [
            self::TNC_ID[0],
            self::PRIVACY_ID[0],
            self::CONTACT_US_ID[0],
            self::ABOUT_US_ID[0],
        ];
    }

    public function parent()
    {
        return $this->belongsTo(self::class, 'parent_id');
    }

    public function children()
    {
        return $this->hasMany(self::class, 'parent_id')->with('children')->orderBy('on_menu_position');
    }

    public function activeChildren()
    {
        return $this->children()->active()->with('activeChildren');
    }

    public function scopeActive($query)
    {
        $query->where('static_pages.is_active', true);
    }

    public function scopeOnMenu($query)
    {
        $query->where('static_pages.on_menu', true);
    }

    public function scopeOnFooter($query)
    {
        $query->where('static_pages.on_footer', true);
    }

    public function scopeFilters($query, Request $request)
    {
        $query->when($request->has('status'), function ($query) use ($request) {
            return $query->where('is_active', $request->status == 'active');
        });

        $query->when($request->has('range'), function ($query) use ($request) {
            $date_range = explode(' to ', $request->range);

            if (count($date_range) == 2) {
                $from = new Carbon($date_range[0]);
                $to = new Carbon($date_range[1]);

                $query->whereBetween('created_at', [$from->startOfDay(), $to->endOfDay()]);
            } else if (count($date_range) == 1) {
                $query->whereDate('created_at', $date_range[0]);
            }

            return $query;
        });
    }

    public static function makeDataTable($source, $trash = false)
    {
        return DataTables::of($source)
            ->editColumn('position', function (StaticPage $row) {
                return Html::el('span')
                    ->addHtml(Html::el('i class="fas fa-grip-vertical mr-2"'))
                    ->addText($row->position);
            })
            // ->editColumn('title', function (self $row) {
            //     return Html::el('a', [
            //             'href' => $url = $row->link_url,
            //             'data-placement' => 'right',
            //             'data-toggle' =>
            //             'tooltip',
            //             'title' => $url
            //         ])
            //         ->addHtml(Html::el('span', ['class' => 'd-inline-block mr-2'])->addText($row->title))
            //         ->addHtml(Html::el('i class="fas fa-arrow-up-right-from-square"'));
            // })
            ->editColumn('editor_content', function (self $row) {
                return view('admin.datatables.limit', ['title' => html_entity_decode(strip_tags($row->editor_content)), 'limit' => 40]);
            })
            ->addColumn('status', function (self $row) {
                return view('admin.datatables.status', ['active' => $row->is_active]);
            })
            ->addColumn('actions', function (self $row) use ($trash) {
                $actions = ['row' => $row];

                if ($trash) {
                    $actions['restore_route'] = 'static-page.restore';
                } else {
                    $actions['update_route'] = 'static-page.edit';
                    $actions['delete_route'] = 'static-page.destroy';
                }

                return view('admin.datatables.actions', $actions);
            })
            ->addColumn('is_static', function (self $row) {
                return view('admin.datatables.status', ['active' => in_array($row->id, self::unDeletedPages()), 'true' => 'Yes', 'false' => 'No']);
            })
            // ->addColumn('on_menu', function (self $row) {
            //     return view('admin.datatables.status', ['active' => $row->on_menu, 'true' => 'Yes', 'false' => 'No']);
            // })
            // ->addColumn('on_footer', function (self $row) {
            //     return view('admin.datatables.status', ['active' => $row->on_footer, 'true' => 'Yes', 'false' => 'No']);
            // })
            // to fixed yajra weird timezone return
            ->editColumn('created_at', fn($row) => $row->created_at)
            ->editColumn('updated_at', fn($row) => $row->updated_at)
            ->editColumn('deleted_at', fn($row) => $row->deleted_at)
            ->make(true);
    }

    /**
     * Get the link url of the page
     *
     * @return string
     */
    public function getLinkUrlAttribute()
    {
        return $this->page_url && $this->page_type == self::TYPE_CUSTOM_URL
            ? $this->page_url
            : ($this->slug ? url($this->slug) : '#');
    }

    public static function listFooterSections()
    {
        return [
            self::FOOTER_SECTION_1 => config('footer.section_1_title'),
            self::FOOTER_SECTION_2 => config('footer.section_2_title'),
            // self::FOOTER_SECTION_3 => config('footer.section_3_title'),
        ];
    }

    public static function listPageTypes()
    {
        return [
            self::TYPE_INNER_PAGE => 'Inner Page',
            self::TYPE_CUSTOM_URL => 'Custom URL',
        ];
    }
}
