<?php
/**
 * 用户模块公用模型
 */
namespace app\modules\logic\services;
use app\modules\sys\log\ImLog;
use app\modules\common\Helper;
use app\modules\logic\model\UsersModel;
use app\modules\logic\model\UsersShopInfoModel;
use app\modules\logic\model\UsersTechApproveModel;
use app\modules\logic\model\UsersTechInfoModel;
use app\modules\logic\model\ShopRoleModel;
use app\modules\logic\model\UsersTokenModel;
use app\modules\logic\services\AccountService;
use yii\base\Exception;
use Yii;
use yii\db\Query;
class UserService
{

    public static $token_key_shop_pre = 'repucar:shop:token:';
    public static $token_key_tech_pre = 'repucar:tech:token:';

    /**
     *
     * @param $data
     * @return bool|string
     */
    public static function login($data,$app = '')
    {
        if (isset($data['type']) &&  $data['type'] == 2) {
            return self::loginByPhone($data,$app);
        } else {
            return self::LoginByWay($data['username'],$data['password'],$app);
        }
        
    }

    /**
     * 直接用手机号登录，只适用于技师
     * @param $data
     * @return bool|string
     */
    public static function loginByPhone($data,$app = '')
    {
        $conn = Yii::$app->db;
        $sql_chk_phone = "select user_id,password,salt,logintimes,status,type,shop_type from {{%users}} where username=:phone and type=:type";
        $cmd = $conn->createCommand($sql_chk_phone);
        $cmd->bindValue(':phone', $data['username']);
        $cmd->bindValue(':type', $app);
        $rec_username = $cmd->queryOne();
        if (empty($rec_username)) {
            $salt = Helper::genSalt();
            $password = md5(md5('tech' . rand(10000, 999999)) . rand(1, 9999999));
            $insert_data = array(
                'username' => $data['username'],
                'mobile' => $data['username'],
                'password' => $password,
                'salt' => $salt,
                'status' => 0,
                'reg_time' => time(),
                'type' => 'tech',
                'addip' => Helper::getUserIp(),
            );

            $conn = Yii::$app->db;
            $tran = $conn->beginTransaction();
            try {
                $conn->createCommand()->insert('{{%users}}', $insert_data)->execute();
                $uid = $conn->getLastInsertID();
                $tran->commit();
                //更新门店编码
                $conn->createCommand()->update('{{%users}}', ['user_code'=>Helper::autoCtUserCode($uid,0)], ['user_id'=>$uid])->execute(); 
                $login_times = 0;
                //添加用户账户和查询次数限制等用户默认表格
                self::saveCount($uid,'tech');
            } catch (Exception $e) {
                $tran->rollBack();
                Yii::warning($e->getMessage());
                return false;
            }

        } else {
            if ($rec_username['status'] == 1) {
                return 'lock';
            } else {
                $uid = $rec_username['user_id'];
                $login_times = $rec_username['logintimes'];
            }
            if(!empty($app) && $app!=$rec_username['type']){
                 return 'not_exists';
            }
        }
        $token = self::SaveToken($uid);
        $login_log = array(
            'loginlasttime' => time(),
            'logintimes' => $login_times + 1,
        );
        $log = self::updateLog($uid, $login_log);
        if ($log) {
            //获取认证状态
            switch ($app) {
                case 'shop':
                    $UsersShopInfo = new UsersShopInfoModel();
                    $row = $UsersShopInfo->getWidgetRow(['cols'=>['verify_status'],'user_id'=>$uid]);
                    $auth = isset($row['verify_status'])?Helper::authStatus($row['verify_status']):'miss';
                    if(isset($rec_username['shop_type']) && $rec_username['shop_type']==3){
                        $auth = 'pass';
                    }
                    $ret = [
                        'token'=>$token,
                        'auth'=>$auth
                    ];
                    break;
                case 'tech':
                    $UsersTechInfo = new UsersTechInfoModel();
                    $row = $UsersTechInfo->getWidgetRow(['cols'=>['verify_status'],'user_id'=>$uid]);
                    $auth = isset($row['verify_status'])?Helper::authStatus($row['verify_status']):'miss';
                    $ret = [
                        'token'=>$token,
                        'auth'=>$auth
                    ];
                    break;    
                default:
                   $ret =  $token;
            }
            return $ret;
        } else {
            return 'log_error';
        }
    }
    /**
     * 用户名密码校验   仅对未锁定用户进行校验
     * $name            用户名
     * $password        密码
     */
    public static function LoginByWay($username, $password,$app='')
    {
        $conn = Yii::$app->db;
        //正常账户
        $sql_chk_username = "select user_id,password,salt,logintimes,status,type,shop_type from {{%users}} where username=:username and type=:type";
        $cmd = $conn->createCommand($sql_chk_username);
        $cmd->bindValue(':username', $username);
        $cmd->bindValue(':type', $app);
        $rec_username = $cmd->queryOne();
        if (empty($rec_username)) {
            $sql_chk_phone = "select user_id,password,salt,logintimes,status,type,shop_type from {{%users}} where mobile=:phone and type=:type";
            $cmd = $conn->createCommand($sql_chk_phone);
            $cmd->bindValue(':phone', $username);
            $cmd->bindValue(':type', $app);
            $rec_username = $cmd->queryOne();
        }
        $conn->close();
        if (is_array($rec_username) && !empty($rec_username)) {
            //校验账号类型是否正确
            if(!empty($app) && $app!=$rec_username['type']){
                 return 'not_exists';
            }
            
            if ($rec_username['status'] == 1) {
                return 'lock';
            }
            if (md5(md5($password) . $rec_username['salt']) == $rec_username['password']) {
                //登陆成功处理  1.生成登陆token; 2.修改登陆记录
                $token = self::SaveToken($rec_username['user_id'],$rec_username['type']);
                $login_log = array(
                    'loginlasttime' => time(),
                    'logintimes' => $rec_username['logintimes'] + 1,
                );
                $log = self::updateLog($rec_username['user_id'], $login_log);
                if ($log) {
                    $uid = $rec_username['user_id'];
                    //获取认证状态
                    switch ($app) {
                        case 'shop':
                            $UsersShopInfo = new UsersShopInfoModel();
                            $row = $UsersShopInfo->getWidgetRow(['cols'=>['verify_status'],'user_id'=>$uid]);
                            $auth = isset($row['verify_status'])?Helper::authStatus($row['verify_status']):'miss';
                            if(isset($rec_username['shop_type']) && $rec_username['shop_type']==3){
                            $auth = 'pass';
                            }
                            $ret = [
                            'token'=>$token,
                            'auth'=>$auth
                            ];
                        break;
                        case 'tech':
                            $UsersTechInfo = new UsersTechInfoModel();
                            $row = $UsersTechInfo->getWidgetRow(['cols'=>['verify_status'],'user_id'=>$uid]);
                            $auth = isset($row['verify_status'])?Helper::authStatus($row['verify_status']):'miss';
                            $ret = [
                            'token'=>$token,
                            'auth'=>$auth
                            ];
                        break;    
                        default:
                            $ret =  $token;
                        }
                    return $ret;

                } else {
                    return 'log_error';
                }
            } else {
                //登陆失败处理
                return 'pw_error';
            }
        } else {
            return 'not_exists';
        }
    }
    /**
     * 用户名密码校验   仅对未锁定用户进行校验
     * $name            用户名
     * $password        密码
     */
    public static function LoginByUid($user_id,$app='')
    {
        $conn = Yii::$app->db;
        //正常账户
        $sql_chk_username = "select user_id,password,salt,logintimes,status,type,shop_type from {{%users}} where user_id=:user_id and type=:type";
        $cmd = $conn->createCommand($sql_chk_username);
        $cmd->bindValue(':user_id', $user_id);
        $cmd->bindValue(':type', $app);
        $rec_username = $cmd->queryOne();
        $conn->close();
        if (is_array($rec_username) && !empty($rec_username)) {
            //校验账号类型是否正确
            if(!empty($app) && $app!=$rec_username['type']){
                 return 'not_exists';
            }
            if ($rec_username['status'] == 1) {
                return 'lock';
            }
            //登陆成功处理  1.生成登陆token; 2.修改登陆记录
            $token = self::SaveToken($rec_username['user_id'],$rec_username['type']);
            $login_log = array(
                'loginlasttime' => time(),
                'logintimes' => $rec_username['logintimes'] + 1,
            );
            $log = self::updateLog($rec_username['user_id'], $login_log);
            if ($log) {
                $uid = $rec_username['user_id'];
                //获取认证状态
                    switch ($app) {
                        case 'shop':
                            $UsersShopInfo = new UsersShopInfoModel();
                            $row = $UsersShopInfo->getWidgetRow(['cols'=>['verify_status'],'user_id'=>$uid]);
                            $auth = isset($row['verify_status'])?Helper::authStatus($row['verify_status']):'miss';
                            if(isset($rec_username['shop_type']) && $rec_username['shop_type']==3){
                                $auth = 'pass';
                            }
                            $ret = [
                                'token'=>$token,
                                'auth'=>$auth
                            ];
                        break;
                        case 'tech':
                            $UsersTechInfo = new UsersTechInfoModel();
                            $row = $UsersTechInfo->getWidgetRow(['cols'=>['verify_status'],'user_id'=>$uid]);
                            $auth = isset($row['verify_status'])?Helper::authStatus($row['verify_status']):'miss';
                            $ret = [
                                'token'=>$token,
                                'auth'=>$auth
                            ];
                        break;    
                        default:
                            $ret =  $token;
                        }
                    return $ret;
            } else {
                return 'log_error';
            }
        } else {
            return 'not_exists';
        }
    }

