<?php

namespace App\DTOs\Customer;

use App\DTOs\CommonDTO;

class ClientDTO extends CommonDTO
{
  public ?int $uid = null;
  public ?int $user_uid = null;
  public ?string $site = null;

  // __get이 동작하려면 public이 아닌 protected여야 합니다.
  // public으로 선언되어 있으면 $dto->role 접근 시 __get을 거치지 않고 직접 접근합니다.
  protected ?string $role = null;

  public ?string $name = null;
  public ?string $phone = null;
  public ?string $email = null;
  public ?string $history = null;
  public ?int $account_balance = null;
  public ?int $coupon_balance = null;
  public ?int $point_balance = null;
  public ?string $status = null;

  public function __construct(array $datas = [])
  {
    // 1. [전처리] role이 배열로 들어왔다면 문자열로 변환하여 $datas 덮어쓰기
    if (isset($datas['role']) && is_array($datas['role'])) {
      $datas['role'] = implode(DEFAULTS["DELIMITER_ROLE"], $datas['role']);
    }

    // 2. 변환된 $datas를 가지고 부모(CommonDTO) 생성자 호출
    // 이제 'role'은 문자열이므로 부모 클래스의 Reflection 로직이나 타입 검사를 통과합니다.
    parent::__construct($datas);
  }

  /**
   * role 속성을 읽을 때 자동으로 배열로 변환해서 반환
   */
  public function __get(string $name)
  {
    // role을 요청했고, 실제 데이터가 문자열로 존재한다면 배열로 변환
    if ($name === 'role') {
      if (is_string($this->role)) {
        return explode(DEFAULTS["DELIMITER_ROLE"], $this->role);
      }
      return []; // null이거나 값이 없으면 빈 배열 반환
    }

    // 부모에게 위임 (혹시 CommonDTO에도 __get이 있다면)
    // CommonDTO에 __get이 없다면 이 줄은 에러가 날 수 있으므로,
    // 보통은 아래처럼 처리하거나 속성을 리턴해야 합니다.
    return $this->{$name} ?? null;
  }

  // role 값을 설정할 때도 배열을 받을 수 있게 하려면 __set도 필요할 수 있습니다.
  // (선택 사항)
  public function setRole(array $roles)
  {
    $this->role = implode(DEFAULTS["DELIMITER_ROLE"], $roles);
  }
}
