<?php

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

class DataMenuLoginMeineKurse extends DataMenuMainTopLeft
{
  protected $exportadapterStammhoerer;
  protected $exportadapterBelegung;
  
  protected static $getBelegungStrategy;
  private $searchOptions;

  public function __construct($urlParam)
  {
    parent::__construct($urlParam);

    SessionOperations::setVarValueIntern('loginweitermeldung', ''); 
    $this->exportadapterStammhoerer = $this->exportadapter = new ExpStammhoerer();
    $this->exportadapterBelegung = new ExpBelegungDirektObjekt();

    $this->searchOptions = new MeineKurseSearchOptions();

    $this->setStrategy();
    if (!is_null(self::$getBelegungStrategy)) {
      self::$getBelegungStrategy->setOrderBy();
    }
  }

  private function setStrategy()
  {
    if (is_null(self::$getBelegungStrategy)) {
      self::$getBelegungStrategy = MeineKurseGetBelegungenStrategy::getStrategyForStammhoerer();
    }

    return self::$getBelegungStrategy;
  }

  public function _getClickPath($pName = 'Teilnehmer-Login - Meine Kurse')
  {
    $this->_setStdClickPath($pName, 'clickKundenLoginMeineKurse');

    return $this->clickpfad;
  }

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

  public function mainmenu()
  {
    if (SessionOperations::getWbLogin() == null) {
      $this->getsight(); 

      if ($this->toolsettings->showClickpfad) {
        echo $this->getClickPath();
      }

      echo '<div class="hauptseite">' . "\n";
      $this->_showNichtEingeloggt();
      echo '</div>';
    } else {
      parent::mainmenu();
    }
  }

  public function getdataarrayheader()
  {
    $this->dataarrayheader = array(SessionOperations::getWbLogin());
  }

  
  public function getdataarraybody()
  {
    
    
    
    $belegungen = self::$getBelegungStrategy->getBelegungen($this->searchOptions);

    
    foreach ($belegungen as $belegung) {
      $belegung->kurs->isbeendet = $belegung->kurs->isKursBeendet();


      $kathauptId = 823;
      $belegung->feedbacklink = CleanOperations::cleanStringForHtml(INDEXSCRIPT . '?kathaupt=' . $kathauptId . '&knr='
                                 . $belegung->knr . '&belid=' . $belegung->id);

      $belegung->showFeedbacklink = FeedBackAPI::showFeedbackLinkStammhoererLogin($belegung->kurs->ende_dat);
    }
    $this->dataarraybody = $belegungen;
  }

  private function getBelegungsIds()
  {
    return self::$getBelegungStrategy->getBelegungsIds($this->searchOptions);
  }

  
  public function getAnzahlStandardBelegungen()
  {
    $this->searchOptions->setSearchOptions(true);
    $allbelIds = $this->getBelegungsIds();
    $this->searchOptions->setSearchOptions(false); 

    return count($allbelIds);
  }

  
  public function getAnzahlBelegungen()
  {
    $belIds = $this->getBelegungsIds();

    return count($belIds);
  }

  
  public function getFilterBeginn()
  {
    return $this->searchOptions->vondat;
  }

  public function getdataarrayfooter()
  {
    $this->dataarrayfooter = array(SessionOperations::getWbLogin());
  }

  public function getdataarraynocolumn()
  {
    $this->dataarraynocolumn = array(SessionOperations::getWbLogin());
  }

  public function showheader()
  {
    $tmp = $this->exportadapter;
    $this->exportadapter = $this->exportadapterStammhoerer;
    echo $this->getheader();
    $this->exportadapter = $tmp;
  }

  public function showbody()
  {
    $tmp = $this->exportadapter;
    $this->exportadapter = $this->exportadapterBelegung;
    $api = new StammhoererWeitermeldungApi('');
    $this->exportadapter->setSightInfo('ermaessigung_ungueltig', $api->isErmaessigungUngueltig());
    echo $this->getbody();
    $this->exportadapter = $tmp;
  }

  public function showfooter()
  {
    $tmp = $this->exportadapter;
    $this->exportadapter = $this->exportadapterStammhoerer;
    echo $this->getfooter();
    $this->exportadapter = $tmp;
  }

