<?php

declare (strict_types=1);

namespace Seka\Portal\Modul\Terminy\Entities\Dtos;

use Spatie\LaravelData\Casts\Cast;
use Spatie\LaravelData\Casts\Uncastable;
use Spatie\LaravelData\Exceptions\CannotCastEnum;
use Spatie\LaravelData\Support\DataProperty;
use Throwable;
use UnitEnum;

/**
 * Class UnitEnumCast
 */
class UnitEnumCast implements Cast
{
    /**
     * @param string|null $type
     */
    public function __construct(
        protected ?string $type = null,
    ) {}

    /**
     * @throws \Spatie\LaravelData\Exceptions\CannotCastEnum
     */
    public function cast(DataProperty $property, mixed $value, array $context): UnitEnum|Uncastable
    {
        $type = $this->type ?? $property->type->findAcceptedTypeForBaseType(UnitEnum::class);

        if ($type === null) {
            return Uncastable::create();
        }

        /** @var class-string<\UnitEnum> $type */
        try {
            return collect($type::cases())->filter(fn($case) => $case->name == $value)->first();
        } catch (Throwable $e) {
            throw CannotCastEnum::create($type, $value);
        }
    }
}
