<?php

namespace xmvc;

/**
 * 验证类
 *
 * @version 1.0
 */

class Valid
{
    /** 错误标识 */
    protected string $errorCustomTag = '';
    public function __construct()
    {
        $this->errorCustomTag = 'valid_error_messges_' . uniqid();
    }

    /**
     * 验证 & 将符合规则的值转换成对应的变量
     * - check($var, ['type'=>'int']); check(变量,规则) 两个参数
     * - check($arr, $key, ['type'=>'int']); check(数组, 数组的键, 规则) 三个参数
     * - check($a, ['type'=>'int']); 如果 $a = '123' 符合规则, 并被转化成 $a = 123;
     * @param mixed $value
     * @param array $rules
     * @return boolean
     */
    public function check(...$args): bool
    {
        $isValided = true;
        $argsCount = count($args);
        if ($argsCount == 2) {
            $value = $args[0];
            $rules = $args[1];
        } elseif ($argsCount == 3) {
            $rules = $args[2];
            if ((!isset($args[0][$args[1]]) || $args[0][$args[1]] == '') && isset($rules['must']) && $rules['must']) {
                $this->error(isset($rules['mustMsg']) ?: lg('必须传入一个非空值'), !isset($args[0][$args[1]]) ? 'NULL' : '');
                $value = null;
                $isValided = false;
            } elseif (isset($args[0][$args[1]])) {
                $value = $args[0][$args[1]];
            } else {
                $value = null;
                $isValided = false;
            }
        }
        $msg = isset($rules['msg']) ? $rules['msg'] : '';
        if ($isValided) {
            if (isset($rules['type'])) {
                switch ($rules['type']) {
                    case 'int':
                    case 'double':
                    case 'number':
                        if (!is_numeric($value)) {
                            $this->error($msg ?: lg('必须为数字'), $value);
                            $value = null;
                            $isValided = false;
                        } else {
                            $value *= 1;
                            if ($rules['type'] == 'int' && !is_int($value)) {
                                $this->error($msg ?: lg('必须为整型数字'), $value);
                                $value = null;
                                $isValided = false;
                            }
                            break;
                        }
                        break;
                    case 'date':
                        $format = cfg('date.dateFormat');
                        $d = \DateTime::createFromFormat($format, $value);
                        if (!$d || $d->format($format) !== $value) {
                            $this->error($msg ?: lg('必须为日期格式') . ' ' . $format, $value);
                            $value = null;
                            $isValided = false;
                        }
                        break;
                    case 'datetime':
                        $format = cfg('date.dateTimeFormat');
                        $d = \DateTime::createFromFormat($format, $value);
                        if (!$d || $d->format($format) !== $value) {
                            $this->error($msg ?: lg('必须为日期时间格式') . ' ' . $format, $value);
                            $value = null;
                            $isValided = false;
                        }
                        break;
                    case 'time':
                        $format = cfg('date.timeFormat');
                        $d = \DateTime::createFromFormat($format, $value);
                        if (!$d || $d->format($format) !== $value) {
                            $this->error($msg ?: lg('必须为时间格式') . ' ' . $format, $value);
                            $value = null;
                            $isValided = false;
                        }
                        break;
                }
            } else {
                $rules['type'] = 'string';
            }
        }
        if ($isValided && isset($rules['min'])) {
            if ($value < $rules['min']) {
                $this->error($msg ?: lg('必须') . ' >= ' . $format, $value);
                $value = null;
                $isValided = false;
            }
        }
        if ($isValided && isset($rules['max'])) {
            if ($value > $rules['max']) {
                $this->error($msg ?: lg('必须') . ' <= ' . $format, $value);
                $value = null;
                $isValided = false;
            }
        }
        if ($isValided && isset($rules['minLen'])) {
            if (strlen($value) < $rules['minLen']) {
                $this->error($msg ?: lg('长度') . ' ' . lg('必须') . ' >= ' . $format, $value);
                $value = null;
                $isValided = false;
            }
        }
        if ($isValided && isset($rules['maxLen'])) {
            if (strlen($value) > $rules['maxLen']) {
                $this->error($msg ?: lg('长度') . ' ' . lg('必须') . ' <= ' . $format, $value);
                $value = null;
                $isValided = false;
            }
        }
        return $isValided;
    }
    protected function error(string $message, mixed $value)
    {
        ErrorClass::setErrorCustomPool($this->errorCustomTag, $message, ['value' => $value], [__FILE__]);
    }

    /**
     * 验证错误信息
     */
    public function errorInfo(): array|null
    {
        return ErrorClass::getErrorCustomPool($this->errorCustomTag);
    }
}
