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

class DataMenuLoginBankdaten extends DataMenuMain
{
  public const NOTHING_DONE = 0;
  public const INSERT_SUCCESS = 1;
  public const INSERT_FAIL = 2;
  public const INSERT_VALIDATION_ERROR = 3;
  public const INSERT_SEPA_UNVOLLSTAENDIG = 4;
  public const INSERT_DTA_UNVOLLSTAENDIG = 5;
  public const UPDATE_SUCCESS = 6;
  public const UPDATE_FAIL = 7;
  public const UPDATE_VALIDATION_ERROR = 8;
  public const UPDATE_SEPA_UNVOLLSTAENDIG = 9;
  public const UPDATE_DTA_UNVOLLSTAENDIG = 10;
  public const DELETE_SUCCESS = 11;
  public const DELETE_FAIL = 12;
  public const GET_STAMMBV_FAIL = 13;
  public const USE_STAMMBV_SUCCESS = 14;
  public const USE_STAMMBV_FAIL = 15;

  private $_statusCodes = array();
  private $_fehlerhafteStammBv = array();

  public function __construct($pUrlparameter)
  {
    parent::__construct($pUrlparameter);
    $this->exportadapter = new ExpStammBv();
  }

  public function getsight($sightid = 483)
  {
    parent::getsight($sightid);
  }

  public function _getClickPath($pName = 'Teilnehmerlogin - Bankdaten')
  {
    $this->_setStdClickPath($pName, 'clickKundenLoginBankdatenText');

    return $this->clickpfad;
  }

  public function mainmenu()
  {
    if ($this->toolsettings->showClickpfad) {
      echo $this->getClickPath();
    }
    echo '<div class="hauptseite_ohnestatus">' . "\n" . $this->getContentAnker();

    $this->internerContent();

    echo '</div>';
  }

  public function internerContent()
  {
    $this->getsight();

    if (!$this->istZugriffErlaubt()) {
      $this->showAccessDenied();
    } else {
      if (!$this->isStammhoererLoggedIn()) {
        $this->showNichtEingeloggt();
      } else {
        $this->handleChangeRequests();
        $this->showFormular();
      }
    }
  }

  private function setFehlerhafteStammBv($pStammBv)
  {
    $key = trim($pStammBv->id) == '' ? '_neu' : $pStammBv->id;
    $this->_fehlerhafteStammBv[$key] = $pStammBv;
  }

  private function getFehlerhafteStammBv($pKey, $pDefault)
  {
    if (isset($this->_fehlerhafteStammBv[$pKey])) {
      return $this->_fehlerhafteStammBv[$pKey];
    } else {
      return $pDefault;
    }
  }

  private function getFehlerhafteStammBvAry($pStammBvAry)
  {
    $result = array();
    foreach ($pStammBvAry as $pStammBv) {
      $result[] = $this->getFehlerhafteStammBv($pStammBv->id, $pStammBv);
    }

    return $result;
  }

  public function istZugriffErlaubt()
  {
    return BASysSettingsAPI::isSwitchSet(SCHALTER_LOGIN_REGISTRIERUNG_PER_DMZ);
  }

  public function showAccessDenied()
  {
    echo '<div>Diese Funktion ist nicht freigeschaltet.</div>';
  }

  private function handleChangeRequests()
  {
    
    
    
    

    $action = GetOperations::getVarValue('action');
    if ($action == 'send') {
      if (Xsrf::checkAndUseXsrf4KuferWEB('wbAendereBankdaten') === Xsrf::KEY_OK) {
        $this->handleSend();
      }
      $this->setEmptyStatusCodeIfNoStatus();
    } elseif ($action == 'delete') {
      $idToDel = GetOperations::getVarValue('bv', 0);
      if (Xsrf::checkAndUseXsrf4KuferWEB('wbLoescheBankdaten', $idToDel) === Xsrf::KEY_OK) {
        $this->handleDelete();
      }
      $this->setEmptyStatusCodeIfNoStatus();
    } elseif ($action == 'usebv') {
      $idToUse = GetOperations::getVarValue('bv', 0);
      if (Xsrf::checkAndUseXsrf4KuferWEB('wbVerwendeBankdaten', $idToUse) === Xsrf::KEY_OK) {
        $this->handleStammBvToSession();
      }
      $this->setEmptyStatusCodeIfNoStatus();
    }
    $this->getStammBv4Tn(); 
    
    $this->exportadapter->setSightInfo('status', $this->getStatusMessages());
  }

