<?php
// +----------------------------------------------------------------------
// | A3Mall
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.a3-mall.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: xzncit <158373108@qq.com>
// +----------------------------------------------------------------------

namespace app\api\service;

use app\common\enum\Terminal as TerminalEnum;
use think\facade\Request;
use app\common\library\file\FileManager;
use app\common\library\utils\Check;
use app\common\facade\Sms as SmsUtils;
use app\common\enum\Sms as SmsEnum;
use app\common\enum\Terminal;
use app\common\enum\User as UserEnum;
use app\common\library\jwt\Token;
use app\common\library\utils\Hash;
use app\common\library\utils\Image;
use app\common\library\utils\Tool;
use app\common\library\utils\Check as CheckUtils;
use app\common\service\Config as ConfigService;
use app\common\model\Users as UsersModel;
use app\common\model\UsersAuth as UsersAuthModel;
use app\common\service\Users as UsersService;
use app\api\model\users\UsersCoupon as UsersCouponModel;
use app\common\model\order\Order as OrderModel;
use app\common\service\promotion\Award as AwardService;
use app\common\service\promotion\Invite as InviteService;

/**
 * @package app\api\service
 * @class User
 * @author xzncit 2024-01-24
 */
class User {

    /**
     * 注册
     * @param array $params
     * @return string
     */
    public static function register($params=[]){
        $salt = Tool::getRands(5);
        $uid = 0;
        if(!empty($params["uid"])){
            $uid = UsersModel::where(["id"=>$params["uid"],"status"=>1])->value("id",0);
        }

        $id = UsersModel::create([
            "username"      => $params["username"],
            "nickname"      => Tool::getNickName(),
            "password"      => Hash::md5($params["password"],$salt),
            "salt"          => $salt,
            "join_ip"       => Request::ip(),
            "login_ip"      => Request::ip(),
            "status"        => 1,
            "terminal"      => Terminal::getTerminalNo(Request::header("Client-Type","h5")),
            "inviter_id"    => $uid,
            "login_time"    => time(),
            "prev_time"     => time(),
            "create_time"   => time(),
            "update_time"   => time(),
            "join_time"     => time()
        ])->id;

        AwardService::reward($id);
        InviteService::reward($id,$uid);
        return Token::set("id",$id);
    }

    /**
     * 登录
     * @param array $params
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function login($params=[]){
        $condition = [];
        if(CheckUtils::mobile($params["username"])){
            $condition[] = ["mobile","=",$params["username"]];
        }else{
            $condition[] = ["username","=",$params["username"]];
        }

        $user = UsersModel::where($condition)->find();
        if(empty($user)){
            throw new \Exception("您输入的帐号不存在",0);
        }

        if($params["scene"] == "code"){
            SmsUtils::verifyStatus(SmsEnum::USER_LOGIN, $params["username"], $params["code"]);
        }else{
            if(Hash::md5($params["password"],$user["salt"]) != $user["password"]){
                throw new \Exception("您输入的密码错误",0);
            }
        }

        $isBind = false;
        if(ConfigService::getArray("users.users_bind_mobile",0) && empty($user["mobile"])){
            $isBind = true;
        }

        $terminal  = TerminalEnum::getTerminalNo(Request::header("Client-Type","h5"));
        UsersModel::where($condition)->save(["login_time"=>time(),"login_ip"=>Request::ip()]);
        $binding = 0;
        if(in_array($terminal,[1,2])){
            $binding = UsersAuthModel::where(["user_id"=>$user["id"],"terminal"=>$terminal])->count() ? 1 : 2;
        }

        return [
            "token"     => Token::set("id",$user["id"]),
            "is_bind"   => $isBind,
            "binding"   => $binding
        ];
    }

    /**
     * 找回密码
     * @param array $params
     * @return bool
     */
    public static function forget($params=[]){
        SmsUtils::verifyStatus(SmsEnum::USER_PASSWORD, $params["username"], $params["code"]);
        $salt = Tool::getRands(5);
        UsersModel::where("mobile",$params["username"])->update([
            "salt"          => $salt,
            "password"      => Hash::md5($params["password"],$salt),
            "update_time"   => time()
        ]);

        return true;
    }