    /**
     * 登陆成功,生成并保存token
     * $user_id         用户id
     * LOGIN_EXP_TIME  token最长保存时间，在index.php内定义
     */
    private static function saveToken($user_id,$type =  'shop')
    {
        $redis = Yii::$app->redis;
        $login_key = self::genLoginKey();
        $redis_key_token = md5(md5($user_id) . 'REPUCAR' . rand(100, 999999));
        $token = $redis_key_token . '_user';
        /*保存token到users表*/
        $Users = new UsersModel();
        $Users->saveUs(['token'=>$token],$user_id);
        $token_info = array(
            'user_id' => $user_id,
            'login_key' => $login_key,
        );
        if($type == 'shop'){
            $redis_per = self::$token_key_shop_pre . $redis_key_token;
        }else{
            $redis_per = self::$token_key_tech_pre . $redis_key_token;
        }
        //删除之前token遗留
        if(!empty($user_id) && $type=='tech'){
            $UsersToken = new UsersTokenModel();
            $rows = $UsersToken->getWidgetRows(['cols'=>['id','token','type'],'user_id'=>$user_id]);
            if(!empty($rows)){
                foreach ($rows as $value) {
                    self::delToken($value['token'],$value['type']);
                    $UsersToken->findOne($value['id'])->delete();
                }
            }
            //保存用户token
            $data = [
                'user_id'=>$user_id,
                'type'=>$type,
                'token'=>$token,
                'addtime'=>time(),
            ];
            $UsersToken->saveUs($data);
        }
        //解决技师端不能账号在不同设备上登录
        $redis->set($redis_per, serialize($token_info), 'EX', LOGIN_EXP_TIME);
        return $token;
    }


