<?php

namespace Ignite\Core\Entities;

use Carbon\Carbon;
use Ignite\Core\Traits\AttributeToggle;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;

/**
 * Ignite\Core\Entities\Block
 *
 * @property int $id
 * @property string $name
 * @property string $code
 * @property string|null $locale
 * @property string $content
 * @property string $status
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property \Illuminate\Support\Carbon|null $published_at
 * @method static Builder|Block byCode($code)
 * @method static Builder|Block newModelQuery()
 * @method static Builder|Block newQuery()
 * @method static Builder|Block onlyActive()
 * @method static Builder|Block onlyPublished()
 * @method static Builder|Block query()
 * @method static Builder|Block whereCode($value)
 * @method static Builder|Block whereContent($value)
 * @method static Builder|Block whereCreatedAt($value)
 * @method static Builder|Base whereHasPermission(string $permission, ?\Ignite\Core\Entities\User $user = null)
 * @method static Builder|Block whereId($value)
 * @method static Builder|Block whereLocale($value)
 * @method static Builder|Block whereName($value)
 * @method static Builder|Block wherePublishedAt($value)
 * @method static Builder|Block whereStatus($value)
 * @method static Builder|Block whereUpdatedAt($value)
 * @mixin \Eloquent
 */
class Block extends Base
{
    use AttributeToggle;

    /** @const string */
    public const ACTIVE = 'active';

    /** @const string */
    public const INACTIVE = 'inactive';

    /** @const string */
    public const CODE_SEPARATOR = '_';

    /**
     * The database table name.
     * @var string
     */
    protected $table = 'core_block';

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = [
        'created_at',
        'updated_at',
        'published_at',
    ];

    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    public static function boot()
    {
        parent::boot();

        static::saving(function ($block) {
            // When saving, make sure the code slug is in the correct format
            if (isset($block->code) && ! empty($block->code)) {
                $block->code = Str::slug($block->code, static::CODE_SEPARATOR);
            }

            // Purify
            $purifier = app(\Ignite\Core\Models\Purifier::class);
            $block->attributes['content'] = $purifier->clean($block->attributes['content']);
        });
    }

    /**
     * Get the statuses.
     *
     * @return array
     */
    public function getStatuses()
    {
        $statuses = [
            static::INACTIVE => ucfirst(static::INACTIVE),
            static::ACTIVE => ucfirst(static::ACTIVE),
        ];

        return $statuses;
    }

    /**
     * Is the page active.
     *
     * @return bool
     */
    public function isActive()
    {
        return $this->status === static::ACTIVE;
    }

    /**
     * Is the page inactive.
     *
     * @return bool
     */
    public function isInactive()
    {
        return $this->status === static::INACTIVE;
    }

    /**
     * Get the content as a HtmlString.
     *
     * @return HtmlString
     */
    public function getContentHtml()
    {
        return new HtmlString($this->content ?? '');
    }

    // ----- Scopes

    /**
     * Query for a URL code.
     *
     * @param Builder $query
     * @param string $code
     * @return Builder
     */
    public function scopeByCode(Builder $query, $code)
    {
        $query->where('code', $code);

        return $query;
    }

    /**
     * Query for a URL code.
     *
     * @param Builder $query
     * @return Builder
     */
    public function scopeOnlyActive(Builder $query)
    {
        $query->where('status', static::ACTIVE);

        return $query;
    }

    /**
     * Query for a URL code.
     *
     * @param Builder $query
     * @return Builder
     */
    public function scopeOnlyPublished(Builder $query)
    {
        $query->where('published_at', '<=', Carbon::now());

        return $query;
    }
}
