<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

namespace Kufer\KuferTools\Oeffentlich\LoginAnfordern\SendeAutoLoginAnfordern;

use Kufer\KuferTools\Oeffentlich\LoginAnfordern\Utils\HandleLoginAnfordernEingaben as HandleLoginAnfordern;

class SendeAutoLoginAnfordernUseCase extends \Kufer\KuferTools\Basis\UseCase\UseCase
{
  public const DOZ_AUTO_LOGIN = 'dozent';
  public const TN_AUTO_LOGIN = 'teilnehmer';

  
  private $toolSettings;

  
  private $allowedToolGroups;

  public function __construct($request, $pToolSettings)
  {
    parent::__construct($request, new SendeAutoLoginAnfordernResponse());
    $this->toolSettings = $pToolSettings;
    $this->allowedToolGroups = \DBWorkTools::getDefaultInstance()->getBenGruppen4Tools();
  }

  public function hasAccess($pToolSectionId = null)
  {
    if (!$this->isDozentAllowed()
        && !$this->isTeilnehmerAllowed()) {
      return false;
    }

    if ($this->getBenutzergruppe() === static::DOZ_AUTO_LOGIN && !$this->isDozentAllowed()) {
      return false;
    }

    if ($this->getBenutzergruppe() === static::TN_AUTO_LOGIN && !$this->isTeilnehmerAllowed()) {
      return false;
    }

    if (!in_array($this->getBenutzergruppe(), array(static::DOZ_AUTO_LOGIN, static::TN_AUTO_LOGIN))) {
      return false;
    }

    if (!$this->request->isXsrfOk && !$this->request->isRefresh) {
      return false;
    }

    return true;
  }

  private function isDozentAllowed(): bool
  {
    return ((isset($this->toolSettings->dozAutoLogin) && $this->toolSettings->dozAutoLogin) && in_array(KURZ_DOZENT, $this->allowedToolGroups));
  }

  private function isTeilnehmerAllowed(): bool
  {
    return ((isset($this->toolSettings->tnAutoLogin) && $this->toolSettings->tnAutoLogin) && in_array(KURZ_TEILNEHMER, $this->allowedToolGroups));
  }

  public function action()
  {
    $this->setzeMenupunkte();
    $benutzergruppe = $this->getBenutzergruppe();
    $checkEingaben = new HandleLoginAnfordern(
      $this->request->email,
      $this->request->passwort,
      $this->request->passwortWiederholt,
      $this->request->captchaOk,
      $this->request->geschlecht,
      $this->request->name,
      $this->request->vorname,
      $benutzergruppe,
      $this->toolSettings->dseZustimmung4Login,
      $this->request->dseZustimmung,
      $this->toolSettings->freiesPflichtfeldZustimmung4Login,
      $this->request->freiesPflichtfeldZustimmung
    );

    if ($this->request->isRefresh) {
      if (\SessionOperations::getVarValueWTIntern('AutoLoginErfolgreichAngefordert', false)) {
        $this->response->statusCodes[] = HandleLoginAnfordern::ERROR_DOPPELT_ABSENDEN;
      } else {
        $this->getFormValuesToResponse();
        $this->response->statusCodes = $checkEingaben->validateEingaben();
        $this->request->geschlecht = $checkEingaben->getGeschlecht();
      }
    } else {
      $statusCode = $checkEingaben->validateEingaben();
      if (empty($statusCode)) {
        $this->request->geschlecht = $checkEingaben->getGeschlecht();
        $this->response->statusCodes[] = $this->handleSendOptInMail($this->request);
      } else {
        $this->response->statusCodes = $statusCode;
      }
      $this->getFormValuesToResponse();
    }

    $this->response->pwAnzahlZeichen = $this->toolSettings->pwdMinLength;
    $this->response->pwZahlErforderlich = $this->toolSettings->pwdNumbersRequired;
    $this->response->pwGrossKleinBuchstabenErforderlich = $this->toolSettings->pwdLowerUpperRequired;
    $this->response->pwSonderzeichenErforderlich = $this->toolSettings->pwdSpecialCharsRequired;

    $this->response->dozAutoLogin = $this->toolSettings->dozAutoLogin;
    $this->response->tnAutoLogin = $this->toolSettings->tnAutoLogin;

    $this->response->showDseZustimmung = $this->toolSettings->dseZustimmung4Login;
    $this->response->dseZustimmungLink = $this->toolSettings->dseZustimmungLink4Login;

    return $this->response;
  }

