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

namespace Kufer\KuferTools\Oeffentlich\PasswortAnfordern\Utils;


class HandlePasswortAnfordernEingaben
{
  
  public const SUCCESS_PASSWORT_GEAENDERT = 'passwortGeaendert';
  public const SUCCESS_DBLOPTIN_EMAIL_VERSANDT = 'dblOptinEMailVersandt';
  public const ERROR_OPTIN_NICHT_GEFUNDEN = 'optinNichtGefunden';
  public const ERROR_KEIN_LOGIN_ANGEGEBEN = 'keinLoginAngegeben';
  public const ERROR_KEIN_PASSWORT_ANGEGEBEN = 'keinPasswortAngegeben';
  public const ERROR_PASSWORT_NICHT_WIEDERHOLT = 'PasswortNichtWiederholt';
  public const ERROR_PASSWORT_PASST_NICHT_ZU_WIEDERHOLUNG = 'PasswortPasstNichtZurWiederholung';
  public const ERROR_CAPTCHA_LEER_ODER_FALSCH = 'CaptchaLeerOderFalsch';
  public const ERROR_PASSWORT_ZU_KURZ = 'PasswortZuKurz';
  public const ERROR_PASSWORT_KEIN_SONDERZEICHEN = 'PasswortKeinSonderzeichen';
  public const ERROR_PASSWORT_KEINE_ZIFFER = 'PasswortKeineZiffer';
  public const ERROR_PASSWORT_KEINE_KLEINBUCHSTABEN = 'PasswortKeineKleichbuchstaben';
  public const ERROR_PASSWORT_KEINE_GROSSBUCHSTABEN = 'PasswortKeineGrossbuchstaben';
  public const ERROR_LOGIN_NICHT_GEFUNDEN = 'LoginExistiertNicht';
  public const ERROR_LOGIN_OHNE_EMAIL = 'LoginHatKeineEMail';
  public const ERROR_FEHLER_BEIM_DBLOPTIN_EMAIL_VERSAND = 'dblOptinEMailNichtVersandt';
  public const ERROR_DOPPELT_ABSENDEN = 'doppeltVersandt';
  public const ERROR_PASSWORT_ANFORDERN_NICHT_ERLAUBT_FUER_LDAP_LOGIN = 'PasswortAnfordernNichtErlaubt';
  public const ERROR_INTERNER_FEHLER = 'internerFehler';


  protected $status = array();
  protected $login;
  protected $password;
  protected $passwordRepeat;
  protected $captchaOk;

  public function __construct($pLogin, $pPassword, $pPasswordRepeat, $pCaptchaOk)
  {
    $this->login = $pLogin;
    $this->password = $pPassword;
    $this->passwordRepeat = $pPasswordRepeat;
    $this->captchaOk = $pCaptchaOk;
  }

  
  public function validateEingaben()
  {
    $this->validateCaptcha();
    if (in_array(self::ERROR_CAPTCHA_LEER_ODER_FALSCH, $this->status)) {
      return $this->status;
    }
    $this->validateLogin();
    $this->validatePasswoerterGefuellt();

    if ($this->password !== '') {
      $this->validatePasswortErfuelltVoraussetzungen();
    }

    return $this->status;
  }

  private function isLoginExtern(string $login): bool
  {
    $dbwPw = \DBWorkWebPasswordsUsers::getDefaultInstance();
    $pw = $dbwPw->getWebPasswordsUsersByLogin($login);
    if (!empty($pw->id) && $pw->id != -1) {
      if ($pw->auth_extern == 1) {
        return true;
      }
    }

    return false;
  }

  protected function validateLogin()
  {
    if (\trim($this->login) === '') {
      $this->status[] = self::ERROR_KEIN_LOGIN_ANGEGEBEN;
    } else {
      if (\Kufer\KuferTools\Utils\LDAP\BaseLoginLDAP::hasEinrichtungTeilnehmerLDAPLogin()) {
        $dbwWebPwUsers = new \DBWorkWebPasswordsUsers();
        $wpu = $dbwWebPwUsers->getWebPasswordsUsersByLogin($this->login);
        if ($wpu->isLdapLogin()) {
          $this->status[] = self::ERROR_PASSWORT_ANFORDERN_NICHT_ERLAUBT_FUER_LDAP_LOGIN;

          return;
        }
      }

      $dbwUser = new \DBWorkUser(1, true);
      $user = $dbwUser->getUserbyLogin(\StringOperations::strtoupper($this->login));

      if ($user->isEmpty()) {
        $this->status[] = self::ERROR_LOGIN_NICHT_GEFUNDEN;
      } elseif ($user->email == '') {
        $this->status[] = self::ERROR_LOGIN_OHNE_EMAIL;
      }
    }
  }

  protected function validateCaptcha()
  {
    if (!$this->captchaOk) {
      $this->status[] = self::ERROR_CAPTCHA_LEER_ODER_FALSCH;
    }
  }

  protected function validatePasswoerterGefuellt()
  {
    if ($this->password === '') {
      $this->status[] = self::ERROR_KEIN_PASSWORT_ANGEGEBEN;
    } elseif ($this->passwordRepeat === '') {
      $this->status[] = self::ERROR_PASSWORT_NICHT_WIEDERHOLT;
    } elseif ($this->password !== $this->passwordRepeat) {
      $this->status[] = self::ERROR_PASSWORT_PASST_NICHT_ZU_WIEDERHOLUNG;
    }
  }