    /**
     * 绑定手机
     * @param array $params
     * @param int $scene_id
     * @return bool
     * @throws \app\common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function bind($params=[],$scene_id=0){
        SmsUtils::verifyStatus($scene_id, $params["username"], $params["code"]);
        $user = UsersModel::where("id",Token::get("id"))->find();
        if(empty($user)){
            throw new \Exception("您还未登录，不允许执行绑定手机操作",0);
        }

        if(!empty($user["mobile"])){
            throw new \Exception("您的帐号已绑定手机，不允许执行此操作",0);
        }

        if(UsersModel::where("mobile",$params["username"])->count()){
            throw new \Exception("申请绑定的手机号已被其他帐号绑定",0);
        }

        UsersModel::where("id",$user["id"])->update([
            "mobile"          => $params["username"],
            "update_time"     => time()
        ]);

        return true;
    }

    /**
     * 修改密码
     * @param array $params
     * @return bool
     * @throws \app\common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function password($params=[]){
        $salt = Tool::getRands(5);
        UsersModel::where("id",UsersService::get("id",0))->update([
            "salt"          => $salt,
            "password"      => Hash::md5($params["password"],$salt),
            "update_time"   => time()
        ]);

        return true;
    }

    /**
     * 获取会员信息
     * @return array
     * @throws \app\common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function center(){
        $user = UsersModel::where("id",Token::get("id"))->find();
        if(empty($user)){
            throw new \Exception("msg:ok",0);
        }

        $coupon = UsersCouponModel::withJoin("coupon")->where([
            ["users_coupon.user_id","=",Token::get("id")],
            ["users_coupon.status","=",0],
            ["users_coupon.end_time",">",time()]
        ])->count();

        return [
            "id"            => $user["id"],
            "username"      => $user["username"],
            "nickname"      => $user["nickname"],
            "gender"        => UserEnum::getGender($user["gender"]),
            "mobile"        => Tool::repeat($user["mobile"]),
            "avatar"        => Image::avatar($user["avatar"]),
            "money"         => $user["money"],
            "score"         => $user["score"],
            "coupon"        => $coupon,
            "order"         => [
                "payment"  => OrderModel::where("user_id",$user["id"])->where("status","in","1,2")->where("pay_status",1)->count(),
                "delivery" => OrderModel::where("user_id",$user["id"])->where("status","=","3")->where("delivery_status",1)->count(),
                "received" => OrderModel::where("user_id",$user["id"])->where("status","in","4,5")->where("collect_status",1)->count(),
                "evaluate" => OrderModel::where("user_id",$user["id"])->where("status","=","6")->where("refund_status",1)->where("evaluate_status","in","1,3")->where("collect_status",2)->count(),
            ],
            "join_time"     => date("Y-m-d H:i:s",$user["join_time"]),
            "is_bind"       => ConfigService::getArray("users.users_bind_mobile",0) && empty($user["mobile"])
        ];
    }

    /**
     * 上传头像
     * @return mixed|string|null
     * @throws \app\common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function avatar(){
        $upload = FileManager::upload("file",0,false,["save"=>false]);
        UsersModel::where("id",UsersService::get("id",0))->update([ "avatar"=>$upload["path"]??"" ]);
        return Image::avatar($upload["path"]??"");
    }

    /**
     * 更新会员信息
     * @param array $params
     * @return null
     */
    public static function field($params=[]){
        $array = [];
        if(isset($params["sex"])){
            $array["gender"] = in_array($params["sex"],[0,1,2]) ? $params["sex"] : 0;
        }

        if(isset($params["nickname"])){
            $params["nickname"] = trim($params["nickname"]);
            if(empty($params["nickname"])){
                throw new \Exception("请填写用户名称",0);
            }

            if(!Check::chsAlphaNum($params["nickname"])){
                throw new \Exception("您填写的用户不合法，用户名称只允许汉字、字母和数字",0);
            }

            $array["nickname"] = $params["nickname"];
        }

        UsersModel::where("id",UsersService::get("id",0))->update($array);
        return null;
    }

}