<?php

namespace App\Traits;

use ErrorException;
use ReflectionProperty;

trait StaticCreateSelf
{
    public static function create(array $values): self
    {
        $dto = new self();

        foreach ($values as $key => $value) {
            if (property_exists($dto, $key)) {
                $rp = new ReflectionProperty($dto::class, $key);

                try {
                    $traits = class_uses($rp->getType()->getName());
                } catch (ErrorException $e) {
                    $traits = false;
                }

                if ($traits) {
                    if (in_array(StaticCreateSelf::class, $traits)) {
                        if ($value) {
                            if (is_array($value)) {
                                $dto->$key = app($rp->getType()->getName())::create($value);

                                continue;
                            }
                        }
                    }
                }
                $dto->$key = $value;
            }
        }

        return $dto;
    }
}
