<?php

namespace App\Api\Controllers;

use App\Http\Controllers\BaseApiController;
use App\Models\DoctorModel;
use App\Models\PharmacyModel;
use App\Models\User;
use App\Services\SmsService;
use Illuminate\Http\Request;

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 response()->json(['error' => '手机号不能为空']);
        }

        // 验证手机号格式
        if (! preg_match('/^1[3-9]\d{9}$/', $mobile)) {
            return response()->json(['error' => '手机号格式不正确']);
        }

        // TODO 增加手机验证码发送频率限制

        // 检查手机号在医师或者药店表中是否存在
        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('手机号不存在');
            }
        } else {
            return $this->failed('登录类型错误');
        }

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

        // 存储验证码和有效期（10分钟）
        cache()->put("sms_verification_code_{$login_type}_{$mobile}", $verificationCode, 600); // 600秒 = 10分钟

        $templateName = 'verification_code';
        $templateData = ['code' => $verificationCode];
        $smsService = new SmsService();
        $response = $smsService->sendSms($mobile, $templateName, $templateData);

        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');
        if (! $mobile || ! $login_type || ! $code) {
            return $this->failed('参数错误');
        }

        $verificationCode = cache()->get("sms_verification_code_{$login_type}_{$mobile}");
        if ($verificationCode != $code) {
            return $this->failed('验证码错误');
        }
        // 验证手机号是否存在
        if ($login_type == User::LOGIN_TYPE_PHARMACY) {
            $pharmacy = PharmacyModel::query()->where('mobile', $mobile)->first();
            if (! $pharmacy) {
                return $this->failed('手机号不存在');
            }
            $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('手机号不存在');
            }
            $doctor->user_id = $authInfo->id;
            $doctor->save();
        } 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,
        ]);
    }
}
