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


class DataMenuWeitermeldung extends DataMenuMainTopLeft
{
  
  private $weitermeldecode;

  
  private $gebuehrensummeAnzeige;

  
  private $tnInfo;

  public function getsight($pSightId = 781)
  {
    parent::getsight($pSightId);
  }

  public function mainmenu()
  {
    if (!SessionOperations::isDmzBetrieb()) {
      echo 'Die Online-Weitermeldung wird aktuell nicht unterstützt!';
      echo "</div>\n\n";

      return;
    }

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

    echo '<div class="hauptseite">' . "\n" . $this->getContentAnker();
    $this->statusmenu();

    
    $this->getsight();
    $this->getdataarraynocolumn();

    
    $optinHash = GetOperations::getVarValue('optinhash');
    if ($optinHash != '') {
      $this->handleDblOptIn($optinHash);
    }

    
    $this->weitermeldecode = SessionOperations::getDatamodulFromSession(new Weitermeldecode(), SESSION_PREFIX_WM);

    
    if ($this->weitermeldecode->isEmpty()) {
      $this->shownocolumn();
      echo "</div>\n\n";

      return;
    }

    
    $vorgaengerkurs = $this->getVorgaengerkurs($this->weitermeldecode->knr);
    $nachfolgekurs = $this->getNachfolgekurs($this->weitermeldecode->knr_nachfolgekurs);

    
    KursStore::setIntoCache($nachfolgekurs);

    
    
    $belegungBemerkung = $this->getBelegungBemerkung($this->weitermeldecode);
    $this->tnInfo = $this->erstelleTnInfo(
      $this->weitermeldecode,
      $nachfolgekurs,
      $this->ermittleZahlart4Weitermeldung($this->weitermeldecode->belegid),
      $belegungBemerkung
    );
    $this->gebuehrensummeAnzeige = $this->ermittleKursgebuehr($nachfolgekurs, $this->tnInfo->getTeilnehmer(), $this->tnInfo->getWeitere());

    $this->getdataarrayheader($vorgaengerkurs);
    $this->getdataarraybody($nachfolgekurs);
    $this->getdataarrayfooter();
    $this->getdataarraynodata();


    if (PostOperations::getVarValue('agb_checkbox') === 'on') {
      $success = $this->weitermelden($nachfolgekurs);
      $this->setExportSightInfo('weitermeldung_ok', $success);
      $this->shownodata(); 
    } else {
      $this->showheader(); 
      $this->showbody(); 
      $this->showfooter(); 
    }

    echo "</div>\n\n";
  }

  public function getdataarrayheader(?\Kurs $kurs = null)
  {
    $this->dataarrayheader = array($kurs);
  }

  protected function getExportAdapterHeader()
  {
    return new ExpKurse();
  }

  public function getdataarraybody(?\Kurs $kurs = null)
  {
    $kurs->gebuehr = MathOperations::floatToString($this->gebuehrensummeAnzeige);
    $this->dataarraybody = array($kurs);
  }

  protected function getExportAdapterBody()
  {
    return new ExpKurse();
  }

  public function getdataarrayfooter()
  {
    if ($this->weitermeldecode->isEmpty()) {
      parent::getdataarrayfooter();

      return;
    }

    $this->dataarrayfooter = array($this->tnInfo->getTeilnehmer());
  }

  protected function getExportAdapterFooter()
  {
    return new ExpTeilnehmer();
  }

