<?php

namespace App\Api\Controllers;

use App\Http\Controllers\BaseApiController;
use App\Models\AdminUsers;
use App\Models\DoctorModel;
use App\Models\PharmacyModel;
use App\Models\User;
use App\Services\SmsService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Overtrue\EasySms\EasySms;

class UserController extends BaseApiController
{
    public function userInfo()
    {
        $authInfo = auth('api')->user();
        $data = [
            'id' => $authInfo->id,
            'name' => $authInfo->name,
            'nick_name' => $authInfo->nick_name,
            'avatar' => $authInfo->avatar,
            'last_login_type' => $authInfo->last_login_type,
        ];

        return $this->success($data);
    }

    // 小程序静默登录，如果没有记录则生成一条
    public function login(Request $request)
    {
        $code = $request->input('code');
        $credentials = app('wechat.mini_program')->auth->session($code);
        // $credentials['openid'] = 'textopenid';
        if ($credentials['openid'] ?? '') {
            $user = User::firstOrCreate(['openid' => $credentials['openid']]);
            // 追加登录类型到token里面,前端需要带在header头中 Authorization:Bearer Token
            $token = auth('api')->claims(['login_type' => User::LOGIN_TYPE_USER])->fromUser($user);
            $data = $this->respondWithToken($token)->original;

            return $this->success($data);
        } else {
            return $this->fail('登录错误~');
        }
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth('api')->logout();

        return response()->json(['message' => '退出成功~']);
    }

    /**
     * 发送短信接口
     */
    public function smsCode(Request $request)
    {
        // 验证手机号是否存在
        $mobile = $request->input('mobile');
        $login_type = $request->input('login_type');
        if (! $mobile) {
            return $this->failed('手机号不能为空');
        }

        // 验证手机号格式
        if (! preg_match('/^1[3-9]\d{9}$/', $mobile)) {
            return $this->failed('手机号格式不正确');
        }
        // // 增加手机验证码发送频率限制
        // $today = date('Y-m-d');
        // $smsCountKey = "sms_count_{$mobile}_{$today}";
        // $smsCount = cache()->get($smsCountKey, 0);
        // if ($smsCount >= 10) {
        //     return $this->failed('今天该手机号已达到发送次数上限');
        // }
        // 获取当前时间戳
        $currentTime = time();
        // 检查1分钟内是否已发送
        $lastSendTimeKey = "last_sms_time_{$mobile}";
        $lastSendTime = cache()->get($lastSendTimeKey, 0);
        if ($currentTime - $lastSendTime < 60) {
            return $this->failed('请等待60秒后再试');
        }

        // 检查手机号在医师或者药店表中是否存在
        if ($login_type == User::LOGIN_TYPE_PHARMACY) {
            $pharmacy = PharmacyModel::query()->where('mobile', $mobile)->first();
            if (! $pharmacy) {
                return $this->failed('手机号不存在');
            }
        } elseif ($login_type == User::LOGIN_TYPE_DOCTOR) {
            $doctor = DoctorModel::query()->where('mobile', $mobile)->first();
            if (! $doctor) {
                return $this->failed('手机号不存在');
            }
        }

        // 生成短信验证码
        $verificationCode = rand(100000, 999999); // 生成6位随机验证码

        // 存储验证码和有效期（10分钟）
        cache()->put("sms_verification_code_{$mobile}", $verificationCode, 60); // 600秒 = 10分钟
        // cache()->put($smsCountKey, $smsCount + 1, strtotime('tomorrow') - time());
        cache()->put($lastSendTimeKey, $currentTime, 60);

        if (env('SMS_CHANNEL') == 'chengliye') {
            $templateName = 'verification_code';
            $templateData = ['code' => $verificationCode];
            $smsService = new SmsService();
            $response = $smsService->sendSms($mobile, $templateName, $templateData);
            Log::info(json_encode($response));
        } elseif (env('SMS_CHANNEL') == 'qcloud') { // 腾讯短信
            $easySms = new EasySms(config('easysms'));
            $response = $easySms->send($mobile, [
                'content' => "您的验证码为：{$verificationCode}，请勿泄露于他人！",
                'template' => '2311645',
                'data' => [
                    'code' => $verificationCode,
                ],
            ]);
            Log::info(json_encode($response));
        }

        return $this->success('验证码已发送');
    }

