<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;

class Config extends Model
{
    protected $table = 'tb_config';

    public $keyType = 'string';
    public $incrementing = false;
    public $timestamps = false;

    public string $metaKey = 'id';
    public string $metaValue = 'value';
    public string $metaDescription = 'description';
    public string $cacheName = 'config-meta';
    public int $cacheTime = CACHE_EXPIRE_TIME;

    public function __set($name, $value)
    {
        $this->{$name} = $value;
    }

    public function __get($name)
    {
        return ($this->{$name} ?? null);
    }

    /**
     * 모든 관리자 설정 값 조회
     */
    public function getAllMeta(): ?Config
    {
        $cacheName = $this->cacheName;
        if (!$result = Cache::get($cacheName)) {
            $res = $this->get();
            if ($res) {
                foreach ($res as $val) {
                    $this->{$val[$this->metaKey]} = $val[$this->metaValue];
                }
                $result = $this;
                Cache::put($cacheName, $this, $this->cacheTime);
            }
        }
        return $result;
    }

    /**
     * 저장
     */
    public function save($saveData = [], array $attributes = []): void
    {
        if ($saveData && is_array($saveData)) {
            foreach ($saveData as $column => $value) {
                if (array_key_exists($column, $attributes)) {
                    $description = $attributes[$column];
                    $this->_metaUpdate($column, $value, $description);
                }
            }
        }
        Cache::forget($this->cacheName);
        $this->getAllMeta();
    }

    /**
     * 조회
     */
    public function item($column = '', $default = false): mixed
    {
        if (empty($column)) {
            return false;
        }

        $data = $this->getAllMeta();
        if (property_exists($data, $column)) {
            $return = $data->{$column};
        } else {
            $return = $default;
        }

        return $return;
    }

    /**
     * 등록/수정
     */
    private function _metaUpdate($column = '', $value = false, $description = ''): bool|string
    {
        $column = trim($column);
        if (empty($column)) {
            return false;
        }

        $items = $this->getAllMeta();

        if (property_exists($items, $column)) {
            return $this->_updateMeta($column, $value, $description); // 수정
        } else {
            return $this->_addMeta($column, $value, $description); // 새로 추가
        }
    }

    /**
     * 등록
     */
    private function _addMeta($column = '', $value = '', $description = ''): bool
    {
        $column = trim($column);
        if (empty($column)) {
            return false;
        }

        $insertData = [
            $this->metaKey => $column,
            $this->metaValue => $value,
            $this->metaDescription => $description
        ];

        return $this->insert($insertData);
    }

    /**
     * 수정
     */
    private function _updateMeta($column = '', $value = '', $description = ''): bool
    {
        $column = trim($column);
        if (empty($column)) {
            return false;
        }

        $updateData = [
            $this->metaValue => $value,
            $this->metaDescription => $description
        ];

        return $this->where($this->metaKey, $column)->update($updateData);
    }
}
