<?php

declare(strict_types=1);

namespace PpPhp\Core\Designer\Selection;

final class DesignerSelectionTarget
{
    public function __construct(
        private readonly string $targetId,
        private readonly string $componentId,
        private readonly string $componentType,
        private readonly string $label,
        private readonly ?string $part = null,
        private readonly array $path = [],
        private readonly array $meta = []
    ) {}

    public static function page(array $page): self
    {
        $id = (string) ($page['id'] ?? $page['name'] ?? 'page');

        return new self(
            $id,
            $id,
            'page',
            (string) ($page['title'] ?? $page['name'] ?? 'Page'),
            null,
            [],
            ['kind' => 'page']
        );
    }

    public static function component(array $component, array $path = []): self
    {
        $id = (string) ($component['id'] ?? $component['name'] ?? 'component');
        $type = (string) ($component['type'] ?? 'component');
        $label = (string) ($component['label'] ?? $component['name'] ?? $id);

        return new self($id, $id, $type, $label, null, $path, [
            'kind' => 'component',
        ]);
    }

    public static function partTarget(array $component, string $part, string $partId, string $label, array $path = [], array $meta = []): self
    {
        $componentId = (string) ($component['id'] ?? $component['name'] ?? 'component');
        $type = (string) ($component['type'] ?? 'component');

        return new self(
            $componentId . ':' . $part . ':' . $partId,
            $componentId,
            $type,
            $label,
            $part,
            $path,
            array_replace(['kind' => 'part', 'partId' => $partId], $meta)
        );
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['targetId'] ?? ''),
            (string) ($data['componentId'] ?? ''),
            (string) ($data['componentType'] ?? ''),
            (string) ($data['label'] ?? ''),
            isset($data['part']) && $data['part'] !== '' ? (string) $data['part'] : null,
            (array) ($data['path'] ?? []),
            (array) ($data['meta'] ?? [])
        );
    }

    public function targetId(): string { return $this->targetId; }
    public function componentId(): string { return $this->componentId; }
    public function componentType(): string { return $this->componentType; }
    public function label(): string { return $this->label; }
    public function part(): ?string { return $this->part; }
    public function path(): array { return $this->path; }
    public function meta(): array { return $this->meta; }

    public function toArray(): array
    {
        return [
            'targetId' => $this->targetId,
            'componentId' => $this->componentId,
            'componentType' => $this->componentType,
            'label' => $this->label,
            'part' => $this->part,
            'path' => $this->path,
            'meta' => $this->meta,
        ];
    }
}
