<?php

namespace IZON\Admin\Web\Controllers;

use \Exception;
use IZON\MVC\Controller;
use IZON\MVC\HttpRequest;
use IZON\MVC\ModelAndView;
use IZON\Admin\Config;
use IZON\Forms\Form;

use IZON\Admin\Domain\AdminUser;

use \IZON\Admin\Services\SessionService;

/**
 * 
 */
class LoginController implements Controller {

  /**
   * @var SessionService
   */
  protected $sessionService;

  /**
   * defaultni controller na ktery sa ma po loginu presmerovat
   * @var string|null
   */
  protected $redirectCotrollerIdentifier = NULL;

  /**
   * jake view se ma pouzit pro zobrazeni formulare
   * @var string 
   */
  protected $loginFormViewName = "admin/login";

  
  public function __construct(SessionService $sessionService, $redirectCotrollerIdentifier) {
    $this->sessionService = $sessionService;
    $this->redirectCotrollerIdentifier = $redirectCotrollerIdentifier;
  }

  public function login(HttpRequest $request) {
    $loginForm = $this->createLoginForm($request);
    $loginForm->setValues($request->getParameters());

    // neni vyplneny zadny login pravdepodobne je novy dotaz
    if ($loginForm->getField("login")->parse() == '') {
      $modelAndView = new ModelAndView($this->loginFormViewName, ["loginForm" => $loginForm]);
      return $modelAndView;
    }

    // pokusit se prihlasit
    try {
      $this->sessionService->loginUser($loginForm->getField("login")->parse(), $loginForm->getField("password")->parse());
      $modelAndView = $this->redirectModule();
      return $modelAndView;
    } catch (Exception $e) {
      if ($e->getCode() == 100) {
        $loginForm->getField('login')->addError(__("Pro login neexistuje uzivatel."));
      } else if ($e->getCode() == 200) {
        $loginForm->getField('password')->addError(__("Pro login nesouhlasí heslo."));
      } else if ($e->getCode() == 300) {
        $loginForm->getField('login')->addError(__("Pro login neexistuje uzivatel."));
      } else {
        $loginForm->addFormError($e->getMessage());
      }

      $modelAndView = new ModelAndView($this->loginFormViewName, ["loginForm" => $loginForm, "loginError" => true]);
    }

    return $modelAndView;
  }

  protected function createLoginForm(HttpRequest $request) {
    $form = new Form();
    $form->addCharField("login", "Login");
    $form->addPasswordField("password", "Heslo");
    return $form;
  }

  /**
   * 
   * @return ModelAndView
   */
  protected function redirectModule() {
    $loggedUser = $this->sessionService->getLoggedUser();
    return $this->redirectModuleConfig($loggedUser);
  }

  /**
   * get redirect from config
   * @param \IZON\Admin\Domain\AdminUser $loggedUser
   * @return ModelAndView
   */
  protected function redirectModuleConfig(AdminUser $loggedUser) {
    try {
      $redirect = Config::getValue('adminLoginRedirect');
    } catch (\Exception $ex) {
      return ModelAndView::createControllerRedirect($this->redirectCotrollerIdentifier, []);
    }
    $redirectConfig = NULL;
    // config for user
    if (isset($redirect['user'][$loggedUser->getId()])) {
      $redirectConfig = $redirect['user'][$loggedUser->getId()];
      if (!$loggedUser->getSuperuser()) {
        $hasAccess = FALSE;
        // check permisions for module
        foreach ($loggedUser->getRoles() as $role) {
          foreach ($role->getModules() as $module) {
            if ($module->getIdentifier() == $redirectConfig['module']) {
              $hasAccess = true;
            }
          }
        }
        // access denied
        if(!$hasAccess) {
          $redirectConfig = NULL;
        }
      }
    }
    if (empty($redirectConfig)) {
      // role redirect config 
      foreach ($loggedUser->getRoles() as $role) {
        if (isset($redirect['role'][$role->getId()])) {
          $currentRedirect = $redirect['role'][$role->getId()];
          if(empty($roleRedirect)) {
            $redirectConfig = $currentRedirect;
          } elseif ($roleRedirect['priority'] < $currentRedirect['priority']) {
            $redirectConfig = $currentRedirect;
          }
        }
      }
    }
    if (!empty($redirectConfig)) {
      return $this->createRedirect($redirectConfig);
    }
    return ModelAndView::createControllerRedirect($this->redirectCotrollerIdentifier, []);
  }

  protected function createRedirect($config) {
    $identifier = \IZON\Admin\DI\moduleIdentifier($config['controller'], $config['module']);
    $params = !empty($config['parameters']) ? $config['parameters'] : [];
    if (!isset($params['action'])) {
      $params['action'] = 'execute';
    }
    return new ModelAndView($identifier, $params, true);
  }

}