  private function showFormular()
  {
    $this->showKopfbereich();
    $this->showBankdaten();
    $this->showFussbereich();
  }

  private function isStammhoererLoggedIn()
  {
    $wblogin = $this->getWbLogin();

    return $wblogin !== null && trim($wblogin->login) !== '';
  }

  private function showKopfbereich()
  {
    echo $this->getSightPart($this->sight->id, WB_SIGHT_PART_HEADER, array(new StammBv()));
  }

  private function showBankdaten()
  {
    $stammBvAry = $this->getStammBv4Tn(true);
    if (count($stammBvAry) == 0) {
      $this->showKeineBankverbindungen();
    } else {
      
      $stammBvMitFehlerhaftenEingaben = $this->getFehlerhafteStammBvAry($stammBvAry);
      $this->showBankVerbindungen($stammBvMitFehlerhaftenEingaben);
    }
  }

  private function showFussbereich()
  {
    $stammBv = $this->getFehlerhafteStammBv('_neu', new StammBv());
    $anzahlStammBv = count($this->getStammBv4Tn());
    $this->setExportSightInfo('anzahl_stammbv', $anzahlStammBv);
    echo $this->getSightPart($this->sight->id, WB_SIGHT_PART_FOOTER, array($stammBv));
  }

  private function showNichtEingeloggt()
  {
    echo $this->getSightPart($this->sight->id, WB_SIGHT_PART_NOCOLUMN, array(new StammBv()));
  }

  private function showBankVerbindungen($pStammBvArray)
  {
    echo $this->getSightPart($this->sight->id, WB_SIGHT_PART_BODY, $pStammBvArray);
  }

  private function showKeineBankverbindungen()
  {
    echo $this->getSightPart($this->sight->id, WB_SIGHT_PART_NODATA, array(new StammBv()));
  }

  private function handleStammBvToSession()
  {
    $stammBvAry = $this->getStammBv4Tn();
    $idToUse = GetOperations::getVarValue('bv', 0);

    foreach ($stammBvAry as $stammbv) {
      if ($stammbv->id == $idToUse) {
        $this->setStammBvToSession($stammbv);
        $this->addStatuscode(self::USE_STAMMBV_SUCCESS);

        return;
      }
    }
    
    $this->addStatuscode(self::USE_STAMMBV_FAIL);
  }

  
  private function setStammBvToSession($pStammBv)
  {
    SessionOperations::setVarValueWkWb('w_iban', $pStammBv->iban);
    SessionOperations::setVarValueWkWb('w_bic', $pStammBv->bic);
    SessionOperations::setVarValueWkWb('w_konto', $pStammBv->konto);
    SessionOperations::setVarValueWkWb('w_bankbez', $pStammBv->bankbez);
    SessionOperations::setVarValueWkWb('w_blz', $pStammBv->blz);
    SessionOperations::setVarValueWkWb('w_kontoinhaber', $pStammBv->inhaber);

    $datenNeuesAnmeldeverfahren = SessionOperations::getVarValueAnmInfo();
    if (null !== $datenNeuesAnmeldeverfahren) {
      $hauptTn = $datenNeuesAnmeldeverfahren->hauptTn;
      $hauptTn->iban = $pStammBv->iban;
      $hauptTn->bic = $pStammBv->bic;
      $hauptTn->konto = $pStammBv->konto;
      $hauptTn->bankbez = $pStammBv->bankbez;
      $hauptTn->blz = $pStammBv->blz;
      $hauptTn->kontoinhaber = $pStammBv->inhaber;
      SessionOperations::setVarValueAnmInfo($datenNeuesAnmeldeverfahren);
    }
  }

  
  private function handleDelete()
  {
    $stammBvAry = $this->getStammBv4Tn();
    $idToDel = GetOperations::getVarValue('bv', 0);

    foreach ($stammBvAry as $stammbv) {
      if ($stammbv->id == $idToDel) {
        $success = StammBvAPIHauptId::deleteStammBv($stammbv->id, $stammbv->nr);
        if ($success) {
          if (SessionOperations::isStammBvInSession($stammbv)) {
            
            $nichtGeloeschteStammBv = array_values(array_filter($stammBvAry, function($pStammBv) use ($idToDel) {return $pStammBv->id != $idToDel;}));
            if (isset($nichtGeloeschteStammBv[0])) {
              $this->setStammBvToSession($nichtGeloeschteStammBv[0]);
            } else {
              $this->setStammBvToSession(new StammBv());
            }
          }
          $this->addStatusCode(self::DELETE_SUCCESS);
          $this->handleBankverbindungGeaendertEmail($stammbv->nr);
        } else {
          $this->addStatusCode(self::DELETE_FAIL);
        }

        return;
      }
    }
  }

