<?php

namespace App\DTOs;

use ReflectionClass;
use ReflectionNamedType;

abstract class CommonDTO
{
  protected function __construct(array $datas = [])
  {
    if (empty($datas))
      return;

    $reflection = new ReflectionClass($this);

    foreach ($datas as $key => $value) {
      if (!$reflection->hasProperty($key))
        continue;

      $property = $reflection->getProperty($key);
      $type = $property->getType();
      $assignValue = $value;

      // *_uid 규칙 처리
      if ($value === '' && preg_match('/_uid$/', $key)) {
        if ($type instanceof ReflectionNamedType && $type->allowsNull()) {
          $this->{$key} = null;
          continue;
        }
      }

      // 1) 기존: 빈 문자열('') 처리
      if ($value === '') {
        if ($type instanceof ReflectionNamedType && $type->allowsNull()) {
          $assignValue = null;
        } else {
          $typeName = ($type instanceof ReflectionNamedType) ? $type->getName() : '';
          $assignValue = ($typeName === 'int' || $typeName === 'float') ? 0 : '';
        }
      }
      // 2) 기존: 타입별 캐스팅
      elseif ($type instanceof ReflectionNamedType) {
        $typeName = $type->getName();

        if ($typeName === 'array' && is_string($value)) {
          $assignValue = explode(DEFAULTS["DELIMITER_COMMA"], $value);
        } elseif ($typeName === 'int' && is_numeric($value)) {
          $assignValue = (int) $value;
        } elseif ($typeName === 'float' && is_numeric($value)) {
          $assignValue = (float) $value;
        }
      }

      $this->{$key} = $assignValue;
    }
  }

  public function toArray(): array
  {
    $reflection = new ReflectionClass($this);
    $properties = $reflection->getProperties();
    $result = [];

    foreach ($properties as $property) {
      $name = $property->getName();
      $result[$name] = $this->{$name};
    }

    return $result;
  }
}