  private function getFormValuesToResponse()
  {
    $this->response->geschlecht = $this->request->geschlecht;
    $this->response->name = $this->request->name;
    $this->response->vorname = $this->request->vorname;
    $this->response->login = $this->request->email;
    $this->response->hinweis = isset($this->toolSettings->hint4Login) ? $this->toolSettings->hint4Login : null;
    $this->response->passwort = $this->request->passwort;
    $this->response->passwortWiederholt = $this->request->passwortWiederholt;
    if ($this->toolSettings->SSLLogin) {
      $this->response->https = \ConstantOperations::getHTTPSPath4Url(LOGIN);
    }
    $this->response->dseZustimmungChecked = $this->request->dseZustimmung ? \HTMLOperations::getEmptyAttribute('checked') : '';

    $benutzergruppe = $this->getBenutzergruppe();
    $this->response->benutzergruppeDozSelected = $benutzergruppe === self::DOZ_AUTO_LOGIN;
    $this->response->benutzergruppeTnSelected = $benutzergruppe === self::TN_AUTO_LOGIN;

    if ($this->toolSettings->freiesPflichtfeldZustimmung4Login) {
      $this->response->freiesPflichtfeld = true;
      $this->response->textFreiesPflichtfeld = $this->toolSettings->freiesPflichtfeldZustimmungText4Login;
    } else {
      $this->response->freiesPflichtfeld = false;
      $this->response->textFreiesPflichtfeld = '';
    }

    $this->response->freiesPflichtfeldChecked = $this->request->freiesPflichtfeldZustimmung ? \HTMLOperations::getEmptyAttribute('checked') : '';
  }

  private function handleSendOptInMail($requestObj)
  {
    $pw = \PasswordFactory::getLatest();
    $passwordHashed = $pw->getHash($requestObj->passwort, array());
    $hashversion = $pw::getHashversion();
    $dblOptin = $this->getDblOption($requestObj, $passwordHashed, $hashversion);

    $benutzergruppe = $this->getBenutzergruppe();
    if ($benutzergruppe === self::TN_AUTO_LOGIN) {
      $dbwDoubleOptin = new \DBWorkDblOptinToolTnAutoLoginAnfordern(1, true);
    } else {
      $dbwDoubleOptin = new \DBWorkDblOptinToolDozAutoLoginAnfordern(1, true);
    } 
    $dblOptin->optin = $dbwDoubleOptin->saveDblOptin($dblOptin);

    $result = $this->sendOptInMail($dblOptin, $requestObj->email);

    if (!$result) {
      $dbwDoubleOptin->deleteByOptin($dblOptin->optin);

      return HandleLoginAnfordern::ERROR_FEHLER_BEIM_DBLOPTIN_EMAIL_VERSAND;
    } else {
      return HandleLoginAnfordern::SUCCESS_DBLOPTIN_EMAIL_VERSANDT;
    }
  }

  private function getDblOption($requestObj, $pPasswordHashed, $pHashversion)
  {
    $dtop = new \DateTimeOperations();
    $optin = new \WebDblOptin();
    $optin->bearbdatum = $dtop->getDateTimeNow();
    if (\StringOperations::strlen($optin->passworttext) == 0) {
      $optin->passworttext = $pPasswordHashed;
    }
    $optin->passwort = $pPasswordHashed;
    $optin->hashversion = $pHashversion;
    $optin->name = $requestObj->name;
    $optin->vorname = $requestObj->vorname;
    $optin->email = $requestObj->email;
    $optin->geschlecht = $requestObj->geschlecht;
    if ($this->toolSettings->dseZustimmung4Login) {
      $optin->dse_unterschrieben_datum = \DateTimeOperations::getDateTimeNow();
    }

    return $optin;
  }

  
  private function getLoginName($pDbloptin): string
  {
    if (\DBWorkBASysSettings::isBremenLIS()) {
      $vornameName = \StringOperations::removeUmlaute(\StringOperations::substr($pDbloptin->vorname, 0, 1) . $pDbloptin->name);
      $dbwLogin = new \DBWorkLogin();
      $i = 0;
      do {
        $login = \StringOperations::strtoupper($vornameName) . ($i > 0 ? $i : '');
        $loginExists = $dbwLogin->loginExists($login);
        $i++;
      } while ($loginExists);
    } else {
      $login = $pDbloptin->email;
    }

    return $login;
  }

