<?php

namespace App\Entities;

use App\Entities\CommonEntity;
use App\Models\UserModel as Model;

class UserEntity extends CommonEntity
{
    const PK = Model::PK;
    const TITLE = Model::TITLE;

    protected array $nullableFields = [
        'mobile',
        // uid 같은 숫자 PK가 nullable이면 여기에 추가
    ];

    // ✅ role은 반드시 "문자열" 기본값 (DB 저장형)
    protected $attributes = [
        'id' => '',
        'passwd' => '',
        'name' => '',
        'email' => '',
        'mobile' => null,
        'role' => '',   // ✅ array 금지
        'status' => '',
    ];

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

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

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

    /**
     * role을 "배열"로 반환 (DB에는 CSV/JSON/배열 무엇이든 복구)
     */
    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 !== '') {
            // JSON 시도
            $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 !== ''));
            }

            // CSV fallback
            $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 [];
    }

    /**
     * ✅ CI4 뮤테이터: "return 값"이 attributes에 저장됨
     * - 빈값이면 기존값 유지 (create에서 required면 validate에서 걸러짐)
     */
    public function setPasswd($password): string
    {
        // null/'' 이면 기존값 유지
        if (!is_string($password) || $password === '') {
            return (string) ($this->attributes['passwd'] ?? '');
        }

        return password_hash($password, PASSWORD_BCRYPT);
    }

    /**
     * ✅ role은 최종적으로 "CSV 문자열"로 저장 (DB 안전)
     */
    public function setRole($role): string
    {
        $roleArray = [];

        if (is_string($role)) {
            $clean = trim($role, " \t\n\r\0\x0B\"");
            if ($clean !== '') {
                // JSON 문자열 가능성도 있어서 먼저 JSON 시도
                $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);
    }
}
