<?php

namespace Modules\Base\Http\Controllers\Api;

use Illuminate\Support\Facades\Auth;
use Modules\Base\Entities\User;
use Modules\Base\Http\Requests\AuthorizationRequest;
use Modules\Base\Http\Requests\OpenloginRequest;
use Modules\Base\Services\NewOpenloginService;
use Modules\Base\Transformers\AccessTokenTransformer;

class AuthorizationsController extends ApiController
{
    /**
     * 登陆
     *
     * @param AuthorizationRequest $request
     *
     * @return mixed
     *
     * @OA\Post(
     *     tags={"用户"},
     *     summary="用户登陆",
     *     path="/api/base/authorizations",
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/x-www-form-urlencoded",
     *             @OA\Schema(
     *                 type="object",
     *                 required={"phone","password"},
     *                 @OA\Property(
     *                     property="phone",
     *                     ref="#/components/schemas/phone"
     *                 ),
     *                 @OA\Property(
     *                     property="password",
     *                     ref="#/components/schemas/password"
     *                 ),
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *          response="201",
     *          description="登陆成功",
     *          @OA\MediaType(
     *              mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(property="data", type="object", ref="#/components/schemas/Token")
     *              )
     *          )
     *      )
     * )
     */
    public function store(AuthorizationRequest $request)
    {
        $user = User::query()->where('phone', $request->phone)->first();

        if (!$user) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'phone' => ['验证失败，用户不存在'],
            ]);
        }

        if ($user->password != \Illuminate\Support\Facades\Hash::check($request->password, $user->password)) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'password' => ['密码错误'],
            ]);
        }

        return $this->response->item($user, new AccessTokenTransformer())->setStatusCode(201);
    }

    /**
     * @param $type
     * @param OpenloginRequest $request
     * @param OpenloginService $openlogin
     *
     * @throws \Throwable
     *
     * @return \Dingo\Api\Http\Response
     *
     * @OA\Post(
     *     tags={"用户"},
     *     summary="第三方账号登陆",
     *     path="/api/base/authorizations/openlogin/{type}",
     *     @OA\Parameter(
     *         name="type",
     *         in="path",
     *         description="第三方登陆类型",
     *         required=true,
     *         @OA\Schema(
     *             type="string",
     *         )
     *     ),
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/x-www-form-urlencoded",
     *             @OA\Schema(
     *                 type="object",
     *                 @OA\Property(
     *                     property="code",
     *                     type="string"
     *                 ),
     *                 @OA\Property(
     *                     property="bind",
     *                     type="string",
     *                     description="是否是绑定操作,如果是传1，否则可不传"
     *                 )
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *          response="201",
     *          description="登陆成功",
     *          @OA\MediaType(
     *              mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(property="data", type="object", ref="#/components/schemas/Token")
     *              )
     *          )
     *      )
     * )
     */
    public function openlogin($type, OpenloginRequest $request, NewOpenloginService $openlogin)
    {
        if ($request->get('bind', false)) {
            $user = auth('api')->user();
            throw_if(!$user, '\Exception', '没有登陆');
        } else {
            $user = null;
        }
        $user = $openlogin->login($type, $request->all(), $user);

        return $this->response->item($user, new AccessTokenTransformer())->setStatusCode(201);
    }

    /**
     * 登陆
     *
     * @param SmsLoginRequest $request
     *
     * @return mixed
     *
     * @OA\Post(
     *     tags={"用户"},
     *     summary="短信登陆",
     *     path="/api/base/authorizations/sms",
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/x-www-form-urlencoded",
     *             @OA\Schema(
     *                 type="object",
     *                 required={"phone","password"},
     *                 @OA\Property(
     *                     property="phone",
     *                     ref="#/components/schemas/phone"
     *                 ),
     *                 @OA\Property(
     *                     property="code",
     *                     ref="#/components/schemas/phone_code"
     *                 ),
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *          response="201",
     *          description="登陆成功",
     *          @OA\MediaType(
     *              mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(property="data", type="object", ref="#/components/schemas/Token")
     *              )
     *          )
     *      )
     * )
     */
    public function smsLogin(SmsLoginRequest $request)
    {
        $user = User::where('phone', $request->phone)->first();
        if (!$user) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'phone' => ['验证失败，手机号不存在'],
            ]);
        }

        abort_if($user->is_blocked, 500, '账户已经停用');

        return $this->response->item($user, new AccessTokenTransformer())->setStatusCode(201);
    }

    /**
     * @return mixed
     *
     * @OA\Put(
     *     tags={"用户"},
     *     summary="刷新TOKEN",
     *     path="/api/base/authorizations/current",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Response(
     *          response="200",
     *          description="刷新成功",
     *          @OA\MediaType(
     *              mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(property="data", type="object", ref="#/components/schemas/Token")
     *              )
     *          )
     *      )
     * )
     */
    public function update()
    {
        return $this->response->item(auth('api')->user(), new AccessTokenTransformer())->setStatusCode(201);
    }

    /**
     * @return mixed
     *
     * @OA\Delete(
     *     tags={"用户"},
     *     summary="用户登出",
     *     path="/api/base/authorizations/current",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Response(
     *          response="204",
     *          description="登出成功"
     *      )
     * )
     */
    public function destroy()
    {
        \Auth::logout();

        return $this->response->noContent()->setStatusCode(200);
    }
}