  private function sendOptInMail($pDbloptin, $pEmail)
  {
    if (!$pDbloptin->isEmpty()) {
      $allgeinstell = \AllgSettingsAPI::getAllgSettings();
      $viewModel = new SendeAutoLoginAnfordernEMailViewModel();
      $viewModel->vhsname = $allgeinstell->vhsname;
      $viewModel->name = $this->request->name;
      $viewModel->vorname = $this->request->vorname;
      $viewModel->login = $this->getLoginName($pDbloptin);
      $linkZuIndex = $this->getLinkZuIndex();
      $viewModel->linkDblOptIn = $linkZuIndex . '?action=confirmLogin&key=' . $pDbloptin->optin;

      $emailPresenter = new SendeAutoLoginAnfordernEMailPresenter($viewModel);
      $email = new \Kufer\Mail\EMail\EMailHTML($emailPresenter->getSubject(), $emailPresenter->getBody());
      $emailSender = \Kufer\Mail\Sender\EMailSenderFactory::create();
      $retour = $emailSender->sendFromEinrichtung(
        $email,
        array(new \Kufer\Mail\Address\EMailAddress($this->request->vorname . ' ' . $this->request->name, $pDbloptin->email)),
        'Sie'
      )->hasSentAnyMails();

      if (!$retour) {
        \Logger::logg('Tools Login anfordern DoubleOptin: Fehler beim Versenden der eMail an ' . $pEmail, 50);
      } else {
        \Logger::logg('Tools Login anfordern DoubleOptin: dbloptin mail sent', 1);
      }

      return $retour;
    } else {
      return false;
    }
  }

  private function getLinkZuIndex()
  {
    if ($this->toolSettings->SSLAnmeldung || $this->toolSettings->SSLLogin) {
      if ($this->toolSettings->SSLAnmeldung) {
        return \ConstantOperations::getHTTPSPath4Url('') . 'index.php';
      } else {
        return \ConstantOperations::getHTTPSPath4Url(LOGIN) . 'index.php';
      }
    } else {
      return 'http://' . \StringOperations::getCompleteUrlToSkript();
    }
  }

  private function setzeMenupunkte()
  {
    $menuBar = new \MenuBar();
    $menuBar->setMenuBarFromSettings(array(), 'LOGIN', null, true, true);
    $menuPunkte = $menuBar->getMenuPunkte();

    $zumLoginMenuPunkt = new \Kufer\Menu\MenuPunkt\MenuPunkt4LoginSeite();
    array_unshift($menuPunkte, $zumLoginMenuPunkt);

    $this->response->menuPunkte = $menuPunkte;
  }

  private function getBenutzergruppe()
  {
    if ($this->isDozentAllowed()
            && $this->isTeilnehmerAllowed()) {
      return $this->request->benutzergruppe;
    }
    
    
    elseif ($this->isDozentAllowed()) {
      return static::DOZ_AUTO_LOGIN;
    } elseif ($this->isTeilnehmerAllowed()) {
      return static::TN_AUTO_LOGIN;
    }

    assert(false, 'Sollte nicht erreicht werden, da in hasAccess abgefangen');
  }
}

class SendeAutoLoginAnfordernRequest
{
  public $geschlecht;
  public $name;
  public $vorname;
  public $email;
  public $passwort;
  public $passwortWiederholt;
  public $captchaOk;
  public $isRefresh;
  public $isXsrfOk;
  public $benutzergruppe;
  public $dseZustimmung;
  public $freiesPflichtfeldZustimmung;
}

class SendeAutoLoginAnfordernResponse extends \Kufer\KuferTools\Basis\UseCase\BasisResponse
{
  public $menuPunkte;
  public $statusCodes = array();
  public $login;
  public $passwort;
  public $passwortWiederholt;
  public $https;
  public $geschlecht;
  public $name;
  public $vorname;
  public $email;
  public $hinweis;

  public $pwAnzahlZeichen;
  public $pwZahlErforderlich;
  public $pwGrossKleinBuchstabenErforderlich;
  public $pwSonderzeichenErforderlich;
  public $dozAutoLogin;
  public $tnAutoLogin;
  public $benutzergruppeDozSelected;
  public $benutzergruppeTnSelected;
  public $showDseZustimmung;
  public $dseZustimmungLink;
  public $dseZustimmungChecked;
}