  public function _getClickPath($pName = 'Weitermelden')
  {
    $this->_setStdClickPath($pName, 'clickWeitermeldungFormularText');

    return $this->clickpfad;
  }

  
  public function weitermelden(\Kurs $nachfolgekurs): bool
  {
    $stammhoererWasLoggedIn = false;
    $stammhoererTnr = SessionOperations::getCurrentStammhoererTnr();
    if (SessionOperations::isStammhoererLoggedIn()) {
      LoginApi::logoutStammhoerer();
      $stammhoererWasLoggedIn = true;
    }

    $this->setSessionValues4WeitermeldenBelegung($this->tnInfo->getTeilnehmer(), $nachfolgekurs);
    if (isset($nachfolgekurs->typ) && ($nachfolgekurs->typ == 'L' || $nachfolgekurs->typ == 'K')) {
      $this->setSessionValues4WeitermeldenKinder($this->tnInfo->getWeitere());
    }

    $success = $this->anmelden($this->weitermeldecode, $nachfolgekurs);
    if ($success) {
      WeitermeldungAPI::setWeitermeldecodeEingeloest($this->weitermeldecode->code);
      try {
        if ($this->weitermeldecode->belegid_nachfolgekurs > 0 || $this->weitermeldecode->belegid_nachfolgekurs == -10) {
          WeitermeldungAPI::deletePlatzreservierungen($nachfolgekurs, $this->weitermeldecode);
        }
      } catch (Exception $ex) {
        
        
        Logger::logg(
          "Fehler beim Löschen der Platzreservierung für die Weitermeldung: {$ex->getMessage()}",
          5123
        );
      }
      if ($stammhoererWasLoggedIn) {
        LoginApi::loginStammhoererByTnr($stammhoererTnr);
      }
    }
    $this->unSetSessionValues4Weitermelden();

    return $success;
  }

  
  private function anmelden(\Weitermeldecode $weitermeldecode, \Kurs $nachfolgekurs): bool
  {
    $buchungsvorgang = new BuchungsvorgangWEBBASysWeitermeldung($nachfolgekurs, $weitermeldecode->tnr);
    $buchungsvorgang->setTNInfo($this->tnInfo);
    $buchungsvorgang->setKurseBySession();
    $buchungsvorgang->setBuchungsVars();

    $buchungsvorgang->buchungStep1();
    $erfolgreich = $buchungsvorgang->buchungStep2();

    if ($erfolgreich) {
      $buchungsvorgang->sendTNBestaetigung();
      $buchungsvorgang->sendBestaetigungKopie();
    }

    return $erfolgreich;
  }

  
  private function setSessionValues4WeitermeldenKinder(array $kinderTnPflicht)
  {
    SessionOperations::setVarValueAnm(ANMELDEART, ANMELDEART_INTERN_ELTERNKIND);
    SessionOperations::setVarValueWk('gAnzahl_Kinder', count($kinderTnPflicht));

    foreach ($kinderTnPflicht as $index => $kind) {
      $j = $index + 1;
      SessionOperations::setVarValueWk('w_vorname_k' . $j, $kind->vorname);
      SessionOperations::setVarValueWk('w_name_k' . $j, $kind->name);
      SessionOperations::setVarValueWk('w_gebdat_k' . $j, $kind->gebdat);
      SessionOperations::setVarValueWk('w_info_k' . $j, $kind->bemerkung);
    }
  }

  
  private function setSessionValues4WeitermeldenBelegung(\TeilnehmerPflicht $teilnehmer, \Kurs $nachfolgekurs)
  {
    SessionOperations::setVarValueWk('w_bemerkung', $teilnehmer->bemerkung);
    SessionOperations::setVarValueIntern('w_anmeldeart', 'W'); 

    if (isset($nachfolgekurs->typ) && ($nachfolgekurs->typ == 'L' || $nachfolgekurs->typ == 'K')) {
      SessionOperations::setVarValueIntern('w_zahlart', $teilnehmer->zahlart);
    } else {
      SessionOperations::setVarValueWk('w_zahlart_b', $teilnehmer->zahlart);
    }
  }

  
  private function unSetSessionValues4Weitermelden()
  {
    SessionOperations::setVarValueWk('w_bemerkung', '');
    SessionOperations::setVarValueWk('w_zahlart_b', '');
    SessionOperations::setVarValueIntern('w_zahlart', '');
    SessionOperations::setVarValueIntern('w_anmeldeart', '');
    SessionOperations::setVarValueWeitermelden('active', '0');
    SessionOperations::setVarValueWeitermelden('special_status_check', null);
    SessionOperations::unsetDatamodulFromSession(new Weitermeldecode(), SESSION_PREFIX_WM);
    SessionOperations::cleanupSessionNachAnmeldung();
  }

  
  private function getWeitermeldeCodeFromDmz(int $id): Weitermeldecode
  {
    try {
      return WeitermeldungAPI::getWeitermeldecodeFromDmzById($id);
    } catch (Exception $e) {
      Logger::logg(
        "Fehler beim Abrufen des Weitermeldecodes mit ID '$id' per DMZ (Double-OptIn): {$e->getMessage()}",
        5123
      );

      return new Weitermeldecode();
    }
  }

  
  private function getVorgaengerkurs(?string $knr): \Kurs
  {
    if ($knr == null) {
      return new Kurs();
    }

    try {
      
      
      return \Kufer\Web\Classes\Addfunctions\KursOperations::getKursFromDMZ($this->weitermeldecode->knr, true);
    } catch (Exception $e) {
      Logger::logg(
        "Weitermelden: Fehler beim Laden der Kursdaten des Vorgänger-Kurses ({$this->weitermeldecode->knr_nachfolgekurs}).",
        5123
      );
      
      return new Kurs();
    }
  }

  
  private function getNachfolgekurs(?string $knr): \Kurs
  {
    if ($knr == null) {
      return new Kurs();
    }

    try {
      return \Kufer\Web\Classes\Addfunctions\KursOperations::getKursFromDMZ($knr);
    } catch (Exception $e) {
      Logger::logg(
        "Weitermelden: Fehler beim Laden der Kursdaten des Nachfolge-Kurses ({$knr}).",
        5123
      );
      
      return new Kurs();
    }
  }

  
  private function getTeilnehmerPflicht($tnr): \TeilnehmerPflicht
  {
    $teilnehmer = TeilnehmerAPI::getTeilnehmerInfosPerDMZ($tnr, true);
    $teilnehmer = $teilnehmer->copyAsTeilnehmerPflicht();
    $teilnehmer->id = $tnr;
    $kommInfo = KommunikationsAPI::getKommunikationInfosPerDMZ($tnr);

    return LoginApi::kommToTn($teilnehmer, $kommInfo);
  }

  
  private function getBelegungBemerkung(\Weitermeldecode $weitermeldecode): string
  {
    if ($weitermeldecode->belegid_nachfolgekurs > 0) {
      $dmzResponse = BelegungAPI::getBelegungsinformationen($weitermeldecode->belegid_nachfolgekurs, true);
      $belegungsInfos = JsonOperations::decode($dmzResponse->reason, false, 512, 0, true);
      $belegungBemerkungString = $belegungsInfos->Bemerkung;
    } else {
      $belegungBemerkungString = 'weitergemeldet aus ' . $weitermeldecode->knr;
    }

    return $belegungBemerkungString;
  }

  
  private function erstelleTnInfo(\Weitermeldecode $weitermeldecode, \Kurs $nachfolgekurs, string $zahlart, string $bemerkung): TNInfo
  {
    $hauptTn = $this->getTeilnehmerPflicht($weitermeldecode->tnr);
    $hauptTn->bemerkung = $bemerkung;
    $hauptTn->zahlart = $zahlart;

    $weitereTn = array();

    if (isset($nachfolgekurs->typ) && ($nachfolgekurs->typ == 'L' || $nachfolgekurs->typ == 'K')) {
      $kinderTnrs = WeitermeldungAPI::getKinderTnrForWeitermeldecode($weitermeldecode);

      foreach ($kinderTnrs as $kindTnr) {
        $kind = $this->getTeilnehmerPflicht($kindTnr);
        $kind->bemerkung = $bemerkung;
        $weitereTn[] = $kind;
      }
    }

    return new TNInfo($hauptTn, $weitereTn);
  }

  
  private function ermittleZahlart4Weitermeldung($belegId): string
  {
    $dmzResponse = BelegungAPI::getBelegungsinformationen($belegId, true);
    $belegungsInfos = JsonOperations::decode($dmzResponse->reason, false, 512, 0, true);

    return $belegungsInfos->Zahlart == 'Ü' ? 'Ü' : '';
  }

  
  private function ermittleKursgebuehr(\Kurs $nachfolgekurs, \TeilnehmerPflicht $hauptTn, ?array $kinder): float
  {
    $gebuehrensumme = 0.0;

    
    if (isset($nachfolgekurs->typ) && ($nachfolgekurs->typ != 'K')) {
      $dbwKursGeb = new DBWorkKursgebuehr();
      $gebuehrensumme = $dbwKursGeb->getKursgebuehrErmaessigt($nachfolgekurs->id, $hauptTn->id, '', '', '', $hauptTn);
    }

    
    if (isset($nachfolgekurs->typ) && ($nachfolgekurs->typ == 'L' || $nachfolgekurs->typ == 'K')) {
      $gebuehrenrechner = GebuehrenElementRechner::createInstance(true);
      $gebuehrenrechner->ladeGebuehren($nachfolgekurs->id);
      $kGebBerKontextTn = $this->createKGebBerKontextTeilnehmer($hauptTn, $nachfolgekurs->id);

      foreach ($kinder as $index => $kind) {
        $gebuehrensumme += $gebuehrenrechner->getKindGebuehrErmaessigtSumme($index + 1, $kGebBerKontextTn);
      }
    }

    return $gebuehrensumme;
  }

