<?php

namespace Encore\Admin\Controllers;

use Encore\Admin\Facades\Admin;
use Encore\Admin\Form;
use Encore\Admin\Layout\Content;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Validator;
use App\Services\Common\GeetestService;
use App\Validators\AuthValidatorRequest;

class AuthController extends Controller
{
    /**
     * Show the login page.
     *
     * @return \Illuminate\Contracts\View\Factory|Redirect|\Illuminate\View\View
     */
    public function getLogin()
    {
        if ($this->guard()->check()) {
            return redirect($this->redirectPath());
        }

        return view('admin::login');
    }

    /**
     * Handle a login request.
     *
     * @param Request $request
     *
     * @return mixed
     */
    public function postLogin(AuthValidatorRequest $request, GeetestService $geetestService)
    {
        if (!$geetestService->checkGeetest(config('aix.system.site_safety.site_vo_code.members_login'), GeetestService::KEY_LOGIN_ADMIN)) {
            return $this->sendErrorResponse("验证码不通过,请重新验证", ['is_need_geetest'=>1]);
        }

        $passLen = strlen(request()->password);
        if ($passLen < 6 || $passLen > 16) {
            return $this->sendErrorResponse("密码长度在6-16位之间", ['is_need_geetest'=>1]);
        }

        $credentials = $request->only([$this->username(), 'password']);
        $remember = $request->get('remember', false);

        if ($this->guard()->attempt($credentials, $remember)) {
            admin_toastr(trans('admin.login_successful'));
            $request->session()->regenerate();
            return $this->sendSuccessResponse(['redirect_url'=>url($request->session()->pull('url.redirect_url', $this->redirectPath()))]);
        }
        $data['is_need_geetest']=$geetestService->isNeedGeetest(config('aix.system.site_safety.site_vo_code.members_login'), GeetestService::KEY_LOGIN_ADMIN);
        return $this->sendErrorResponse($this->getFailedLoginMessage(), $data);
    }
    protected function sendSuccessResponse($data = [])
    {
        $responseData['message']='OK';
        $responseData['data']=$data;
        return response()->json($responseData);
    }
    protected function sendErrorResponse($message, $data = [], $status = 400)
    {
        $responseData['message']=$message;
        $responseData['errors']=$data;
        return response()->json($responseData)->setStatusCode($status);
    }

    /**
     * User logout.
     *
     * @return Redirect
     */
    public function getLogout(Request $request)
    {
        $this->guard()->logout();

        $request->session()->invalidate();

        return redirect(config('admin.route.prefix'));
    }

    /**
     * User setting page.
     *
     * @param Content $content
     *
     * @return Content
     */
    public function getSetting(Content $content)
    {
        $form = $this->settingForm();
        $form->tools(
            function (Form\Tools $tools) {
                $tools->disableList();
            }
        );

        return $content
            ->header(trans('admin.user_setting'))
            ->body($form->edit(Admin::user()->id));
    }

    /**
     * Update user setting.
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function putSetting()
    {
        return $this->settingForm()->update(Admin::user()->id);
    }

    /**
     * Model-form for user setting.
     *
     * @return Form
     */
    protected function settingForm()
    {
        $class = config('admin.database.users_model');

        $form = new Form(new $class());

        $form->display('username', trans('admin.username'));
        $form->text('name', trans('admin.name'))->rules('required');
        $form->image('avatar', trans('admin.avatar'));
        $form->password('password', trans('admin.password'))->rules('confirmed|required');
        $form->password('password_confirmation', trans('admin.password_confirmation'))->rules('required')
            ->default(function ($form) {
                return $form->model()->password;
            });

        $form->setAction(admin_base_path('auth/setting'));

        $form->ignore(['password_confirmation']);

        $form->saving(function (Form $form) {
            if ($form->password && $form->model()->password != $form->password) {
                $form->password = bcrypt($form->password);
            }
        });

        $form->saved(function () {
            admin_toastr(trans('admin.update_succeeded'));

            return redirect(admin_base_path('auth/setting'));
        });

        return $form;
    }

    /**
     * @return string|\Symfony\Component\Translation\TranslatorInterface
     */
    protected function getFailedLoginMessage()
    {
        return "账号或者密码错误";
    }

    /**
     * Get the post login redirect path.
     *
     * @return string
     */
    protected function redirectPath()
    {
        if (!Admin::user()->isAdministrator()) {
            $redirectPath = $this->getUserRedirectPath();
            if ($redirectPath) {
                return $redirectPath;
            }
        }
        return '/'.config('admin.route.prefix');
    }
    protected function getUserRedirectPath()
    {
        $menus = Admin::menu();
        $user_menu = [];
        foreach ($menus as $k => $item) {
            if ((!isset($item['status']) || $item['status'] == 1) && Admin::user()->canVisitMenu($item['id'])) {
                if(!isset($item['children'])) {
                    if (url()->isValidUrl($item['uri'])) {
                        $user_menu[] = $item['uri'];break;
                    } else {
                        $user_menu[] = admin_base_path($item['uri']);break;
                    }
                } else {
                    foreach ($item['children'] as $v) {
                        if ((!isset($v['status']) || $v['status'] == 1) && Admin::user()->canVisitMenu($v['id'])) {
                            if (url()->isValidUrl($v['uri'])) {
                                $user_menu[] = $v['uri'];break;
                            } else {
                                $user_menu[] = admin_base_path($v['uri']);break;
                            }
                        }
                    }
                }
            }
        }
        return $user_menu?$user_menu[0]:'';
    }

    /**
     * Send the response after the user was authenticated.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return \Illuminate\Http\Response
     */
    protected function sendLoginResponse(Request $request)
    {
        admin_toastr(trans('admin.login_successful'));

        $request->session()->regenerate();

        return redirect($this->redirectPath());
    }

    /**
     * Get the login username to be used by the controller.
     *
     * @return string
     */
    protected function username()
    {
        return 'username';
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\StatefulGuard
     */
    protected function guard()
    {
        return Auth::guard('admin');
    }
}
