<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */

class StammBvAPI
{
  private function __construct()
  {
  }

  
  protected static function _sendeDmz($pOperation, $pNutzlast, $pSettings = null)
  {
    $abgleichAPI = new AbgleichAPI();

    return $abgleichAPI->sendeNachricht($pOperation, $pNutzlast, $pSettings);
  }

  
  public static function insertStammBv($pStammBv)
  {
    
    if (trim($pStammBv->mandatid) == DBWorkStammBv::getDefaultSepaMandatId($pStammBv->nr)) {
      $pStammBv->mandatid = '';
    }

    $allgsettings = AllgSettingsAPI::getAllgSettings();
    if (SessionOperations::isReplikat()) {
      if ($allgsettings->dmzEnabled) {
        return static::_insertStammBvDmz($pStammBv);
      } else {
        return static::_insertStammBvReplikat($pStammBv);
      }
    } else {
      return static::_insertStammBvDirekt($pStammBv);
    }
  }

  
  protected static function _insertStammBvDirekt($pStammBv)
  {
    $dbwStammBv = new DBWorkStammBv(1, true);
    $id = $dbwStammBv->insertStammBv($pStammBv, true, false);
    static::bereinigeBankdatenAnhandStammBv($pStammBv->nr, true, false);

    return $id > 0;
  }

  
  protected static function _insertStammBvReplikat($pStammBv)
  {
    $dbwStammBv = new DBWorkStammBv(1, true);
    $id = $dbwStammBv->insertStammBv($pStammBv, false, false);
    static::bereinigeBankdatenAnhandStammBv($pStammBv->nr, false, false);

    return $id > 0;
  }

  
  private static function _insertStammBvDmz($pStammBv)
  {
    try {
      $dbwStammBv = new DBWorkStammBv(1, true);
      $pStammBv->id = $dbwStammBv->insertStammBv($pStammBv, false, true);

      static::_sendStammBvToDmz($pStammBv);

      static::bereinigeBankdatenAnhandStammBv($pStammBv->nr, false, true);

      return true;
    } catch (AbgleichApiException $aae) {
      Logger::logg('StammBv einfügen - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);
      $dbwStammBv = new DBWorkStammBv(1, true);
      $dbwStammBv->deleteStammBv($pStammBv->id, false, true);

      return false;
    }
  }

  private static function _sendStammBvToDmz($pStammBv)
  {
    $stammBvNode = XMLNode::getXMLNode($pStammBv, 'stammbv', array(), true);
    $message = new XMLNode('stammbvs');
    $message->addChild($stammBvNode);

    static::_sendeDmz(AbgleichAPI::ABGLEICH_STAMMBVINSERT, new Nutzlast($message));
  }

  public static function insertStammBvDmzNoMySQL($pStammBv)
  {
    try {
      $pStammBv->id = 0;

      static::_sendStammBvToDmz($pStammBv);

      return true;
    } catch (AbgleichApiException $aae) {
      Logger::logg('StammBv einfügen NoMySQL - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);

      return false;
    }
  }

  
  public static function updateStammBv($pStammBv, $pOrigStammBv)
  {
    $allgsettings = AllgSettingsAPI::getAllgSettings();
    if (SessionOperations::isReplikat()) {
      if ($allgsettings->dmzEnabled) {
        return static::_updateStammBvDmz($pStammBv, $pOrigStammBv);
      } else {
        return static::_updateStammBvReplikat($pStammBv);
      }
    } else {
      return static::_updateStammBvDirekt($pStammBv);
    }
  }

  
  protected static function _updateStammBvDirekt($pStammBv)
  {
    $dbwStammBv = new DBWorkStammBv(1, true);
    $dbwStammBv->updateStammBv($pStammBv, true, false);
    static::bereinigeBankdatenAnhandStammBv($pStammBv->nr, true, false);

    return true;
  }

  
  protected static function _updateStammBvReplikat($pStammBv)
  {
    $dbwStammBv = new DBWorkStammBv(1, true);
    $dbwStammBv->updateStammBv($pStammBv, false, false);
    static::bereinigeBankdatenAnhandStammBv($pStammBv->nr, false, false);

    return true;
  }

  
  private static function _updateStammBvDmz($pStammBv, $pOrigStammBv)
  {
    try {
      $zuUebertragendeFelder = $pOrigStammBv->getDiffFields($pStammBv, true);
      if (!is_null($pStammBv->erstelltvon) && $pStammBv->erstelltvon !== '') {
        $zuUebertragendeFelder[] = 'erstelltvon';
      }
      if (!is_null($pStammBv->bearbeiter) && $pStammBv->bearbeiter !== '') {
        $zuUebertragendeFelder[] = 'bearbeiter';
      }

      $zuUebertragendeFelder[] = 'id';

      $stammBvNode = XMLNode::getXmlNodeOnlySpecificFields($pStammBv, 'stammbv', $zuUebertragendeFelder, true);
      $origStammBvNode = XMLNode::getXmlNodeOnlySpecificFields($pOrigStammBv, 'oldobject', $zuUebertragendeFelder, true);

      $stammBvNode->addChild($origStammBvNode);
      $message = new XMLNode('stammbvs');
      $message->addChild($stammBvNode);
      static::_sendeDmz(AbgleichAPI::ABGLEICH_STAMMBVUPDATE, new Nutzlast($message));
      static::_updateStammBvDirekt($pStammBv);

      return true;
    } catch (AbgleichApiException $aae) {
      Logger::logg('StammBv bearbeiten - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);

      return false;
    }
  }

  
  public static function deleteStammBv($pStammBvId, $pTnr)
  {
    $allgsettings = AllgSettingsAPI::getAllgSettings();
    if (SessionOperations::isReplikat()) {
      if ($allgsettings->dmzEnabled) {
        return static::_deleteStammBvDmz($pStammBvId, $pTnr);
      } else {
        return static::_deleteStammBvReplikat($pStammBvId, $pTnr);
      }
    } else {
      return static::_deleteStammBvDirekt($pStammBvId, $pTnr);
    }
  }

  
  protected static function _deleteStammBvDirekt($pStammBvId, $pTnr)
  {
    $dbwStammBv = new DBWorkStammBv(1, true);
    $dbwStammBv->deleteStammBv($pStammBvId, true, false);
    static::bereinigeBankdatenAnhandStammBv($pTnr, true, false);

    return true;
  }

  
  protected static function _deleteStammBvReplikat($pStammBvId, $pTnr)
  {
    $dbwStammBv = new DBWorkStammBv(1, true);
    $dbwStammBv->deleteStammBv($pStammBvId, false, false);
    static::bereinigeBankdatenAnhandStammBv($pTnr, false, false);

    return true;
  }

  
  private static function _deleteStammBvDmz($pStammBvId, $pTnr)
  {
    try {
      $idNode = new XMLNode('id', $pStammBvId);
      $stammBvNode = new XMLNode('stammbv');
      $stammBvNode->addChild($idNode);
      $message = new XMLNode('stammbvs');
      $message->addChild($stammBvNode);

      static::_sendeDmz(AbgleichAPI::ABGLEICH_STAMMBVDELETE, new Nutzlast($message));
      static::_deleteStammBvDirekt($pStammBvId, $pTnr);

      return true;
    } catch (AbgleichApiException $aae) {
      Logger::logg('StammBv löschen - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);

      return false;
    }
  }

  
  public static function bereinigeBankdatenAnhandStammBv($pTnr, $pDontProtocol, $pIsDmzBetrieb, ?string $bearbeiterKennung = null)
  {
    
    $dbwStammBv = new DBWorkStammBv(1, true);
    $stammBvAry = $dbwStammBv->getStammBvByTnr($pTnr);

    $dbwTeilnehm = new DBWorkTeilnehmer(1, true);
    $teilnehmer = $dbwTeilnehm->getTeilnehm($pTnr, true);

    
    $teilnehmer = static::_korregierePersonnAnhandStammbv($teilnehmer, $stammBvAry, true);
    $stammBvAry = static::_korregiereStammBvAnhandPersonn($stammBvAry, $teilnehmer, true, $bearbeiterKennung);

    
    
    $dbwTeilnehm->updateTeilnehmer($teilnehmer, $pDontProtocol);
    static::_saveBankBvAry($stammBvAry, $dbwStammBv, $pDontProtocol, $pIsDmzBetrieb);
  }

  
  public static function bereinigeBankdatenAnhandTeilnehmer($pTeilnehmer, $pDontProtocol, $pIsDmzBetrieb, ?string $bearbeiterKennung = null)
  {
    
    $dbwStammBv = new DBWorkStammBv(1, true);
    $stammBvAry = $dbwStammBv->getStammBvByTnr($pTeilnehmer->id);

    
    $pTeilnehmer = static::_korregierePersonnAnhandStammbv($pTeilnehmer, $stammBvAry, false);
    $stammBvAry = static::_korregiereStammBvAnhandPersonn($stammBvAry, $pTeilnehmer, false, $bearbeiterKennung);

    
    $dbwTeilnehm = new DBWorkTeilnehmer(1, true);
    
    $dbwTeilnehm->updateTeilnehmer($pTeilnehmer, $pDontProtocol);
    static::_saveBankBvAry($stammBvAry, $dbwStammBv, $pDontProtocol, $pIsDmzBetrieb);
  }

  
  private static function _saveBankBvAry($pStammBvAry, $pDbwStammBv, $pDontProtocol, $pIsDmzBetrieb)
  {
    $anzahlStammBv = count($pStammBvAry);
    for ($i = 0; $i < $anzahlStammBv; $i++) {
      if ($pStammBvAry[$i]->id === -1) {
        $pDbwStammBv->insertStammBv($pStammBvAry[$i], $pDontProtocol, $pIsDmzBetrieb);
      } else {
        $pDbwStammBv->updateStammBv($pStammBvAry[$i], $pDontProtocol, $pIsDmzBetrieb);
      }
    }
  }

  
  private static function _korregierePersonnAnhandStammbv($pPersonn, $pStammBvAry, $pPrefereStammBv)
  {
    
    if ($pPrefereStammBv) {
      
      if (count($pStammBvAry) === 0) {
        $pPersonn = static::_fillPersonnFromStammBv($pPersonn, new StammBv());
      } else {
        $pPersonn = static::_fillPersonnFromStammBv($pPersonn, $pStammBvAry[0]);
      }
    }

    return $pPersonn;
  }

  
  private static function _korregiereStammBvAnhandPersonn($pStammBvAry, $pPersonn, $pPrefereStammBv, ?string $bearbeiterKennung = null)
  {
    
    if (!$pPrefereStammBv) {
      
      if (empty($pStammBvAry)) {
        
        
        
        $stammBvObj = static::_fillStammBvFromPersonn($pPersonn, new StammBv(), $bearbeiterKennung);
        $stammBvObj->lfd = 1;
        $stammBvObj->id = -1;
        $pStammBvAry[0] = $stammBvObj;
      } else {
        $pStammBvAry[0] = static::_fillStammBvFromPersonn($pPersonn, $pStammBvAry[0], $bearbeiterKennung);
      }
    }
    
    $anzahlStammBv = count($pStammBvAry);
    for ($i = 0; $i < $anzahlStammBv; $i++) {
      $pStammBvAry[$i]->lfd = $i + 1;
    }

    return $pStammBvAry;
  }

  
  private static function _fillStammBvFromPersonn($pPersonn, $pStammBv, ?string $bearbeiterKennung = null)
  {
    $pStammBv->bic = $pPersonn->bic;
    $pStammBv->iban = $pPersonn->iban;
    $pStammBv->konto = $pPersonn->konto;
    $pStammBv->blz = $pPersonn->blz;
    $pStammBv->inhaber = $pPersonn->kontoinhaber;
    $pStammBv->bankbez = $pPersonn->bankbez;
    $pStammBv->ls_von = $pPersonn->last_erteilt;
    $pStammBv->mandatam = $pPersonn->mandatam;
    $pStammBv->nr = $pPersonn->id;
    $pStammBv->typ = $pPersonn->getDbTyp();

    if (!is_null($bearbeiterKennung)) {
      $pStammBv->bearbeiter = $bearbeiterKennung;
    }

    if (empty($pStammBv->id) && !is_null($bearbeiterKennung)) {
      $pStammBv->erstelltvon = $bearbeiterKennung;
    }

    return $pStammBv;
  }

  
  private static function _fillPersonnFromStammBv($pPersonn, $pStammBv)
  {
    $pPersonn->bic = $pStammBv->bic;
    $pPersonn->iban = $pStammBv->iban;
    $pPersonn->konto = $pStammBv->konto;
    $pPersonn->blz = $pStammBv->blz;
    $pPersonn->kontoinhaber = $pStammBv->inhaber;
    $pPersonn->bankbez = $pStammBv->bankbez;
    $pPersonn->last_erteilt = $pStammBv->ls_bis;
    $pPersonn->mandatam = $pStammBv->mandatam;

    return $pPersonn;
  }

  
  public static function getStammBvByTnr($pTnr)
  {
    if (\SessionOperations::isDmzBetrieb()) {
      return static::_getStammBvByTnrDmz($pTnr);
    } else {
      return static::_getStammBvByTnrFromDb($pTnr);
    }
  }

  
  private static function _getStammBvByTnrDmz($pTnr)
  {
    try {
      

      $message = new XMLNode('filter');
      $message->addChild(new XMLNode('typ', 'T'));
      $message->addChild(new XMLNode('nr', $pTnr));

      $result = static::_sendeDmz(AbgleichAPI::ABGLEICH_STAMMBV_GET, new Nutzlast($message));
      $stammbvOriginalInfos = JsonOperations::getFromString($result->reason);
      $resultList = array();
      foreach ($stammbvOriginalInfos as $item) {
        $resultList[] = Datamodul::toDatamodul('StammBv', $item);
      }

      return $resultList;
    } catch (AbgleichApiException $aae) {
      return false;
    }
  }

  private static function _getStammBvByTnrFromDb($pTnr)
  {
    $dbw = new DBWorkStammBv(1, true);

    return $dbw->getStammBvByTnr($pTnr);
  }

  private static function getDbwStammBv()
  {
    static $cache = null;
    if (is_null($cache)) {
      $cache = new DBWorkStammBv(1, true);
    }

    return $cache;
  }

  
  public static function hasSepaMandat($tn)
  {
    if ($tn->id > 0) {
      $dbwStammBv = new \DBWorkStammBv(1, true);
      $stammBv = $dbwStammBv->getStammBvByTnrAndIban($tn->id, $tn->iban);

      return \StammBvAPI::checkSepaMandatFromTn($stammBv);
    }

    return false;
  }

  
  public static function checkSepaMandatFromTn($pStammBv)
  {
    if (!SessionOperations::isReplikat()) {
      return static::checkSepaMandatFromTnDirekt($pStammBv);
    } elseif (SessionOperations::isDmzBetrieb()) {
      return static::checkSepaMandatFromTnDmz($pStammBv);
    } else { 
      return static::checkSepaMandatFromTnReplikat($pStammBv);
    }
  }

  
  public static function checkSepaMandatFromTns($pStammBvAry)
  {
    if (!SessionOperations::isReplikat()) {
      return static::checkSepaMandatFromTnsDirekt($pStammBvAry);
    } elseif (SessionOperations::isDmzBetrieb()) {
      return static::checkSepaMandatFromTnsDmz($pStammBvAry);
    } else { 
      return static::checkSepaMandatFromTnsReplikat($pStammBvAry);
    }
  }

  
  protected static function checkSepaMandatFromTnDirekt($pStammBv)
  {
    $result = static::checkSepaMandatFromTnsDirekt(array($pStammBv));

    return $result[$pStammBv->id];
  }

  
  protected static function checkSepaMandatFromTnsDirekt($pStammBvAry)
  {
    $dbwStammBv = self::getDbwStammBv();
    $resultAry = array();
    foreach ($pStammBvAry as $stammBv) {
      if (!$stammBv->isEmpty()) {
        $resultAry[$stammBv->id] = $dbwStammBv->checkSepaMandatFromTn($stammBv);
      }
    }

    return $resultAry;
  }

  
  protected static function checkSepaMandatFromTnDmz($pStammBv)
  {
    $result = static::checkSepaMandatFromTnsDmz(array($pStammBv));

    
    if (!isset($result[$pStammBv->id])) {
      return false;
    }

    return $result[$pStammBv->id];
  }

  
  protected static function checkSepaMandatFromTnsDmz($pStammBvAry)
  {
    $message = new XMLNode('teilnehmerdaten');

    $stammBvAryAssoc = array();
    foreach ($pStammBvAry as $stammBv) {
      $teilnehmerXmlNode = new XMLNode('teilnehmer');
      $teilnehmerXmlNode->addChild(new XMLNode('tnr', $stammBv->nr));
      $teilnehmerXmlNode->addChild(new XMLNode('iban', $stammBv->iban));
      $message->addChild($teilnehmerXmlNode);

      $stammBvAryAssoc[(int)$stammBv->nr . '_' . $stammBv->iban] = $stammBv;
    }

    $resultAry = array();
    try {
      $result = static::_sendeDmz(AbgleichAPI::ABGLEICH_CHECK_SEPA_MANDAT, new Nutzlast($message));
      $sepaMandatInfos = JsonOperations::getFromString($result->reason);

      foreach ($sepaMandatInfos as $info) {
        $stammBvId = $stammBvAryAssoc[$info->Tnr . '_' . $info->Iban]->id;
        $resultAry[$stammBvId] = (boolean)$info->Gueltig;
      }
    } catch (\Exception $e) {
      
    }

    return $resultAry;
  }

  
  protected static function checkSepaMandatFromTnReplikat($pStammBv)
  {
    $result = static::checkSepaMandatFromTnsReplikat(array($pStammBv));

    return $result[$pStammBv->id];
  }

  
  protected static function checkSepaMandatFromTnsReplikat($pStammBvAry)
  {
    $dbwStammBv = self::getDbwStammBv();
    $resultAry = array();
    foreach ($pStammBvAry as $stammBv) {
      $resultAry[$stammBv->id] = $dbwStammBv->hasTnSepaMandat($stammBv->nr, $stammBv->iban);
    }

    return $resultAry;
  }
}


class StammBvAPIHauptId extends StammBvAPI
{
  
  protected static function _sendeDmz($pOperation, $pNutzlast, $pSettings = null)
  {
    $pNutzlast->addNode(new XMLNode('nomapping', 'W'));
    
    $abgleichAPI = new AbgleichAPI();

    return $abgleichAPI->sendeNachricht($pOperation, $pNutzlast, $pSettings);
  }

  
  protected static function _insertStammBvDirekt($pStammBv)
  {
    return true;
  }

  
  protected static function _insertStammBvReplikat($pStammBv)
  {
    return true;
  }

  
  protected static function _updateStammBvDirekt($pStammBv)
  {
    return true;
  }

  
  protected static function _updateStammBvReplikat($pStammBv)
  {
    return true;
  }

  
  protected static function _deleteStammBvDirekt($pStammBvId, $pTnr)
  {
    return true;
  }

  
  protected static function _deleteStammBvReplikat($pStammBvId, $pTnr)
  {
    return true;
  }

  
  public static function bereinigeBankdatenAnhandStammBv($pTnr, $pDontProtocol, $pIsDmzBetrieb, ?string $bearbeiterKennung = null)
  {
  }

  
  public static function bereinigeBankdatenAnhandTeilnehmer($pTeilnehmer, $pDontProtocol, $pIsDmzBetrieb, ?string $bearbeiterKennung = null)
  {
  }
}