<?php

namespace Ignite\Core\Entities;

/**
 * Core Report
 *
 * @property int $id
 * @property string $name
 * @property string $class
 * @property array $params
 * @property string $status
 * @property bool $sensitive
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property \Illuminate\Support\Carbon|null $published_at
 * @property \Illuminate\Support\Carbon|null $unpublished_at
 * @method static \Illuminate\Database\Eloquent\Builder|Report newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Report newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Report query()
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereClass($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereCreatedAt($value)
 * @method static Builder|Base whereHasPermission(string $permission, ?\Ignite\Core\Entities\User $user = null)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereParams($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report wherePublishedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereSensitive($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereStatus($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereUnpublishedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Report whereUpdatedAt($value)
 * @mixin \Eloquent
 */
class Report extends Base
{
    /** @const string */
    public const ACTIVE = 'active';

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

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

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

    /**
     * The attributes that should be cast automatically.
     *
     * @var array
     */
    protected $casts = [
        'params' => 'array',
        'sensitive' => 'boolean',
    ];

    /**
     * Get the name of the report.
     *
     * @return string
     */
    public function getName()
    {
        return $this->getAttribute('name');
    }

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

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

    /**
     * Create an instance of the report table class.
     *
     * @return \Ignite\Core\Contracts\Table
     */
    public function getReportClassInstance()
    {
        return app($this->getAttribute('class'), ['params' => $this->params]);
    }

    /**
     * Determine if the report is published.
     *
     * @return bool
     */
    public function isPublished()
    {
        return $this->published_at <= now() && $this->unpublished_at >= now();
    }

    /**
     * Determine if the report is unpublished.
     *
     * @return bool
     */
    public function isUnpublished()
    {
        return ! $this->isPublished();
    }

    /**
     * Determine if the report is sensitive.
     *
     * @return bool
     */
    public function isSensitive()
    {
        return $this->sensitive;
    }

    /**
     * The report filename.
     *
     * @param string $prefix
     * @param string $extension
     * @return string
     */
    public function getFilename($prefix = '', $extension = 'xlsx')
    {
        $path = empty($prefix) ? '' : rtrim($prefix, '\/\\').DIRECTORY_SEPARATOR;
        $file = class_basename($this->class).'_'.now()->format('YmdHis');
        $extension = ltrim($extension, '.');

        return "{$path}{$file}.{$extension}";
    }

    /**
     * Little helper function to take care a lot of the settings.
     * (using a more verbose name to avoid Eloquent naming collisions into the future).
     *
     * @param string $class
     * @param array $overrides
     * @return Report
     */
    public static function addReport(string $class, array $overrides = []): Report
    {
        /** @var static $report */
        $report = static::query()
            ->create(array_merge([
                'name' => trim(preg_replace(['/([A-Z])/', '/Report$/'], [' $1', ''], class_basename($class))),
                'class' => $class,
                'params' => [],
                'status' => 'active',
                'sensitive' => 0,
                'published_at' => now(),
                'unpublished_at' => today()->startOfYear()->addYears(10),
            ], $overrides));

        return $report;
    }

    /**
     * Little helper function for removing a report.
     * Thought it'd be nice to have a sister to addReport.
     * (using a more verbose name to avoid Eloquent naming collisions into the future).
     *
     * @param string $class
     * @return bool
     */
    public static function removeReport(string $class): bool
    {
        return static::query()
            ->where('class', $class)
            ->delete();
    }
}
