<?php

namespace App\Entities\Customer;

use App\Models\Customer\ClientModel;

class ClientEntity extends CustomerEntity
{
    const PK = ClientModel::PK;
    const TITLE = ClientModel::TITLE;
    protected $attributes = [
        'site' => SITES['prime'],
        'name' => '',
        'phone' => '',
        'email' => 'test@example.com',
        'role' => [],
        'account_balance' => 0,
        'coupon_balance'  => 0,
        'point_balance'   => 0,
        'status' => STATUS['AVAILABLE'],
        'history' => ''
    ];
    public function __construct(array|null $data = null)
    {
        parent::__construct($data);
    }

    final public function getUserUid(): int|null
    {
        return $this->attributes['user_uid'] ?? null;
    }
    //기본기능
    public function getCustomTitle(mixed $title = null): string
    {
        return sprintf("[%s]%s", $this->getSite(), $title ? $title : $this->getTitle());
    }
    public function getName(): string
    {
        return $this->attributes['name'];
    }
    public function getSite(): string
    {
        return $this->attributes['site'];
    }
    public function getAccountBalance(): int
    {
        return $this->attributes['account_balance'] ?? 0;
    }
    public function getCouponBalance(): int
    {
        return $this->attributes['coupon_balance'] ?? 0;
    }
    public function getPointBalance(): int
    {
        return $this->attributes['point_balance'] ?? 0;
    }
    public function getHistory(): string|null
    {
        return $this->attributes['history'];
    }
    /*
     * 사용자의 역할을 배열 형태로 반환합니다. 
     * DB의 JSON 또는 CSV 형식 데이터를 모두 배열로 복구할 수 있는 로직을 포함합니다.
     * @return array
     */
    public function getRole(): array
    {
        $role = $this->attributes['role'] ?? null;
        // 1. 이미 배열인 경우 (방어적 코딩)
        if (is_array($role)) {
            return array_filter($role);
        }
        // 2. 문자열 데이터인 경우 처리
        if (is_string($role) && !empty($role)) {
            // 2-a. JSON 디코딩 시도 (기존 DB의 JSON 형식 처리)
            $decodedRole = json_decode($role, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decodedRole)) {
                return $decodedRole;
            }
            // 2-b. JSON이 아니면 CSV로 가정하고 변환
            $parts = explode(DEFAULTS["DELIMITER_ROLE"], $role);
            // 각 요소의 불필요한 공백과 따옴표 제거
            $cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $parts);
            return array_filter($cleanedRoles);
        }
        // 3. 변환에 실패했거나 데이터가 없는 경우 빈 배열 반환
        return [];
    }
    // --- Setter Methods ---

    /**
     * Role 데이터가 Entity에 설정될 때 호출되어, 입력된 CSV/JSON 문자열을 정리 후 
     * DB에 적합한 CSV 문자열로 최종 저장합니다.
     * @param mixed $role 입력 데이터 (문자열 또는 배열)
     */
    public function setRole(mixed $role)
    {
        $roleArray = [];
        // 입력된 데이터가 문자열인 경우에만 trim 및 explode 처리
        if (is_string($role)) {
            // trim()은 여기서 안전하게 호출됩니다.
            $cleanRoleString = trim($role, " \t\n\r\0\x0B\"");
            if (!empty($cleanRoleString)) {
                // 문자열을 구분자로 분리하여 배열로 만듭니다.
                $roleArray = explode(DEFAULTS["DELIMITER_ROLE"], $cleanRoleString);
            }
        }
        // 입력된 데이터가 이미 배열인 경우 (modify_process에서 $formDatas가 배열로 넘어옴)
        elseif (is_array($role)) {
            $roleArray = $role;
        }
        // 배열의 각 요소를 정리
        $cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $roleArray);
        $roleArray = array_filter($cleanedRoles);
        // 최종적으로 DB에 삽입될 단일 CSV 문자열로 변환하여 저장합니다.
        $this->attributes['role'] = implode(DEFAULTS["DELIMITER_ROLE"], $roleArray);
    }
}