  private function handleSend()
  {
    $this->handleStammBvToUpdate();
    $this->handleStammBvToInsert();
  }

  private function isStammBvEmpty($stammBv)
  {
    return (trim($stammBv->iban) === '' || trim($stammBv->bic) === '')
           && (trim($stammBv->konto) === '' || trim($stammBv->blz) === '');
  }

  private function isStammBvSepaNurTeilweiseGefuellt($stammBv)
  {
    return (trim($stammBv->iban) === '' xor trim($stammBv->bic) === '');
  }

  private function isStammBvDtaNurTeilweiseGefuellt($stammBv)
  {
    return (trim($stammBv->konto) === '' xor trim($stammBv->blz) === '');
  }

  private function fillBankdatenAusHinterlegung($stammBv)
  {
    $bankbez = '';
    $bic = '';
    if (trim($stammBv->iban) !== '') {
      $bankbez = BankDatenOperations::getBankbezeichnungAnhandIban($stammBv->iban);
      $bic = BankDatenOperations::getBicFromIban($stammBv->iban);
    } elseif (trim($stammBv->blz) !== '') {
      $bankbez = BankDatenOperations::getBankbezeichnungAnhandBlz($stammBv->blz);
    }

    if (trim($bankbez) !== '') {
      $stammBv->bankbez = $bankbez;
    }
    if (trim($bic) !== '') {
      $stammBv->bic = $bic;
    }

    return $stammBv;
  }

  private function handleStammBvToUpdate()
  {
    $stammBvAry = $this->getStammBv4Tn();
    foreach ($stammBvAry as $stammBvDb) {
      $stammBvPost = $this->fillStammBvFromPost($stammBvDb, '_' . $stammBvDb->id);
      $stammBvPost = $this->fillBankdatenAusHinterlegung($stammBvPost);
      $diffFields = $stammBvPost->getDiffFields($stammBvDb);
      if (count($diffFields) > 0) {
        $this->updateStammBv($stammBvPost, $stammBvDb);
      }
    }
  }

  private function updateStammBv($stammBvNeu, $stammBvOrig)
  {
    $wrongFields = $this->validateStammBvBody($stammBvNeu);
    $this->exportadapter->addFehler($stammBvOrig->id, $wrongFields['leerePflichtfelder'], $wrongFields['fehlerhaftGefuellt']);
    if ($this->isStammBvSepaNurTeilweiseGefuellt($stammBvNeu)) {
      $this->setFehlerhafteStammBv($stammBvNeu);
      $this->addStatusCode(self::UPDATE_SEPA_UNVOLLSTAENDIG);
    } elseif ($this->isStammBvDtaNurTeilweiseGefuellt($stammBvNeu)) {
      $this->setFehlerhafteStammBv($stammBvNeu);
      $this->addStatusCode(self::UPDATE_DTA_UNVOLLSTAENDIG);
    } elseif (!$this->isStammBvEmpty($stammBvNeu)) {
      if (count($wrongFields['leerePflichtfelder']) === 0 && count($wrongFields['fehlerhaftGefuellt']) === 0) {
        $success = StammBvAPIHauptId::updateStammBv($stammBvNeu, $stammBvOrig);
        if ($success) {
          if (SessionOperations::isStammBvInSession($stammBvOrig) || !SessionOperations::isBankDataInSession()) {
            
            $this->setStammBvToSession($stammBvNeu);
          }
          $this->addStatusCode(self::UPDATE_SUCCESS);
          $this->handleBankverbindungGeaendertEmail($stammBvOrig->nr);
        } else {
          $this->setFehlerhafteStammBv($stammBvNeu);
          $this->addStatusCode(self::UPDATE_FAIL);
        }
      } else {
        $this->setFehlerhafteStammBv($stammBvNeu);
        $this->addStatusCode(self::UPDATE_VALIDATION_ERROR);
      }
    }
  }

