<?php

namespace App\Entities\Customer;

use App\Models\Customer\ClientModel;

class ClientEntity extends CustomerEntity
{
    const PK = ClientModel::PK;
    const TITLE = ClientModel::TITLE;

    protected array $nullableFields = [
        'id',
        'passwd',
    ];

    // ✅ role은 반드시 string 기본값
    protected $attributes = [
        'id' => null,
        'passwd' => null,
        'site' => '',
        'name' => '',
        'phone' => '',
        'email' => '',
        'role' => '',   // ✅ [] 금지
        'account_balance' => 0,
        'coupon_balance' => 0,
        'point_balance' => 0,
        'status' => '',
        'history' => '',
    ];

    public function __construct(array|null $data = null)
    {
        parent::__construct($data);
    }

    public function getUserUid(): int|null
    {
        return $this->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 (string) ($this->attributes['name'] ?? '');
    }

    public function getSite(): string
    {
        return (string) ($this->attributes['site'] ?? '');
    }

    public function getAccountBalance(): int
    {
        return (int) ($this->attributes['account_balance'] ?? 0);
    }

    public function getCouponBalance(): int
    {
        return (int) ($this->attributes['coupon_balance'] ?? 0);
    }

    public function getPointBalance(): int
    {
        return (int) ($this->attributes['point_balance'] ?? 0);
    }

    public function getHistory(): string|null
    {
        return $this->attributes['history'] ?? null;
    }

    /**
     * role을 배열로 반환
     */
    public function getRole(): array
    {
        $role = $this->attributes['role'] ?? null;

        if (is_array($role)) {
            return array_values(array_filter($role, fn($v) => (string) $v !== ''));
        }

        if (is_string($role) && $role !== '') {
            $decoded = json_decode($role, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                $clean = array_map(
                    fn($item) => trim((string) ($item ?? ''), " \t\n\r\0\x0B\""),
                    $decoded
                );
                return array_values(array_filter($clean, fn($v) => $v !== ''));
            }

            $parts = explode(DEFAULTS["DELIMITER_COMMA"], $role);
            $clean = array_map(
                fn($item) => trim((string) ($item ?? ''), " \t\n\r\0\x0B\""),
                $parts
            );
            return array_values(array_filter($clean, fn($v) => $v !== ''));
        }

        return [];
    }

    /**
     * ✅ role은 DB 저장용 CSV 문자열로 반환
     */
    public function setRole($role): string
    {
        $roleArray = [];

        if (is_string($role)) {
            $clean = trim($role, " \t\n\r\0\x0B\"");
            if ($clean !== '') {
                $decoded = json_decode($clean, true);
                if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                    $roleArray = $decoded;
                } else {
                    $roleArray = explode(DEFAULTS["DELIMITER_COMMA"], $clean);
                }
            }
        } elseif (is_array($role)) {
            $roleArray = $role;
        } else {
            $roleArray = [];
        }

        $cleaned = array_map(
            fn($item) => trim((string) ($item ?? ''), " \t\n\r\0\x0B\""),
            $roleArray
        );

        $roleArray = array_values(array_filter($cleaned, fn($v) => $v !== ''));

        return implode(DEFAULTS["DELIMITER_COMMA"], $roleArray);
    }
}