    // 角色绑定
    public function bindRole(Request $request)
    {
        $authInfo = auth('api')->user();
        $mobile = $request->input('mobile');
        $login_type = $request->input('login_type');
        $code = $request->input('code');
        $password = $request->input('password'); // 只有药店登录会传passowrd
        if (! $mobile) {
            return $this->failed('请填写手机号');
        }
        if (! $login_type) {
            return $this->failed('登录类型错误');
        }
        if (($login_type != User::LOGIN_TYPE_PHARMACY) && ! $code) {
            return $this->failed('请填写短信验证码');
        }

        $verificationCode = cache()->get("sms_verification_code_{$mobile}");
        // 有密码说明是药店密码登录
        if (! $password && ($verificationCode != $code)) {
            return $this->failed('验证码错误,请重新发送！');
        }

        // 验证通过清除验证码
        cache()->forget("sms_verification_code_{$mobile}");

        // 验证手机号是否存在
        if ($login_type == User::LOGIN_TYPE_PHARMACY) {
            $pharmacy = PharmacyModel::query()->where('mobile', $mobile)->first();
            if (! $pharmacy) {
                return $this->failed('手机号不存在');
            }
            // 密码验证
            if ($password) {
                $adminUserInfo = AdminUsers::where('pharmacy_id', $pharmacy->id)->first();
                $databasePassword = $adminUserInfo->password;
                $flag = app('hash')->driver('bcrypt')->check($password, $databasePassword);
                if (! $flag) {
                    return $this->failed('手机号或者密码错误！');
                }
            }
            // 先把普通用户状态清除
            if ($pharmacy->user_id > 0) {
                $user = User::query()->find($pharmacy->user_id);
                $user->last_login_type = 0;
                $user->save();
            }
            // 把所有user_id:$authInfo->id的置为0
            PharmacyModel::where('user_id', $authInfo->id)->update(['user_id' => 0]);
            // 重新绑定
            PharmacyModel::where('id', $pharmacy->id)->update(['user_id' => $authInfo->id]);
            // $pharmacy->user_id = $authInfo->id;
            // $pharmacy->save();

        } elseif ($login_type == User::LOGIN_TYPE_DOCTOR) {
            $doctor = DoctorModel::query()->where('mobile', $mobile)->first();
            if (! $doctor) {
                return $this->failed('手机号不存在');
            }
            // 先把普通用户清除
            if ($doctor->user_id > 0) {
                $user = User::query()->find($doctor->user_id);
                $user->last_login_type = 0;
                $user->save();
            }

            // 把所有user_id:$authInfo->id的置为0
            DoctorModel::where('user_id', $authInfo->id)->update(['user_id' => 0]);

            $doctor->user_id = $authInfo->id;
            $doctor->save();
            // 清除验证码
            cache()->forget("sms_verification_code_{$mobile}");
        } else {
            return $this->failed('登录类型错误');
        }

        // 绑定角色
        $user = User::query()->find($authInfo->id);
        $user->last_login_type = $login_type;
        if ($user->save()) {
            return $this->success('绑定成功');
        } else {
            return $this->failed('绑定失败');
        }
    }

    /**
     * Refresh a token.
     * 刷新token，如果开启黑名单，以前的token便会失效。
     * 值得注意的是用上面的getToken再获取一次Token并不算做刷新，两次获得的Token是并行的，即两个都可用。
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth('api')->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string  $token
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60,
        ]);
    }
}