    /**
     *
     * */
    public static function delToken($token,$type = 'shop')
    {
        $redis = Yii::$app->redis;
        $redis_key_token = explode('_', $token)[0];
        $redis->del($redis_key_token);
        if($type == 'shop'){
            $redis->del(self::$token_key_shop_pre . $redis_key_token);
        }else{
            $redis->del(self::$token_key_tech_pre . $redis_key_token);
        }
    }

    /**
     *  用户登录时生成的login_key
     */
    private static function genLoginKey()
    {
        return time() . '_' . rand(100000, 999999);
    }

    /**
     *添加用户登录记录
     *$user_id      用户id
     *$data         需要修改的数据
     * */
    public static function updateLog($user_id, $data)
    {
        $user_id = intval($user_id);
        $conn = Yii::$app->db;
        $command = $conn->createCommand("select 1 from {{%users}} where user_id='{$user_id}'");
        $exist = $command->queryOne();
        if (!$exist) {
            return false;
        }
        $tran = $conn->beginTransaction();
        try {
            $conn->createCommand()->update('{{%users}}', $data, ['user_id' => $user_id])->execute();
            $tran->commit();
            return true;
        } catch (Exception $e) {
            $tran->rollBack();
            Yii::warning($e->getMessage());
            return false;
        }
    }