  private function handleBankverbindungGeaendertEmail($tnr)
  {
    $tool0Settings = ToolSettingsAPI::getToolSettings(0);
    if ($tool0Settings->stammhoererLoginBankverbindungAendernEmailInfo) {
      $sender = \Kufer\Mail\Sender\EMailSenderFactory::create();
      $mail = new \Kufer\Mail\EMail\EMailHTML('Bankverbindung durch Stammhörer geändert', 'Der Stammhörer mit Kundennummer ' . $tnr . ' hat seine Bankverbindung geändert oder gelöscht.');
      $sender->informEinrichtung($mail);
    }
  }

  private function addStatusCode($code)
  {
    $this->_statusCodes[] = $code;
  }

  private function setEmptyStatusCodeIfNoStatus()
  {
    if (count($this->_statusCodes) === 0) {
      $this->_statusCodes[] = self::NOTHING_DONE;
    }
  }

  private function getStatusMessages()
  {
    if (count($this->_statusCodes) > 0) {
      $message = '<div class="wbl_status_message bv_status_messages">';
      foreach ($this->_statusCodes as $code) {
        $message .= $this->getMessage4StatusCode($code);
      }
      $message .= '</div>';

      return $message;
    } else {
      return '';
    }
  }

  private function getMessage4StatusCode($code)
  {
    $cssClass = 'wbl_status bv_status';
    $cssClassNeutral = $cssClass . ' wbl_neutral bv_neutral';
    $cssClassSuccess = $cssClass . ' wbl_success bv_success';
    $cssClassError = $cssClass . ' wbl_error bv_error';

    switch ($code) {
      case self::NOTHING_DONE:
        return '<div class="' . $cssClassNeutral . '">Es wurde keine Änderung vorgenommen.</div>';
      case self::INSERT_SUCCESS:
        return '<div class="' . $cssClassSuccess . '">Eine neue Bankverbindung wurde hinzugefügt.</div>';
      case self::INSERT_FAIL:
        return '<div class="' . $cssClassError . '">Beim Hinzufügen der neuen Bankverbindung ist ein technischer Fehler aufgetreten. Bitte versuchen Sie es erneut.</div>';
      case self::INSERT_VALIDATION_ERROR:
        return '<div class="' . $cssClassError . '">Bitte prüfen Sie die Eingabefelder der hinzuzufügenden Bankverbindung. Entweder wurde ein Pflichtfeld leer gelassen, oder die Bankverbindung konnte nicht verifiziert werden.</div>';
      case self::INSERT_SEPA_UNVOLLSTAENDIG:
        return '<div class="' . $cssClassError . '">Beim Hinzufügen der neuen Bankverbindung wurden nicht IBAN und BIC gemeinsam angegeben.</div>';
      case self::INSERT_DTA_UNVOLLSTAENDIG:
        return '<div class="' . $cssClassError . '">Beim Hinzufügen der neuen Bankverbindung wurden nicht Konto-Nr. und BLZ gemeinsam angegeben.</div>';
      case self::UPDATE_SUCCESS:
        return '<div class="' . $cssClassSuccess . '">Die Bankverbindung wurde erfolgreich geändert.</div>';
      case self::UPDATE_FAIL:
        return '<div class="' . $cssClassError . '">Beim Ändern der Bankverbindung ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.</div>';
      case self::UPDATE_VALIDATION_ERROR:
        return '<div class="' . $cssClassError . '">Bitte prüfen Sie die Eingabefelder der zu ändernden Bankverbindung. Entweder wurde ein Pflichtfeld leer gelassen, oder die Bankverbindung konnte nicht verifiziert werden.</div>';
      case self::UPDATE_SEPA_UNVOLLSTAENDIG:
        return '<div class="' . $cssClassError . '">Beim Ändern der Bankverbindung wurden nicht IBAN und BIC gemeinsam angegeben.</div>';
      case self::UPDATE_DTA_UNVOLLSTAENDIG:
        return '<div class="' . $cssClassError . '">Beim Ändern der Bankverbindung wurden nicht Konto-Nr. und BLZ gemeinsam angegeben.</div>';
      case self::DELETE_SUCCESS:
        return '<div class="' . $cssClassSuccess . '">Die Bankverbindung wurde gelöscht.</div>';
      case self::DELETE_FAIL:
        return '<div class="' . $cssClassError . '">Beim Löschen der Bankverbindung ist ein technischer Fehler aufgetreten. Bitte versuchen Sie es erneut.</div>';
      case self::GET_STAMMBV_FAIL:
        return '<div class="' . $cssClassError . '">Beim Laden der Bankverbindungen ist ein technischer Fehler aufgetreten. Bitte versuchen Sie es später erneut.</div>';
      case self::USE_STAMMBV_SUCCESS:
        return '<div class="' . $cssClassSuccess . '">Die Bankverbindung wird bei Ihrer nächsten Anmeldung verwendet.</div>';
      case self::USE_STAMMBV_FAIL:
        return '<div class="' . $cssClassError . '">Beim Vorbereiten der Bankverbindung für die nächste Anmeldung ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.</div>';
    }

    return '';
  }