  private function _showNichtEingeloggt()
  {
    $this->getdataarraynocolumn();
    $tmp = $this->exportadapter;
    $this->exportadapter = $this->exportadapterStammhoerer;
    $this->shownocolumn();
    $this->exportadapter = $tmp;
  }
}

class MeineKurseSearchOptions
{
  public $status;
  public $vondat;
  public $includeAbwZahlerAnmeldungen;
  public $includeKinderAnmeldungen;

  
  public $knr;

  public function __construct()
  {
    $this->status = self::getStatusFromSettings();
    $this->setSearchOptions();
  }

  
  private static function getStatusFromSettings()
  {
    static $hlStatus = null;
    if (is_null($hlStatus)) {
      
      $einstellungen = ToolSettingsAPI::getToolSettings(4);
      
      
      $possibleValues = 'ATWSZP';
      if (DBWorkBASysSettings::isGoslarVhs()) {
        $possibleValues .= 'I';
      }
      if (DBWorkBASysSettings::isKornwestheimEbz()) {
        $possibleValues .= 'IKL';
      }
      if (DBWorkBASysSettings::isLippstadtVHS()) {
        $possibleValues .= 'I';
      }
      if (DBWorkBASysSettings::isInnsbruckStadt()) {
        $possibleValues .= 'G';
      }
      $hlStatus = static::getStatusFromInputField($einstellungen, $possibleValues);
      if ($hlStatus === '') {
        $hlStatus = 'ATWSZ';
      }
    }

    return $hlStatus;
  }

  
  protected static function getStatusFromInputField($pEinstellungen, $pPossibleValues)
  {
    return StringOperations::strtoupper(StringOperations::filterValidChars($pEinstellungen->kundenLoginStatus, $pPossibleValues));
  }

  
  public function setSearchOptions($pEnforceStandardFilter = false)
  {
    
    if (!$pEnforceStandardFilter && $this->isValidFilterRequest()) {
      $this->vondat = DateTimeOperations::getValidDateString(RequestOperations::getVarValue('filterBeginn'));
    } else { 
      if (DBWorkBASysSettings::isLippstadtVHS()) {
        $this->setSearchOptionsLippstadt();

        return;
      }
      $fromDate = DateTimeObj::getNow();
      $fromDate->addYears(-1);
      $this->vondat = $fromDate->getDate();
    }
    
    $einstellungen = ToolSettingsAPI::getToolSettings(4);
    if (is_numeric($einstellungen->kundenLoginBelegungMaxMonthsBack) && $einstellungen->kundenLoginBelegungMaxMonthsBack > 0) {
      $minDate = DateTimeOperations::addMonths(DateTimeOperations::getDateNow(), -1 * abs($einstellungen->kundenLoginBelegungMaxMonthsBack), true);
      $this->vondat = DateTimeOperations::max($minDate, $this->vondat);
    }
    $this->includeAbwZahlerAnmeldungen = $einstellungen->abweichenderZahlerAnmeldungenAnzeigen;
    $this->includeKinderAnmeldungen = 1; 
  }

  private function setSearchOptionsLippstadt()
  {
    $einstellungen = ToolSettingsAPI::getToolSettings(4);
    if (is_numeric($einstellungen->kundenLoginBelegungMaxMonthsBack) && $einstellungen->kundenLoginBelegungMaxMonthsBack > 0) {
      $date = DateTimeOperations::addMonths(DateTimeOperations::getDateNow(), -1 * abs($einstellungen->kundenLoginBelegungMaxMonthsBack), true);
      $this->vondat = $date;
      $this->includeAbwZahlerAnmeldungen = $einstellungen->abweichenderZahlerAnmeldungenAnzeigen;
    }
  }

  public function isValidFilterRequest()
  {
    return RequestOperations::isDefined('filterBeginn') && DateTimeOperations::isValidDate(RequestOperations::getVarValue('filterBeginn'));
  }
}

abstract class MeineKurseGetBelegungenStrategy
{
  protected $tnr;

  public function __construct($pTnr)
  {
    $this->tnr = $pTnr;
  }

  public static function getStrategyForStammhoerer()
  {
    $wblogin = SessionOperations::getWbLogin();
    if (!is_null($wblogin) && $wblogin->tnr > 0) {
      return static::getStrategy($wblogin->tnr);
    }

    return null;
  }

