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


class GebuehrenBerechnung
{
  
  private $kGebBerKontexts = array();

  
  private $gebuehrenElemente = array();
  private $isKuferSql5;

  private $wkKontext;
  private $wkState;

  
  public function __construct(?bool $isKuferSql5 = null)
  {
    if (is_null($isKuferSql5)) {
      $isKuferSql5 = System::isKuferSql5();
    }
    $this->isKuferSql5 = $isKuferSql5;
    $this->wkKontext = new Kufer\Web\Classes\Gebuehren\WarenkorbBerechnungsKontext();
    $this->wkState = new Kufer\Web\Classes\Gebuehren\WarenkorbBerechnungsState();
  }

  
  public function setBerechnungsKontexte(array $kGebBerKontexte, ?Kufer\Web\Classes\Gebuehren\WarenkorbBerechnungsKontext $wkKontext = null): void
  {
    $this->kGebBerKontexts = $kGebBerKontexte;
    if ($wkKontext) {
      $this->wkKontext = $wkKontext;
    }
  }

  
  public function loadKursgebuehrenElemente(KursgebuehrElementeLader $lader): void
  {
    $this->gebuehrenElemente = $lader->load();
  }

  
  public function berechneGebuehrenByKurs(): array
  {
    $result = array();
    foreach ($this->kGebBerKontexts as $kontext) {
      $result[$kontext->knr] = $this->berechneGebuehren($kontext, $this->wkKontext, $this->wkState);
    }

    return $result;
  }

  
  public function berechneGebuehrenSumme(): float
  {
    return array_sum($this->berechneGebuehrenByKurs());
  }

  
  public function berechneGebuehrenForKurs(string $knr): float
  {
    return $this->berechneGebuehren($this->kGebBerKontexts[$knr], $this->wkKontext, $this->wkState);
  }

  
  public function getGebuehrenSaetze(string $knr): array
  {
    $kGebBerKontext = $this->kGebBerKontexts[$knr];
    $berechner = $this->setupGebuehrenElementRechner($kGebBerKontext);
    $tnSaetze = array();
    foreach ($kGebBerKontext->tns as $key => $tn) {
      $tnSaetze = array_merge(
        $tnSaetze,
        $berechner->getGebuehrenSaetzeErmaessigt($key, $kGebBerKontext, $this->wkKontext, $this->wkState)
      );
    }
    $kinderSaetze = array();
    $kontextTnKind = $this->getKinderErmGrund($kGebBerKontext);
    for ($i = 1; $i <= $kGebBerKontext->kinderanzahl; $i++) {
      $kinderSaetze = array_merge(
        $kinderSaetze,
        $berechner->getKindGebuehrErmaessigtSaetze($i, $kontextTnKind, $this->wkKontext, $this->wkState)
      );
    }

    return array('tnSaetze' => $tnSaetze, 'kinderSaetze' => $kinderSaetze);
  }

  
  public function berechneGebuehren(
    KursgebuehrBerechnungsKontext $kGebBerKontext,
    ?Kufer\Web\Classes\Gebuehren\WarenkorbBerechnungsKontext $wkKontext = null,
    ?Kufer\Web\Classes\Gebuehren\WarenkorbBerechnungsState $wkState = null
  ): float {
    $berechner = $this->setupGebuehrenElementRechner($kGebBerKontext);
    $sum = 0.0;
    $kontextTnKind = $this->getKinderErmGrund($kGebBerKontext);
    for ($i = 1; $i <= $kGebBerKontext->kinderanzahl; $i++) {
      $sum += $berechner->getKindGebuehrErmaessigtSumme($i, $kontextTnKind, $wkKontext, $wkState);
    }
    foreach ($kGebBerKontext->tns as $key => $tn) {
      $sum += $berechner->getGebuehrenSummeErmaessigt($key, $kGebBerKontext, $wkKontext, $wkState);
    }

    return $sum;
  }

  
  private function setupGebuehrenElementRechner(KursgebuehrBerechnungsKontext $kGebBerKontext): GebuehrenElementRechner
  {
    $knr = $kGebBerKontext->knr;
    $berechner = GebuehrenElementRechner::createInstance($this->isKuferSql5);
    if (!isset($this->gebuehrenElemente[$knr])) {
      $berechner->ladeGebuehren($knr);
    } else {
      $berechner->setGebuehrenElement($this->gebuehrenElemente[$knr]);
    }

    return $berechner;
  }

  private function getKinderErmGrund($kGebBerKontext): KursgebuehrBerechnungsKontextTeilnehmer
  {
    if (count($kGebBerKontext->tns) > 0) {
      return $kGebBerKontext->tns[0];
    }

    return new KursgebuehrBerechnungsKontextTeilnehmer();
  }
}