    /**
     * 用户名唯一性检查
     *$username     用户名
     * */

    public static function usernameExists($username,$app = 'shop')
    {
        $conn = Yii::$app->db;
        //正常账户
        $sql_chk_username = "select 1 from {{%users}} where username=:username and type=:type";
        $cmd = $conn->createCommand($sql_chk_username);
        $cmd->bindValue(':username', $username);
        $cmd->bindValue(':type', $app);
        $rec_username = $cmd->queryOne();
        $conn->close();
        if ($rec_username) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 用户名唯一性检查
     *$phone     用户手机
     * */
    public static function userPhoneExists($phone,$app = 'shop')
    {
        $conn = Yii::$app->db;
        //正常账户
        $sql_chk_username = "select user_id from {{%users}} where  mobile=:phone and type=:type";
        $cmd = $conn->createCommand($sql_chk_username);
        $cmd->bindValue(':phone', $phone);
        $cmd->bindValue(':type', $app);
        $rec_id = $cmd->queryOne();
        if($rec_id){
           return $rec_id; 
       }else{
            return self::usernameExists($phone,$app);
       }
    }
    /**
     * [checkUnameMobile 校验账号+手机号是否存在]
     * @method  POST
     * @author JOHN.W
     * @version [1.0]
     * @return  [type]          [description]
     */
    public static function checkUnameMobile($username,$mobile,$app = 'shop'){
        $conn = Yii::$app->db;
        //正常账户
        $sql_chk_username = "select user_id from {{%users}} where  mobile=:mobile and username=:username and type=:type";
        $cmd = $conn->createCommand($sql_chk_username);
        $cmd->bindValue(':mobile', $mobile);
        $cmd->bindValue(':username', $username);
        $cmd->bindValue(':type', $app);
        $rec_id = $cmd->queryOne();
        if($rec_id){
           return $rec_id['user_id']; 
       }else{
            return false;
       }
    }
    /**
     * [checkWxOpenId 校验Openid]
     * @method  POST
     * @author JOHN.W
     * @version [1.0]
     * @return  [type]          [description]
     */
    public static function checkWxOpenId($openid,$app='shop'){
        $conn = Yii::$app->db;
        //正常账户
        $sql_chk_username = "select user_id from {{%users}} where  wx_openid=:wx_openid and type=:app";
        $cmd = $conn->createCommand($sql_chk_username);
        $cmd->bindValue(':wx_openid', $openid);
        $cmd->bindValue(':app', $app);
        $rec_id = $cmd->queryOne();
        if($rec_id){
           return $rec_id['user_id']; 
       }else{
            return false;
       }
    }

    /**
     * 用户注册
     *$data     用户数据
     * */
    public static function reg($data)
    {
        $salt = Helper::genSalt();
        $password = md5(md5($data['password']) . $salt);
        $insert_data = array(
            'username' => $data['username'],
            'mobile' => $data['mobile'],
            'password' => $password,
            'salt' => $salt,
            'status' => 0,
            'reg_time' => time(),
            'type' => $data['type'],
            'addip' => Helper::getUserIp(),
            'wx_nick' => isset($data['wx_nick'])?$data['wx_nick']:'',
            'wx_openid' => isset($data['wx_openid'])?$data['wx_openid']:'',
        );
        $flg = 0;
        if($data['type']=='shop'){
            //默认开放为门店注册
            $insert_data['shop_type'] = 2;
            $flg = 2;
        }
        $conn = Yii::$app->db;
        $tran = $conn->beginTransaction();
        try {
            $conn->createCommand()->insert('{{%users}}', $insert_data)->execute();
            $uid = $conn->getLastInsertID();
            $tran->commit();
            if($uid){
                //更新门店编码
                $conn->createCommand()->update('{{%users}}', ['user_code'=>Helper::autoCtUserCode($uid,$flg)], ['user_id'=>$uid])->execute(); 
            }
            $token = self::saveToken($uid,$data['type']);
            self::saveCount($uid);
            //返回是否认证状态
            $ret = [
                'token'=>$token,
                'auth'=>'miss'
            ];
            return $ret;
        } catch (Exception $e) {
            $tran->rollBack();
            Yii::warning($e->getMessage());
            return false;
        }
    }

    /**
     * 添加用户各种初始化数据表
     *$uid       user_id
     *
     * */
    public static function saveCount($uid)
    {
        $conn = Yii::$app->db;
        $tran = $conn->beginTransaction();
        try {
            $conn->createCommand()->insert('{{%account}}', ['user_id' => $uid])->execute();
            $tran->commit();
            return true;
        } catch (Exception $e) {
            $tran->rollBack();
            Yii::warning($e->getMessage());
            return false;
        }
    }


    /**
     * 修改密码
     *$where        用户标志（用户名 username  手机 phone  id user_id ）
     * $password    新密码
     * */

    public static function updatePassWord($where, $password)
    {
        $salt = Helper::genSalt();
        $password = md5(md5($password) . $salt);
        $update_data = array(
            'password' => $password,
            'salt' => $salt,
        );
        $conn = Yii::$app->db;
        $tran = $conn->beginTransaction();
        try {
            $conn->createCommand()->update('{{%users}}', $update_data, $where)->execute();
            $tran->commit();
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
    * 修改账号
    *$where        用户标志（用户名 username  手机 phone  id user_id ）
    * $password    新密码
    * */
    public static function updateMobile($where, $mobile)
    {
        $update_data = array(
            'mobile' => $mobile,
            'username' => $mobile,
        );
        $conn = Yii::$app->db;
        $tran = $conn->beginTransaction();
        try {
            $conn->createCommand()->update('{{%users}}', $update_data, $where)->execute();
            $tran->commit();
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 校验旧密码
     * */
    public static function checkPassWord($user_id, $password)
    {
        $conn = Yii::$app->db;
        //正常账户
        $sql_extra = ' and status=0';
        $sql_chk_username = "select passwd,salt from {{%users}} where user_id=:id " . $sql_extra;
        $cmd = $conn->createCommand($sql_chk_username);
        $cmd->bindValue(':id', $user_id);
        $rec_username = $cmd->queryOne();

        if (empty($rec_username)) {
            return false;
        } elseif ($rec_username['passwd'] == md5(md5($password) . $rec_username['salt'])) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 添加投诉或意见
     * */
    public static function addComplaint($data)
    {
        $conn = Yii::$app->db;
        $tran = $conn->beginTransaction();
        try {
            $conn->createCommand()->insert('{{%opinion}}', $data)->execute();
            $tran->commit();
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 添加 修改 用户设备号
     * */
    public static function addUserJPush($data)
    {
        $connect = Yii::$app->db;
        try {
            $data['user_id'] = intval($data['user_id']);
            $command = $connect->createCommand("select * from {{%users_jpush}} where  user_id='{$data['user_id']}' ");
            $flag = $command->queryOne();
            if ($flag) {
                $connect->createCommand()->update("{{%users_jpush}}", $data, ['user_id' => $data['user_id'],])->execute();
            } else {
                $connect->createCommand()->insert("{{%users_jpush}}", $data)->execute();
            }
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    //获取用户电话
    public static function getUserMobile($user_id)
    {
        $con = Yii::$app->db;
        $user_id = intval($user_id);
        $sql = "select mobile from {{%users}}  where user_id={$user_id} ";
        $command = $con->createCommand($sql);
        $phone = $command->queryScalar();

        return $phone;
    }
    //获取门店用户基本信息
    public static function getShopUserInfo($user_id = 0){
        if(empty($user_id))  return NULL;
        $Users= new UsersModel();
        $UsersShopInfo= new UsersShopInfoModel();
        $u_where = [
            'cols'=>['user_id','parent_id','username','wx_nick','wx_openid','realname','mobile','credit_pay_id','longitude','latitude','role_id','shop_type'],
            'user_id'=>$user_id,
            'type'=>'shop',
        ];
        $uinfo_where = [
            'cols'=>['door_pic','verify_status','name'],
            'user_id'=>$user_id
        ];
        $row = $Users->getWidgetRow($u_where);

        $row['role_name'] = ($row['role_id']==0)?'超级管理员':'--';

        $row_info = $UsersShopInfo->getWidgetRow($uinfo_where);
        if(!empty($row_info['door_pic'])) $row_info['door_pic'] = Helper::getImageUrl($row_info['door_pic']);
        if(!empty($row['role_id'])){
            $ShopRole = new ShopRoleModel();
            $row_pur = $ShopRole->getWidgetRow(['cols'=>['purview','role_name'],'id'=>$row['role_id']]);
            $row['role_name'] = $row_pur['role_name'];
            $pur_arr = explode(',', $row_pur['purview']);
        }
        $ret = [
            'base'=>$row,
            'info'=>$row_info,
            'purview'=>[]
        ];
        if(isset($pur_arr)){
            $ret['purview']=$pur_arr;
        }
        return $ret;
    }
    //获取门店用户基本信息
    public static function getTechUserInfo($user_id = 0){
        if(empty($user_id))  return NULL;
        $Users= new UsersModel();
        $UsersTechInfo= new UsersTechInfoModel();//技师基本信息
        $UsersTechApprove= new UsersTechApproveModel();//技师认证信息
        $u_where = [
            'cols'=>['user_id','username','online_status','wx_nick','wx_openid','realname','mobile','longitude','latitude'],
            'user_id'=>$user_id,
            'type'=>'tech',
        ];
        $approve_where = [
            'cols'=>['yw_id','level_id'],
            'user_id'=>$user_id
        ];
        $row = $Users->getWidgetRow($u_where);
        $row_approve = $UsersTechApprove->getWidgetRow($approve_where);
        if(isset($row_approve['level_id'])){
           $row_approve['tech_level'] = Helper::getTechLevel($row_approve['level_id']);
        }
        $row_detail = $UsersTechInfo->getWidgetRow(['cols'=>['ut_contact','ut_tel','work_type','work_age','ut_footing','crash_save_valid','verify_status'],'user_id'=>$user_id]);
        $ret = [
            'base'=>$row,
            //'account'=>AccountService::accountMoney($user_id),
            'approve'=>$row_approve,
            'detail'=>!empty($row_detail)?$row_detail:[],
        ];
        
        return $ret;
    }
    /*获取门店账号类型*/
    public static function getShopAccountInfo($user_id = 0){
        $Users = new UsersModel();
        $res = $Users->getWidgetRow(['cols'=>['shop_type','parent_id','credit_pay_id','pay_type'],'user_id'=>$user_id,'type'=>'shop']);
        return $res;
    }
    /**
     * [getShopUserId 获取门店ID]
     * @return [type] [description]
     */
    public static function getShopUserId($user_id = 0){
        $row = self::getShopAccountInfo($user_id);
        $rt_shop_user_id = 0;
        switch ($row['shop_type']) {
            case '1':
                $rt_shop_user_id = 0;
                break;
            case '2':
                $rt_shop_user_id = $user_id;
                break;
            case '3':
               $rt_shop_user_id = $row['parent_id'];
                break;    
            default:
               $rt_shop_user_id = 0;
        }
        return $rt_shop_user_id;
    }
}