  public static function getStrategy($tnr)
  {
    if ($tnr > 0) {
      if (SessionOperations::isDmzBetrieb() && AbgleichAPI::ping()) {
        return new MeineKurseGetBelegungenStrategyDMZ($tnr);
      } else {
        $dboperation = DBOperation::getInstance(2);
        if ($dboperation == null || !$dboperation->checkConnection()) {
          
          return new MeineKurseGetBelegungenStrategyDb($tnr, 1);
        } else {
          return new MeineKurseGetBelegungenStrategyDb($tnr, 2);
        }
      }
    }

    return null;
  }

  final public function getBelegungen($pSearchOptions)
  {
    $cacheKey = $this->getCacheKey($pSearchOptions);
    static $belCache = null;
    if (is_null($belCache)) {
      $belCache = array();
    }
    if (!isset($belCache[$cacheKey])) {
      $this->setSearchParameters($pSearchOptions);
      $belCache[$cacheKey] = $this->getBelegungenByIdsStrategyDependentPart($pSearchOptions);
    }

    return $belCache[$cacheKey];
  }

  protected function getCacheKey($pSearchOptions)
  {
    return serialize($pSearchOptions);
  }

  final public function getBelegungsIds($pSearchOptions)
  {
    $cacheKey = $this->getCacheKey($pSearchOptions);
    static $idCache = null;
    if (is_null($idCache)) {
      $idCache = array();
    }
    if (!isset($idCache[$cacheKey])) {
      $this->setSearchParameters($pSearchOptions);
      $idCache[$cacheKey] = $this->getBelegungsIdsStrategyDependentPart($pSearchOptions);
    }

    return $idCache[$cacheKey];
  }

  abstract public function setOrderBy();

  abstract protected function getBelegungenByIdsStrategyDependentPart($pBelegungsIds);

  abstract protected function getBelegungsIdsStrategyDependentPart($pSearchOptions);

  abstract public function setSearchParameters($pSearchOptions);
}

class MeineKurseGetBelegungenStrategyDb extends MeineKurseGetBelegungenStrategy
{
  private $dbwBelegung;

  public function __construct($pTnr, $pDbTyp = 2)
  {
    parent::__construct($pTnr);
    $this->dbwBelegung = new DBWorkBelegung($pDbTyp);
    $this->setOrderBy();
  }

  public function setOrderBy()
  {
    $this->dbwBelegung->orderby = 'beginn_dat';
    $this->dbwBelegung->orderbyasc = false;
    $this->dbwBelegung->orderby2 = 'beginn';
    $this->dbwBelegung->orderbyasc2 = false;
  }

  public function setSearchParameters($pSearchOptions)
  {
    $this->dbwBelegung->newSearch();
    $this->dbwBelegung->fromobject->status = $pSearchOptions->status;
    $this->dbwBelegung->fromobject->kurs->beginn_dat = $pSearchOptions->vondat;
  }

  public function getBelegungsIdsStrategyDependentPart($pSearchOptions)
  {
    $belids = $this->dbwBelegung->getBelegungsIdsbyTeilnehmerNR($this->tnr);
    if ($pSearchOptions->includeAbwZahlerAnmeldungen) {
      $abwBelIds = $this->dbwBelegung->getAbwZahlerBelegungsIdsForTeilnehmer($this->tnr);

      return array_merge($belids, $abwBelIds);
    }

    return $belids;
  }

  public function getBelegungenByIdsStrategyDependentPart($pSearchOptions)
  {
    return $this->dbwBelegung->getBelegungenByIds($this->getBelegungsIds($pSearchOptions));
  }
}

class MeineKurseGetBelegungenStrategyDMZ extends MeineKurseGetBelegungenStrategy
{
  public static $cache = array();
  
  protected $searchParameters;

  private $dbanmstat;

  public function getBelegungsIdsStrategyDependentPart($pSearchOptions)
  {
    $cacheKey = $this->getCacheKey($pSearchOptions);
    if (!isset(self::$cache[$cacheKey])) {
      self::$cache[$cacheKey] = $this->getBelegungInfosPerDMZ($this->tnr);
    }

    return $this->getIds($cacheKey);
  }

  
  public function getBelegungenPerDMZMitKinder($pTnr, $pKnr = null, $pStatus = '')
  {
    $this->searchParameters->status = $pStatus;
    $this->searchParameters->knr = $pKnr;
    $belegungenMitBegleitpersonen = $this->getBelegungInfosPerDMZ($pTnr);
    $tool4settings = ToolSettingsAPI::getToolSettings(4);
    $tnrBegleitperson = $tool4settings->tnrBegleitperson;

    return array_filter($belegungenMitBegleitpersonen, function($belegung) use ($tnrBegleitperson) {
      return $belegung->tnr != $tnrBegleitperson;
    });
  }

