<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\Dashboard;

class DesignerDashboardWidget
{
    public function __construct(
        protected readonly string $id,
        protected readonly string $type,
        protected readonly string $title = '',
        protected readonly array $props = [],
        protected readonly int $span = 4,
        protected readonly array $dataSource = [],
        protected readonly array $events = [],
        protected readonly array $permissions = [],
        protected readonly array $meta = []
    ) {}

    public static function create(string $id, string $type = 'stat_card', string $title = '', array $props = [], int $span = 4): self
    {
        return new self($id, $type, $title !== '' ? $title : self::humanize($id), $props, self::normalizeSpan($span));
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['id'] ?? 'widget'),
            (string) ($data['type'] ?? 'stat_card'),
            (string) ($data['title'] ?? $data['label'] ?? self::humanize((string) ($data['id'] ?? 'widget'))),
            (array) ($data['props'] ?? []),
            self::normalizeSpan((int) ($data['span'] ?? $data['layout']['span'] ?? 4)),
            (array) ($data['dataSource'] ?? []),
            (array) ($data['events'] ?? []),
            (array) ($data['permissions'] ?? []),
            (array) ($data['meta'] ?? [])
        );
    }

    public function id(): string { return $this->id; }
    public function type(): string { return $this->type; }
    public function span(): int { return $this->span; }

    public function withId(string $id): self
    {
        return new self($id, $this->type, $this->title, $this->props, $this->span, $this->dataSource, $this->events, $this->permissions, array_replace($this->meta, ['duplicatedFrom' => $this->id]));
    }

    public function withSpan(int $span): self
    {
        return new self($this->id, $this->type, $this->title, $this->props, self::normalizeSpan($span), $this->dataSource, $this->events, $this->permissions, $this->meta);
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->id,
            'type' => $this->type,
            'title' => $this->title,
            'label' => $this->title,
            'span' => $this->span,
            'layout' => ['span' => $this->span],
            'props' => $this->props,
            'dataSource' => $this->dataSource,
            'events' => $this->events,
            'permissions' => $this->permissions,
            'visible' => true,
            'meta' => $this->meta,
        ];
    }

    protected static function normalizeSpan(int $span): int
    {
        return in_array($span, [3, 4, 6, 8, 9, 12], true) ? $span : 4;
    }

    protected static function humanize(string $value): string
    {
        return ucwords(str_replace(['_', '-'], ' ', $value));
    }
}
