<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */

namespace app\api\validate;

use app\common\enum\YesNoEnum;
use app\common\model\User;
use app\common\service\ConfigService;
use app\common\service\sms\SmsDriver;
use app\common\validate\BaseValidate;

/**
 * 注册验证器
 * Class RegisterValidate
 * @package  app\api\validate
 */
class RegisterValidate extends BaseValidate
{
    protected $rule = [
        'register_source' => 'require',
        'mobile' => 'require|mobile',
        'code' => 'checkCode',
        'password' => 'require|length:6,25|alphaDash|checkComplexity',
        'password_confirm' => 'require|confirm'
    ];

    protected $message = [
        'register_source.require' => '注册来源参数缺失',
        'mobile.require' => '请输入手机号',
        'mobile.mobile' => '无效的手机号',
        'password.require' => '请输入密码',
        'password.length' => '密码须在6-25位之间',
        'password.alphaDash' => '密码须为字母数字下划线或破折号',
        'password_confirm.require' => '请确认密码',
        'password_confirm.confirm' => '两次输入的密码不一致'
    ];

    /**
     * @notes 注册发送验证码场景
     * @return RegisterValidate
     */
    public function sceneCaptcha()
    {
        return $this->only(['mobile']);
    }

    /**
     * @notes 用户注册
     * @return RegisterValidate
     */
    public function sceneRegister()
    {
        return $this->only(['register_source', 'mobile', 'code', 'password', 'password_confirm'])
            ->append('mobile', 'checkMobile|checkConfig');
    }

    /**
     * @notes 校验手机号是否已注册
     * @param $value
     * @return bool|string
     */
    public function checkMobile($value)
    {
        $user = User::where('mobile', $value)->findOrEmpty();
        if(!$user->isEmpty()) {
            return '该手机号已被注册';
        }
        return true;
    }

    /**
     * @notes 校验验证码
     * @param $value
     * @param $rule
     * @param $data
     * @return bool|string
     */
    public function checkCode($value, $rule, $data)
    {
        $smsDriver = new SmsDriver();
        $result = $smsDriver->verify($data['mobile'], $value);
        if($result) {
           return true;
        }
        return '验证码错误';
    }

    /**
     * @notes 检测注册配置
     * @param $value
     * @param $rue
     * @param $data
     * @return bool|string
     */
    public function checkConfig($value, $rue, $data)
    {
        $config = [
            'register_way' => ConfigService::get('config', 'register_way', []),
            'is_mobile_register_code' => ConfigService::get('config', 'is_mobile_register_code', YesNoEnum::YES)
        ];
        // 1-手机号注册
        if(!in_array(1, $config['register_way'])) {
            return '未开启手机号注册';
        }
        if($config['is_mobile_register_code'] && !isset($data['code'])) {
            return '请输入验证码';
        }
        return true;
    }

    /**
     * @notes 校验密码复杂度
     * @param $value
     * @param $rue
     * @param $data
     */
    public function checkComplexity($value, $rue, $data)
    {
        $lowerCase = range('a', 'z');
        $upperCase = range('A', 'Z');
        $numbers = range(0, 9);
        $cases = array_merge($lowerCase, $upperCase);
        $caseCount = 0;
        $numberCount = 0;
        $passwordArr = str_split(trim(($data['password'] . '')));
        foreach ($passwordArr as $value) {
            if (in_array($value, $numbers)) {
                $numberCount++;
            }
            if (in_array($value, $cases)) {
                $caseCount++;
            }
        }
        if ($numberCount >= 1 && $caseCount >= 1) {
            return true;
        }
        return '密码需包含数字和字母';
    }
}