  private function getIds($pCacheKey)
  {
    $result = array();
    if (isset(self::$cache[$pCacheKey])) {
      foreach (self::$cache[$pCacheKey] as $item) {
        $result[] = $item->id;
      }
    }

    return $result;
  }

  
  public function getBelegungenByIdsStrategyDependentPart($pSearchOptions)
  {
    $cacheKey = $this->getCacheKey($pSearchOptions);
    if (!isset(self::$cache[$cacheKey])) {
      self::$cache[$cacheKey] = $this->getBelegungInfosPerDMZMitKinderGruppiert($this->tnr);
    }

    return self::$cache[$cacheKey];
  }

  
  public function getBelegungenByIdsStrategyDependentPartNotGrouped($pSearchOptions)
  {
    $cacheKey = $this->getCacheKey($pSearchOptions);
    if (!isset(self::$cache[$cacheKey])) {
      self::$cache[$cacheKey] = $this->getBelegungInfosPerDMZ($this->tnr);
    }

    return self::$cache[$cacheKey];
  }

  public function setSearchParameters($pSearchOptions)
  {
    $this->searchParameters = $pSearchOptions;
  }

  
  public function getBelegungInfosPerDMZ($pTnr)
  {
    $abgleichAPI = new AbgleichAPI();
    $message = new XMLNode('belegung');
    $message->addChild(new XMLNode('tnr', $pTnr));

    $message->addChild(new XMLNode('status', $this->searchParameters->status));
    $message->addChild(new XMLNode('vondat', $this->searchParameters->vondat));
    $message->addChild(new XMLNode('includeabwzahleranmeldungen', $this->searchParameters->includeAbwZahlerAnmeldungen));
    $message->addChild(new XMLNode('includekinderanmeldungen', $this->searchParameters->includeKinderAnmeldungen));

    if (DBWorkBASysSettings::isInnsbruckStadt()) {
      $tool4settings = ToolSettingsAPI::getToolSettings(4);
      $message->addChild(new XMLNode('tnrbegleitperson', $tool4settings->tnrBegleitperson));
    }

    if ($this->searchParameters->knr !== '') {
      $message->addChild(new XMLNode('knr', $this->searchParameters->knr));
    }

    $nutzlast = new Nutzlast($message);
    $nutzlast->addNode(new XMLNode('nomapping', 'W'));

    $result = $abgleichAPI->sendeNachricht(
      AbgleichAPI::ABGLEICH_GET_BELEGUNGEN_FOR_TEILNEHMER,
      $nutzlast
    );
    $resultList = JsonOperations::getFromString($result->reason);
    $belegungsList = array();
    $alreadyAddedBelIds = array();
    foreach ($resultList as $item) {
      $belegung = $this->dmzResultToBelegung($item);
      if (!in_array($belegung->id, $alreadyAddedBelIds)) {
        $belegungsList[] = $belegung;
        $alreadyAddedBelIds[] = $belegung->id;
      }
    }
    self::$cache[$pTnr] = $belegungsList;

    return self::$cache[$pTnr];
  }

  
  public function getBelegungInfosPerDMZMitKinderGruppiert($pTnr)
  {
    $belegungsList = $this->getBelegungInfosPerDMZ($pTnr);
    self::$cache[$pTnr] = $this->groupKinderByKursNr($belegungsList, $pTnr);

    return self::$cache[$pTnr];
  }

  
  public static function groupKinderByKursNr($belegungsList, $pTnrElternteil)
  {
    
    $knrBelegungsArray = ArrayOperations::setAttributAsKeyArray($belegungsList, 'knr');
    $result = array();
    foreach ($knrBelegungsArray as $belegungen) {
      $result[] = self::getBelegungMitMehrerenKindern($belegungen, $pTnrElternteil);
    }

    return $result;
  }

  
  private static function getBelegungMitMehrerenKindern($belegungen, $pTnrElternteil)
  {
    $kinderObjAry = array();
    $tool4settings = ToolSettingsAPI::getToolSettings(4);
    $anmStatus = \StringOperations::str_split($tool4settings->kundenLoginStatus);
    $isInnsbruckStadt = DBWorkBASysSettings::isInnsbruckStadt();
    foreach ($belegungen as $belegung) {
      if ($pTnrElternteil != $belegung->tnr) {
        if ($isInnsbruckStadt && $belegung->tnr == $tool4settings->tnrBegleitperson) {
          continue;
        }
        $kinderObj = new stdClass();
        $kinderObj->name = $belegung->teilnehmer->vorname . ' ' . $belegung->teilnehmer->name;
        
        $kinderObj->status = $belegung->status;
        $kinderObj->belegId = $belegung->id;
        $kinderObj->tnr = $belegung->tnr;
        $kinderObjAry[] = $kinderObj;
      }
    }

    if ($isInnsbruckStadt) {
      $tnrBegleitperson = $tool4settings->tnrBegleitperson;
      $begleitPersonenStatusArray = array();
      foreach ($anmStatus as $status) {
        $begleitPersonCount = count(array_filter($belegungen, function($belegung) use ($tnrBegleitperson, $pTnrElternteil, $status) {
          return $pTnrElternteil == $belegung->firma && $belegung->tnr == $tnrBegleitperson && $belegung->status == $status;
        }));
        $begleitPersonenStatusArray[$status] = $begleitPersonCount;
      }
      $belegungen[0]->anzahl_begleitpersonen = $begleitPersonenStatusArray;
    }
    
    
    $belegungen[0]->setValue2Var('kindernamen', $kinderObjAry);

    return $belegungen[0];
  }

