<?php


namespace App\FrontModule\Presenters;


use App\Model\Exceptions\BattleNet\AlreadyConnectedBattleNetAccountException;
use App\Model\Exceptions\BattleNet\AuthorizationRequiredException;
use App\Model\Exceptions\Db\RecordNotFoundException;
use App\Model\Exceptions\Steam\AlreadyConnectedSteamAccountException;
use App\Model\Exceptions\Steam\AuthenticationFailedException;
use App\Model\Exceptions\Steam\AuthenticationRequiredException;
use App\Components\Forms\AttachCredentialsFormFactory;
use App\Components\Forms\BootstrapForm;
use App\Model\Entities\Security\User as UserEntity;
use App\Model\Enums\FlashMessage;
use App\Model\User;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;


/**
 * Class UserPresenter
 * @property-read User $user
 */
class UserPresenter extends FrontBasePresenter
{
    protected $publicAccess = array('profile');

    /** @var  UserEntity */
    protected $userEntity;

    /**
     * @var AttachCredentialsFormFactory
     * @inject
     */
    public $attachCredentialsFormFactory;

    public function actionProfile($id)
    {
        try {
            $this->userEntity = $this->userFacade->getUserReader()->findUserById($id);
        } catch (RecordNotFoundException $e) {
            $this->error('User not found.');
        }

        $this->pageHeader = $this->userEntity->getNickname();
    }

    public function renderProfile()
    {
        $this->template->profile = $this->userEntity;
        $this->template->isProfileOwner = ($this->user->isLoggedIn() && $this->userEntity->getId() == $this->user->id);
    	$this->template->hasGuildGateAccount = $this->userFacade->getUserAccountReader()->hasGuildGateAccount($this->userEntity);
        $this->template->hasSteamAccount = $this->userFacade->getUserAccountReader()->hasSteamAccount($this->userEntity);
        $this->template->hasBattleNetAccount = $this->userFacade->getUserAccountReader()->hasBattleNetAccount($this->userEntity);
    }

    public function actionAttachSteamAccount()
    {
        /**
         * secured action, user must by logged in
         * @var UserEntity $user
         */
        $user = $this->user->getUserEntity();
        $this->setView('profile');
        $backlink = $this->link('//this');
        try {
            $this->userFacade->getUserAccountWriter()->attachSteamAccount($user, $backlink);
        } catch (AuthenticationRequiredException $e) {
            $url = $this->userFacade->getUserAccountReader()->getSteamAuthRedirectUrl($backlink);
            $this->redirectUrl($url);
        } catch (AlreadyConnectedSteamAccountException $e) {
            $this->flashMessage('Provided steam account is already attached to some account.', FlashMessage::ERROR);
            $this->redirect('User:profile', $this->user->id);
        } catch (AuthenticationFailedException $e) {
            $this->flashMessage('Steam response was not handled correctly. Try it again please.', FlashMessage::ERROR);
            $this->redirect('User:profile', $this->user->id);
        }

        $this->redirect('User:profile', $this->user->id);
    }

    public function actionAttachBattleNetAccount()
    {
        /**
         * secured action, user must by logged in
         * @var UserEntity $user
         */
        $user = $this->user->getUserEntity();
        $this->setView('profile');
        $backlink = $this->link('//this');
        try {
            $this->userFacade->getUserAccountWriter()->attachBattleNetAccount($user, $backlink);
        } catch (AuthorizationRequiredException $e) {
            $url = $this->userFacade->getUserAccountReader()->getBattleNetAuthorizationUrl($backlink);
            $this->redirectUrl($url);
        } catch (AlreadyConnectedBattleNetAccountException $e) {
            $this->flashMessage('Your Battle.net account is already connected to some guild gate account.', FlashMessage::ERROR);
            $this->redirect('User:profile', $this->user->id);
        } catch (IdentityProviderException $e) {
            $this->flashMessage('Refresh protection.', FlashMessage::ERROR);
            $this->redirect('User:profile', $this->user->id);
        }

        $this->redirect('User:profile', $this->user->id);
    }

    /**
     * @return BootstrapForm
     */
    protected function createComponentAttachCredentialsForm()
    {
        $form = $this->attachCredentialsFormFactory->create();

        $form->onSuccess[] = function () {
            $this->redirect('User:profile', $this->user->id);
        };

        return $form;
    }
}