  private function handleStammBvToInsert()
  {
    $stammBv = $this->fillStammBvFromPost(new StammBv(), '_neu');
    $stammBv = $this->fillBankdatenAusHinterlegung($stammBv);
    $wrongFields = $this->validateStammBvFooter($stammBv);
    $this->exportadapter->addFehler('_neu', $wrongFields['leerePflichtfelder'], $wrongFields['fehlerhaftGefuellt']);
    if ($this->isStammBvSepaNurTeilweiseGefuellt($stammBv)) {
      $this->setFehlerhafteStammBv($stammBv);
      $this->addStatusCode(self::INSERT_SEPA_UNVOLLSTAENDIG);
    } elseif ($this->isStammBvDtaNurTeilweiseGefuellt($stammBv)) {
      $this->setFehlerhafteStammBv($stammBv);
      $this->addStatusCode(self::INSERT_DTA_UNVOLLSTAENDIG);
    } elseif (!$this->isStammBvEmpty($stammBv)) {
      if (count($wrongFields['leerePflichtfelder']) === 0 && count($wrongFields['fehlerhaftGefuellt']) === 0) {
        $this->insertStammBv($stammBv);
      } else {
        $this->setFehlerhafteStammBv($stammBv);

        $this->addStatusCode(self::INSERT_VALIDATION_ERROR);
      }
    } else {
      
      $this->exportadapter->addFehler('_neu', array(), array());
    }
  }

  private function insertStammBv($pStammBv)
  {
    $stammBv = $this->bereinigeNeueStammBv($pStammBv);
    $alleStammBvVorInsert = $this->getStammBv4Tn(false);
    $success = StammBvAPIHauptId::insertStammBv($stammBv);
    if ($success) {
      if (count($alleStammBvVorInsert) == 0) {
        $this->setStammBvToSession($stammBv);
      }
      $this->addStatusCode(self::INSERT_SUCCESS);
      $this->handleBankverbindungHinzugefuegtEmail($pStammBv->nr);
    } else {
      $this->addStatusCode(self::INSERT_FAIL);
    }
  }

  private function handleBankverbindungHinzugefuegtEmail($tnr)
  {
    $tool0Settings = ToolSettingsAPI::getToolSettings(0);
    if ($tool0Settings->stammhoererLoginBankverbindungHinzufuegenEmailInfo) {
      $sender = \Kufer\Mail\Sender\EMailSenderFactory::create();
      $mail = new \Kufer\Mail\EMail\EMailHTML('Bankverbindung von Stammhörer hinzugefügt', 'Der Stammhörer mit Kundennummer ' . $tnr . ' hat eine Bankverbindung hinzugefügt.');
      $sender->informEinrichtung($mail);
    }
  }