  private function dmzResultToBelegung($pItem)
  {
    $dbwBelegung = DBWorkBelegung::getDefaultInstance(1, false, true);
    if (is_null($this->dbanmstat)) {
      $this->dbanmstat = new DBWorkHLStatusKZ(1, true);
      $this->dbanmstat->prepareListcompare();
    }
    $belegung = $dbwBelegung->getNewObject();
    $belegung->kurs = WBKursStore::getKurs($pItem->Knr);
    $belegung->id = $pItem->Belid;
    $belegung->anm_datum = $pItem->AnmDatum;
    $belegung->tnr = $pItem->Tnr;
    $belegung->firma = $pItem->Firma;
    $belegung->teilnehmer->id = $pItem->Tnr;
    $belegung->knr = $pItem->Knr;
    $belegung->kurs->id = $pItem->Knr;
    $belegung->status = $pItem->Status1;
    if ($belegung->status == '' || $belegung->status == ' ') {
      $belegung->status = 'A';
    }
    $belegung->nuronline = $pItem->NurOnline === 'W';
    $belegung->status_lang = $this->dbanmstat->getFieldbyID($belegung->status, 'kennz', 'text');
    $belegung->niveau = $pItem->Niveau;
    $belegung->entgelt = MathOperations::floatToString($pItem->Entgelt);
    $belegung->bet_offen = MathOperations::floatToString($pItem->BetOffen);
    $belegung->kurs->beginn_dat = $pItem->BeginnDat;
    $belegung->kurs->beginn = $pItem->BeginnZeit;
    $belegung->kurs->ende_dat = $pItem->EndeDat;
    $belegung->kurs->ende = $pItem->EndeZeit;
    $belegung->kurs->kurzbez = $pItem->Kurzbez;
    $belegung->kurs->titel = $pItem->Titel;
    $belegung->kurs->ausfall = $pItem->Ausfall == 'J';
    $belegung->kurs->abschluss = $pItem->Abschluss;
    $belegung->kurs->ort = $pItem->Ort;
    $belegung->kurs->teil_min = $pItem->TnMin;
    $belegung->kurs->anmeldungen = $pItem->AnzahlAnmeldungen;
    $belegung->kurs->anm_ende = $pItem->AnmEnde;
    $belegung->kurs->anm_ende_manu = $pItem->AnmEndeManu === 'W';
    $belegung->teilnehmer->name = $pItem->TnName;
    $belegung->teilnehmer->vorname = $pItem->TnVorname;
    $belegung->teilnehmer->email_anzeige = $pItem->TnEmail;

    return $belegung;
  }

  public function setOrderBy()
  {
    
  }
}