<?php
namespace DAO;
/**
 * User: liuyuzhen
 * Date: 2018/5/14
 * Time: 17:23
 * Description:
 */
class ShortMessageModel {

    /**
     * 发送验证类短信
     * @param $where
     * @param $messageId
     */
    public function sendSms($where){

        $key = $where['key'];
        $this->validateSendSmsData($where);
        $shortMessageRedis = \Redis\Db11\ShortMessageRedisModel::getInstance();
        $validCode = \Our\Validate::getNumberString();

        $mobile = $where['mobile'];
        $messageType = $where['messageType'];

        $smsTemplate = \Our\SmsTemplateConst::verifyCodeSmsContent;

        $templateId = $smsTemplate['templateId'];
        $param = $smsTemplate['parameters'];
        $param['code'] = $validCode;

        //60秒内锁
        $oneMinuteSendKey = $key.':'.$messageType.':'.$mobile.':currentFlag';
        $isSending = $shortMessageRedis->find($oneMinuteSendKey);
        if($isSending){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::smsIsSending);
        }
        //短信验证码使用次数
        $sendSmsCountForKey = $key .':'.$messageType.':'.$mobile. ':count';
        $sendCount = $shortMessageRedis->find($sendSmsCountForKey);
        if($sendCount&&$sendCount>=\Our\ApiConst::ten){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::smsCountLimitOut);
        }
        if(APP_ENV=='develop'){
            $result = array('status'=>true,'msg'=>'发送成功');
        }else{
            $result = \AliyunSms\Sms::sendSms($mobile,$templateId,$param);
        }
        if($result['status']){
            $shortMessageRedis->update($oneMinuteSendKey,1,\Our\ApiConst::sixty);
            if(!$sendCount) {
                $sendCount = \Our\ApiConst::one;
                $shortMessageRedis->update($sendSmsCountForKey,$sendCount,\Our\ApiConst::oneDaySecond);
            }else{
                $sendCount = $sendCount + \Our\ApiConst::one;
                $expire = $shortMessageRedis->getExpireTime($sendSmsCountForKey);
                $shortMessageRedis->update($sendSmsCountForKey,$sendCount,$expire);
            }
            $messageCode =  $key.':'.$messageType.':'.$mobile.':code';
            $shortMessageRedis->update($messageCode,$validCode,\Our\ApiConst::ten*\Our\ApiConst::sixty);
        }
        return $result;
    }

    /**
     * 发送验证码短信
     * @param $mobile 手机
     * @param $content 内容
     * @return bool
     */
    public function sendValidCodeSmsForPlatform($mobile,$content){
        $smsTemplate = \Our\SmsTemplateConst::verifyCodeSmsContent;

        $templateId = $smsTemplate['templateId'];
        $param = $smsTemplate['parameters'];
        $param['code'] = $content;
        $result = \AliyunSms\Sms::sendSms($mobile,$templateId,$param);
        if($result['status']){
            return true;
        }
        return false;
    }

    /**
     * 发送内容短信
     * @param $mobile 手机号
     * @param $code 短信代码
     * @param $params 参数
     * @return bool 操作结果
     * User: linqin <358887571@qq.com>
     * Date: 2018/11/22 0022
     * Time: 下午 4:53
     */
    public function sendMessageSmsForPlatform($mobile, $code, $params){
        $smsTemplate = \Our\SmsTemplateConst::messageSmsContent;

        $template = $smsTemplate[$code];
        if($template) {
            $templateId = $template['templateId'];
    //        $param = $template['parameters'];
            $result = \AliyunSms\Sms::sendSms($mobile, $templateId, $params);

            if($result['status']){
                return true;
            }
            \Our\Log::getInstance()->write($result['msg']);
        }
        return false;
    }


    /**
     * 验证验证码是否有效
     * @param $where
     * @return bool
     * @throws \Exception
     */
    public function validCode($where){
        if($where['code']=='666666'&&(APP_ENV=='test'||APP_ENV=='develop'||APP_ENV=='pre')){
            return true;
        }
        $this->validateValidCodeData($where);
        $key = $where['key'];
        $shortMessageRedis = \Redis\Db11\ShortMessageRedisModel::getInstance();

        $mobile = $where['mobile'];
        $messageType = $where['messageType'];

        $code = $where['code'];
        $messageCode =  $key.':'.$messageType.':'.$mobile.':code';
        $redisCode = $shortMessageRedis->find($messageCode);
        if(!$redisCode){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyRedisSmsCode);
        }
        if($redisCode!=$code){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongSmsCode);
        }
        return true;
    }

    /**
     * 删除验证码对应缓存
     * @param $key 对应用户权限key
     * @param $mobile 发送验证码的手机号码
     * @param $messageType 对应短信验证码类型
     */
    public function delCodeRedis($key,$mobile,$messageType){
        $messageCode =  $key.':'.$messageType.':'.$mobile.':code';
        $shortMessageRedis = \Redis\Db11\ShortMessageRedisModel::getInstance();
        $shortMessageRedis->tableDel($messageCode);
    }

    /**
     * 验证发送短信数据
     * @param $where
     * @return bool
     * @throws \Exception
     */
    private function validateSendSmsData($where){
        if(!isset($where['mobile'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptySmsMobile);
        }
        if(!\Our\Common::checkMobilePhone($where['mobile'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMobileFormat);
        }
        if(!isset($where['messageType'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptySmsMessageType);
        }
        return true;
    }


    /**
     * 验证短信验证码
     * @param $where 需要验证的数据
     * @return bool
     * @throws \Exception
     */
    private function validateValidCodeData($where){
        $this->validateSendSmsData($where);
        if(!isset($where['code'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptySmsCode);
        }

        if(!\Our\Validate::validNumberStr($where['code'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::codeIsSixNumberString);
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::codeIsSixNumberString);
        }
        return true;
    }

    /**
     * 类实例
     *
     * @var \DAO\UserModel
     */
    private static $_instance = null;

    /**
     * 获取类实例
     *
     * @return \DAO\UserModel
     */
    public static function getInstance() {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

}
