<?php

namespace App\FrontModule\Presenters;

use App\Model\Exceptions\BattleNet\AlreadyConnectedBattleNetAccountException;
use App\Model\Exceptions\BattleNet\AuthorizationRequiredException;
use App\Model\Exceptions\BattleNet\UnknownBattleNetAccountIdException;
use App\Model\Exceptions\Steam\AlreadyConnectedSteamAccountException;
use App\Model\Exceptions\Steam\AuthenticationFailedException;
use App\Model\Exceptions\Steam\AuthenticationRequiredException;
use App\Model\Exceptions\Steam\UnknownSteamIdException;
use App\Components\Forms\BootstrapForm;
use App\Components\Forms\RegisterFormFactory;
use App\Components\Forms\SignFormFactory;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use Nette;

class AuthPresenter extends FrontBasePresenter
{
    protected $publicAccess = true;

    /** @var  SignFormFactory */
    protected $signFormFactory;
    /** @var  RegisterFormFactory */
    protected $registerFormFactory;

    public function injectForms(SignFormFactory $signFormFactory, RegisterFormFactory $registerFormFactory)
    {
        $this->signFormFactory = $signFormFactory;
        $this->registerFormFactory = $registerFormFactory;
    }

    protected function startup()
    {
        parent::startup();

        // logged in user should not get here
        if ($this->user->isLoggedIn()) {
            $this->user->logout(true);
        }
    }

    public function actionIn()
    {
        $this->pageHeader = 'Auth in';
    }

    public function actionRegister()
    {
        $this->pageHeader = 'Registration';
    }

    public function actionSteam()
    {
        $backlink = $this->link('//this');
        try {
            $userEntity = $this->userFacade->getUserAccountReader()->steamAuth($backlink);
        } catch (AuthenticationRequiredException $e) {
            $url = $this->userFacade->getUserAccountReader()->getSteamAuthRedirectUrl($backlink);
            $this->redirectUrl($url);
        } catch (UnknownSteamIdException $e) {
            $this->flashMessage('Your steam account is not registered here.');      // todo: add better message and new registration option
            $this->redirect('Auth:in');
        } catch (AuthenticationFailedException $e) {
            $this->flashMessage('Steam response was not handled correctly. Try it again please.');
            $this->redirect('Auth:in');
        }

        $this->user->login($userEntity);
        $this->redirect('Homepage:');
        $this->pageHeader = 'Steam auth';
    }

    public function actionSteamRegister()
    {
        $this->setView('steam');
        $backlink = $this->link('//this');
        try {
            $userEntity = $this->userFacade->getUserAccountWriter()->registerThroughSteam($backlink);
        } catch (AuthenticationRequiredException $e) {
            $url = $this->userFacade->getUserAccountReader()->getSteamAuthRedirectUrl($backlink);
            $this->redirectUrl($url);
        } catch (AlreadyConnectedSteamAccountException $e) {
            $this->flashMessage('Your steam account is already connected to some guild gate account.');
            $this->redirect('Auth:register');
        } catch (AuthenticationFailedException $e) {
            $this->flashMessage('Steam response was not handled correctly. Try it again please.');
            $this->redirect('Auth:register');
        }

        $this->user->login($userEntity);
        $this->redirect('Homepage:');
        $this->pageHeader = 'Steam registration';
    }

    public function actionBattleNet()
    {
        $backlink = $this->link('//this');
        try {
            $userEntity = $this->userFacade->getUserAccountReader()->battleNetAuth($backlink, 'eu');
        } catch (AuthorizationRequiredException $e) {
            $url = $this->userFacade->getUserAccountReader()->getBattleNetAuthorizationUrl($backlink, 'eu');
            $this->redirectUrl($url);
        } catch (UnknownBattleNetAccountIdException $e) {
            $this->flashMessage('Your BattleNet account is not registered here.');      // todo: add better message and new registration option
            $this->redirect('Auth:in');
        } catch (IdentityProviderException $e) {
            $this->flashMessage('Refresh protection.', 'error');
        }

        $this->user->login($userEntity);
        $this->redirect('Homepage:');
        $this->pageHeader = 'Battle.new auth';
    }

    public function actionBattleNetRegister()
    {
        $this->setView('battleNet');
        $backlink = $this->link('//this');
        try {
            $userEntity = $this->userFacade->getUserAccountWriter()->registerThroughBattleNet($backlink, 'eu');
        } catch (AuthorizationRequiredException $e) {
            $url = $this->userFacade->getUserAccountReader()->getBattleNetAuthorizationUrl($backlink, 'eu');
            $this->redirectUrl($url);
        } catch (AlreadyConnectedBattleNetAccountException $e) {
            $this->flashMessage('Your BattleNet account is already connected to some guild gate account.');
            $this->redirect('Auth:register');
        } catch (IdentityProviderException $e) {
            $this->flashMessage('Refresh protection.', 'error');
            $this->redirect('Auth:register');
        }

        $this->user->login($userEntity);
        $this->redirect('Homepage:');
        $this->pageHeader = 'battle.new registration';
    }

    /**
     * @return BootstrapForm
     */
    protected function createComponentRegisterForm()
    {
        $form = $this->registerFormFactory->create();
        $form->onSuccess[] = function () {
            $this->redirect('Homepage:');
        };

        return $form;
    }

    /**
     * @return BootstrapForm
     */
    protected function createComponentSignInForm()
    {
        $form = $this->signFormFactory->create();
        $form->onSuccess[] = function () {
            $this->redirect('Homepage:');
        };

        return $form;
    }
}