  private function bereinigeNeueStammBv($stammBv)
  {
    $stammBv->typ = 'T';

    if (trim($stammBv->konto) === '' || (trim($stammBv->iban) !== '' && trim($stammBv->bic) !== '')) {
      $stammBv->sepa = 'S';
    } else {
      $stammBv->sepa = 'D';
    }
    $stammBv->lfd = -1;
    $wbLogin = $this->getWbLogin();
    $stammBv->nr = $wbLogin->tnr;

    return $stammBv;
  }


  private function fillStammBvFromPost($pStammBv, $pSuffix)
  {
    $stammBv = clone($pStammBv);
    $vars = get_object_vars($stammBv);
    foreach ($vars as $varname => $value) {
      if ($varname !== 'id') {
        $stammBv->{$varname} = trim(PostOperations::getVarValue('bvedit_' . $varname . $pSuffix, $pStammBv->{$varname} ?? ''));
      }
    }
    if ($stammBv->iban !== '') {
      
      $stammBv->iban = StringOperations::strtoupper($stammBv->iban);
      
      
      
      $stammBv->konto = '';
      $stammBv->blz = '';
    }

    return $stammBv;
  }

  private function getWbLogin()
  {
    static $wblogin = null;
    if (is_null($wblogin)) {
      $login = SessionOperations::getVarValueWk('w_login');
      $dbwWbLogin = new DBWorkWBLogins(1, true);
      $wblogin = $dbwWbLogin->getByLogin($login);
    }

    return $wblogin;
  }

  private function getStammBv4Tn($pRefreshCache = false)
  {
    $stammbv = null;
    if (is_null($stammbv) || $pRefreshCache) {
      $wbLogin = $this->getWbLogin();
      $stammbv = StammBvAPIHauptId::getStammBvByTnr($wbLogin->tnr);
      if ($stammbv === false) {
        $this->addStatusCode(self::GET_STAMMBV_FAIL);
        $stammbv = array();
      }
    }

    return $stammbv;
  }

  private function validateStammBvFooter($pStammBv)
  {
    $pflichtFelder = StringOperations::getPflichtFelder('', $this->sight->footer);

    return $this->validateStammBv($pStammBv, $pflichtFelder);
  }

  private function validateStammBvBody($pStammBv)
  {
    $pflichtFelder = StringOperations::getPflichtFelder('', $this->sight->body);

    return $this->validateStammBv($pStammBv, $pflichtFelder);
  }

  private function validateStammBv($pStammBv, $pflichtFelder)
  {
    $validierung = ValidierungBasis::getInstance();
    $fehlerhaftGefuellt = array();
    $leerePflichtfelder = array();

    $vars = get_object_vars($pStammBv);
    foreach ($vars as $varname => $value) {
      $extraInfo = array();
      if ($varname == 'iban') {
        $extraInfo = array('bic' => $pStammBv->bic);
      }
      if ($varname == 'konto') {
        $extraInfo = array('blz' => $pStammBv->blz);
      }

      if (trim($pStammBv->{$varname} ?? '') === '') {
        if (in_array($varname, $pflichtFelder) && !$this->ignoreBankDatenSpecialCase($varname, $pStammBv)) {
          $leerePflichtfelder[] = StringOperations::strtolower($varname);
        }
      } else {
        if ($validierung->isValidVar($varname, $pStammBv->{$varname}, $extraInfo) !== true) {
          $fehlerhaftGefuellt[] = StringOperations::strtolower($varname);
        }
      }
    }

    return array('fehlerhaftGefuellt' => $fehlerhaftGefuellt, 'leerePflichtfelder' => $leerePflichtfelder);
  }

  
  private function ignoreBankDatenSpecialCase($pVarname, $pStammBv)
  {
    if (($pVarname == 'iban' || $pVarname == 'bic')
      && $pStammBv->konto != '' && $pStammBv->blz) {
      return true;
    } elseif (($pVarname == 'konto' || $pVarname == 'blz')
      && $pStammBv->iban != '') {
      return true;
    } else {
      return false;
    }
  }
}