  private function createKGebBerKontextTeilnehmer($hauptTeilnehmer, $knr): KursgebuehrBerechnungsKontextTeilnehmer
  {
    $teilnehmerKontext = new KursgebuehrBerechnungsKontextTeilnehmer();
    if ($hauptTeilnehmer->erm_grund > 0) {
      $dbwErmaess = new DBWorkErmaessigung();
      if ($dbwErmaess->isErmaessigungStillValid($knr, $hauptTeilnehmer->erm_ende)) {
        $teilnehmerKontext = KursgebuehrBerechnungsKontextTeilnehmer::fromErmGrund($hauptTeilnehmer->erm_grund);
      }
    }

    return $teilnehmerKontext;
  }

  
  private function handleDblOptIn($optinHash)
  {
    $dbwDblOptIn = new DBWorkDblOptinWeitermeldung();
    $dblOptIn = $dbwDblOptIn->getDblOptinByOptin($optinHash);
    if ($dblOptIn == null || $dblOptIn->isEmpty()) {
      Logger::logg(
        "Weitermelden: Fehler beim Verarbeiten des DoubleOptIns für OptInHash '{$optinHash}'",
        5123
      );
      $this->setExportSightInfo('dbloptin_fehler', '1');
      $this->shownocolumn();
      echo "</div>\n\n";

      return;
    }
    $weitermeldecode = $this->getWeitermeldeCodeFromDmz($dblOptIn->weitermeldecode_id);
    SessionOperations::setDatamodulToSession($weitermeldecode, SESSION_PREFIX_WM);
    $this->processDoubleOptIn($dblOptIn, $weitermeldecode->tnr);
  }

  
  private function processDoubleOptIn(WebDblOptin $dblOptIn, int $tnr): void
  {
    $komm = new Kommunikation();
    $komm->art = 'E';
    $komm->typ = 'T';
    $komm->wert = $dblOptIn->email;
    $komm->bezeichner = 'E-Mail';
    $komm->nr = $tnr;
    try {
      $success = KommunikationsAPI::addKommunikation($komm) == 'sendDone';
      if ($success) {
        DBWorkDblOptinWeitermeldung::getDefaultInstance()->deleteByOptin($dblOptIn->optin);
      } else {
        Logger::logg('Weitermeldung Double-Opt-In: Kommunikation wurde nicht hinzugefügt', 5123);
      }
    } catch (Exception $e) {
      Logger::logg(
        "Weitermeldung Double-Opt-In: Fehler beim Hinzufügen der Kommunikation: {$e->getMessage()}",
        5123
      );
    }
  }
}