<?php

declare(strict_types=1);

namespace App\Support\References;

final readonly class ResolvedReference
{
    /**
     * @param  array<string, mixed>  $meta
     */
    public function __construct(
        public ReferenceClass $referenceClass,
        public string $rawIdentifier,
        public string $primaryLabel,
        public ?string $secondaryLabel,
        public ReferenceResolutionState $state,
        public ?string $stateLabel,
        public ?ReferenceLinkTarget $linkTarget,
        public ReferenceTechnicalDetail $technicalDetail,
        public array $meta = [],
    ) {}

    public function isLinkable(): bool
    {
        return $this->linkTarget instanceof ReferenceLinkTarget && $this->state->isLinkable();
    }

    public function withLinkTarget(?ReferenceLinkTarget $linkTarget): self
    {
        return new self(
            referenceClass: $this->referenceClass,
            rawIdentifier: $this->rawIdentifier,
            primaryLabel: $this->primaryLabel,
            secondaryLabel: $this->secondaryLabel,
            state: $this->state,
            stateLabel: $this->stateLabel,
            linkTarget: $linkTarget,
            technicalDetail: $this->technicalDetail,
            meta: $this->meta,
        );
    }

    /**
     * @return array{
     *   referenceClass: string,
     *   rawIdentifier: string,
     *   primaryLabel: string,
     *   secondaryLabel: ?string,
     *   state: string,
     *   stateLabel: ?string,
     *   linkTarget: array{targetKind: string, url: string, actionLabel: string, contextBadge: ?string}|null,
     *   technicalDetail: array{displayId: ?string, fullId: string, sourceHint: ?string, copyable: bool, defaultCollapsed: bool},
     *   meta: array<string, mixed>
     * }
     */
    public function toArray(): array
    {
        return [
            'referenceClass' => $this->referenceClass->value,
            'rawIdentifier' => $this->rawIdentifier,
            'primaryLabel' => $this->primaryLabel,
            'secondaryLabel' => $this->secondaryLabel,
            'state' => $this->state->value,
            'stateLabel' => $this->stateLabel,
            'linkTarget' => $this->linkTarget?->toArray(),
            'technicalDetail' => $this->technicalDetail->toArray(),
            'meta' => $this->meta,
        ];
    }
}
