<?php

declare(strict_types=1);

namespace Builder\Core\Foundation\Dashboard\Widgets;

use Builder\Core\Foundation\Dashboard\Enums\WidgetWidth;

abstract class Widget
{
    /** Width in the dashboard grid. */
    protected WidgetWidth $width = WidgetWidth::Full;

    /** Optional permission key required to see this widget. */
    protected ?string $permissionRequired = null;

    /** Whether the user can hide this widget via preferences. */
    protected bool $hideable = true;

    /** Sort order within the dashboard grid (ascending). */
    protected int $order = 0;

    /** Unique key identifying this widget. */
    abstract public function getKey(): string;

    /** Human-readable label shown in the widget header / manage-widgets list. */
    abstract public function getLabel(): string;

    /** Vue component name used to render this widget. */
    abstract public function getComponent(): string;

    /**
     * Data passed to the Vue component as the `data` prop.
     *
     * @return array<string, mixed>
     */
    abstract public function getData(): array;

    public function getWidth(): WidgetWidth
    {
        return $this->width;
    }

    /** Permission key required to view this widget, or null for public. */
    public function getPermission(): ?string
    {
        return $this->permissionRequired;
    }

    /** Whether the user can hide this widget. */
    public function isHideable(): bool
    {
        return $this->hideable;
    }

    /** Sort order — lower values appear first. */
    public function getOrder(): int
    {
        return $this->order;
    }

    /** @return array<string, mixed> */
    public function toArray(): array
    {
        return [
            'key' => $this->getKey(),
            'label' => $this->getLabel(),
            'component' => $this->getComponent(),
            'width' => $this->getWidth()->value,
            'data' => $this->getData(),
            'permission' => $this->getPermission(),
            'hideable' => $this->isHideable(),
        ];
    }
}