  protected function validatePasswortErfuelltVoraussetzungen()
  {
    $pwOp = new \PasswordOperations();
    if (!$pwOp->validSize($this->password)) {
      $this->status[] = self::ERROR_PASSWORT_ZU_KURZ;
    }
    if (!$pwOp->validSpecialChars($this->password)) {
      $this->status[] = self::ERROR_PASSWORT_KEIN_SONDERZEICHEN;
    }
    if (!$pwOp->validNumbers($this->password)) {
      $this->status[] = self::ERROR_PASSWORT_KEINE_ZIFFER;
    }
    if (!$pwOp->validLowerCaseChar($this->password)) {
      $this->status[] = self::ERROR_PASSWORT_KEINE_KLEINBUCHSTABEN;
    }
    if (!$pwOp->validUpperCaseChar($this->password)) {
      $this->status[] = self::ERROR_PASSWORT_KEINE_GROSSBUCHSTABEN;
    }
  }

  
  public static function filterError(array $statusCodes)
  {
    return \array_filter($statusCodes, function($pStatus): bool {
      return $pStatus != self::SUCCESS_DBLOPTIN_EMAIL_VERSANDT
          && $pStatus != self::SUCCESS_PASSWORT_GEAENDERT;
    });
  }

  public static function getMessageString($pStatus): string
  {
    switch ($pStatus) {
      case self::SUCCESS_PASSWORT_GEAENDERT:
        return 'Ihr Passwort wurde erfolgreich geändert. Sie können sich nun mit Ihren neuen Passwort einloggen.';
      case self::SUCCESS_DBLOPTIN_EMAIL_VERSANDT:
        return 'Ihr neues Passwort muss zunächst aktiviert werden. Hierzu wurde eine E-Mail mit einem Aktivierungslink an Ihre hinterlegte E-Mail-Adresse gesandt.';
      case self::ERROR_OPTIN_NICHT_GEFUNDEN:
        return 'Der Aktivierungslink existiert nicht, oder ist nicht mehr gültig.';
      case self::ERROR_KEIN_LOGIN_ANGEGEBEN:
        return 'Bitte geben Sie Ihr Login an.';
      case self::ERROR_KEIN_PASSWORT_ANGEGEBEN:
        return 'Bitte geben Sie Ihr Wunschpasswort an.';
      case self::ERROR_PASSWORT_NICHT_WIEDERHOLT:
        return 'Bitte wiederholen Sie zur Bestätigung Ihr gewünschtes Passwort.';
      case self::ERROR_PASSWORT_PASST_NICHT_ZU_WIEDERHOLUNG:
        return 'Das Passwort und das wiederholte Passwort stimmen nicht überein.';
      case self::ERROR_CAPTCHA_LEER_ODER_FALSCH:
        return 'Das Captcha wurde nicht korrekt gelöst.';
      case self::ERROR_PASSWORT_ZU_KURZ:
        return 'Ihr Passwort ist zu kurz.';
      case self::ERROR_PASSWORT_KEIN_SONDERZEICHEN:
        return 'Ihr Passwort enthält kein Sonderzeichen.';
      case self::ERROR_PASSWORT_KEINE_ZIFFER:
        return 'Ihr Passwort enthält keine Ziffer.';
      case self::ERROR_PASSWORT_KEINE_KLEINBUCHSTABEN:
        return 'Ihr Passwort enthält keinen Kleinbuchstaben.';
      case self::ERROR_PASSWORT_KEINE_GROSSBUCHSTABEN:
        return 'Ihr Passwort enthält keinen Großbuchstaben.';
      case self::ERROR_LOGIN_NICHT_GEFUNDEN:
        return 'Der Benutzername wurde nicht gefunden.'; 
      case self::ERROR_LOGIN_OHNE_EMAIL:
        return 'Es wurde keine E-Mail-Adresse zu Ihrem Login gefunden.'; 
      case self::ERROR_FEHLER_BEIM_DBLOPTIN_EMAIL_VERSAND:
        return 'Es ist ein Fehler beim Versand der E-Mail aufgetreten. Bitte versuchen Sie es erneut, oder wenden Sie sich an die Einrichtung.';
      case self::ERROR_PASSWORT_ANFORDERN_NICHT_ERLAUBT_FUER_LDAP_LOGIN:
        return 'Ihr Login und Passwort werden über ein LDAP-Verzeichnis verwaltet.<br />Passwortanforderung nicht möglich.';
      case self::ERROR_DOPPELT_ABSENDEN:
        return '';
      case self::ERROR_INTERNER_FEHLER:
        return 'Ein interner Fehler ist aufgetreten. Versuchen Sie es noch einmal.';
      default:
        return '';
    }
  }

  public const URL_EXPIRES_IN_HOURS = 2;

  
  public static function isOptinValid(\WebDblOptin $optin): bool
  {
    $dateNow = \DateTimeObj::getNow();
    $dateCreation = \DateTimeObj::createFromString($optin->bearbdatum);
    $dateExpiration = (clone $dateCreation)->addHours(self::URL_EXPIRES_IN_HOURS);

    $result = $dateNow->isBetweenDateTimes($dateCreation, $dateExpiration);

    if (!$result) {
      $dbwOptin = new \DBWorkDblOptinToolPasswortAendern(1, true);
      $dbwOptin->deleteByOptin($optin->optin);
    }

    return $result;
  }
}