<?php

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

if (!defined('BASEDIR')) {
  include_once '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'constants.php';
}


class DataMenuKurseMonatsuebersicht extends DataMenuMain
{
  
  public $dbwork;

  
  public $kurseSorted = array();

  public function __construct($pUrlParameter)
  {
    parent::__construct($pUrlParameter);
    $this->dbwork = new DBWorkKurse();

    $this->settings = ToolSettingsAPI::getToolSettings(4);
  }

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

  public function mainmenu()
  {
    $this->prepareMainmenu();
    $out = "<div class='hauptseite'>\n";
    $this->statusmenu();
    $this->getKurseSorted();

    
    $out .= $this->renderMonthList();

    $this->sight = SightsAPI::getSight(424);
    if ($this->settings->nurAusgewaehlterMonatMonthsOverview) {
      if (isset($this->urlparameter->monat) && StringOperations::strlen($this->urlparameter->monat) > 0) {
        $monatStr = $this->urlparameter->monat;
      } else {
        $monatStr = '-1';
      }
      $month = 00;
      if ($monatStr == -1) {
        $month = date('m');
      } elseif (is_numeric($monatStr)) {
        $month = \StringOperations::pad($monatStr, 2, '0', STR_PAD_LEFT);
      } else {
        $flippedMonthMap = array_flip(DateObj::$_monthMap);
        if (StringOperations::startsWith($monatStr, 'M') && StringOperations::endsWith($monatStr, 'z')) {
          $monatStr = 'März';
        }
        $m = $flippedMonthMap[$monatStr];
        $month = \StringOperations::pad($m, 2, '0', STR_PAD_LEFT);
      }

      if (isset($this->urlparameter->jahr) && StringOperations::strlen($this->urlparameter->jahr) > 0) {
        $year = $this->urlparameter->jahr;
      } else {
        $year = date('Y');
      }

      $this->kurseSorted = array_intersect_key($this->kurseSorted, array($year . '_' . $month => null));
    }

    
    $out .= $this->renderAllKurse();

    $out .= '</div>';

    echo $out;
  }

  protected function getKurseSorted()
  {
    $dbwkurse = $this->initDbwKurse();

    $fromDate = $this->settings->datumVonMonthsOverview;
    $toDate = $this->settings->datumBisMonthsOverview;
    $hardFromDate = $hardToDate = false;
    if ($fromDate != '' && $toDate != '') {
      if (!$this->addfdatetime->isValidDate($fromDate)) {
        Logger::Logg("Monatskursübersicht: ungültiger Konfigwert beim Von-Datum: $fromDate", 4501);

        return;
      }
      if (!$this->addfdatetime->isValidDate($toDate)) {
        Logger::Logg("Monatskursübersicht: ungültiger Konfigwert beim Bis-Datum: $toDate", 4501);

        return;
      }
      $hardFromDate = $this->addfdatetime->getValidDateString($fromDate);
      $hardToDate = $this->addfdatetime->getValidDateString($toDate);
      $kurse = $dbwkurse->getKursIdsWithMonthAndYear($hardFromDate, $hardToDate);
    } else {
      $yearParam = $this->getYearParam();
      $kurse = $dbwkurse->getKursIdsWithMonthAndYearByYear($yearParam);
    }

    $allKurse = array_map(function($pItem) {
      return $pItem['nr'];
    }, $kurse);
    WBKursStore::getKurseByIdArray($allKurse);

    
    $kurseByMonth = $this->prepareKurseByMonth($kurse, $hardFromDate, $hardToDate);

    $this->kurseSorted = $this->fillKurseByMonth($kurseByMonth, $kurse);
  }

  protected function initDbwKurse()
  {
    $settings = $this->settings;
    $dbwkurse = new DBWorkKurseINetAktivFilter();
    $dbwkurse->newSearch();
    
    $dbwkurse->fromobject->suche_nurNichtVolleKurse = $settings->nichtVolleKurseMonthsOverview;
    if ($settings->nurAbAktuellemMonatMonthsOverview) {
      $dbwkurse->fromobject->beginn_dat = $this->getFirstDayOfCurrentMonth();
    }
    $dbwkurse->fromobject->veranart_suche_negativ = $settings->keineKurseDieserVeranartMonthsOverview;
    
    $dbwkurse->justNoAusfall = !$settings->ausfallKurseMonthsOverview;
    $dbwkurse->fromobject->semester = $settings->semlist;
    $dbwkurse->orderby = 'beginn_dat';
    $dbwkurse->select = 'k.nr, k.beginn_dat';

    return $dbwkurse;
  }

  protected function getFirstDayOfCurrentMonth() : string
  {
    return $this->addfdatetime->getValidDateString('1.' . $this->addfdatetime->getMonthByDate($this->addfdatetime->getDateNow()) . '.', true);
  }

  private function getYearParam()
  {
    $yearParam = false;
    if ($this->settings->nurAktuellesJahrMonthsOverview) {
      if ($this->urlparameter->von != '' && is_numeric($this->urlparameter->von)) {
        $yearParam = $this->urlparameter->von;
      } else {
        $date = DateTimeObj::getNow();
        $yearParam = $date->getYear();
      }
    }

    return $yearParam;
  }

  protected function prepareKurseByMonth($kurse, $hardFromDate = false, $hardToDate = false)
  {
    if ($this->settings->nurMonateMitKursenAnzeigen) {
      
      return array();
    }

    
    
    
    
    

    
    $jahresZahlenMitKursen = $this->addJahresZahlenByKurse($kurse);
    
    if ($hardFromDate && $hardToDate) {
      $jahresZahlenMitKursen = $this->addJahresZahlenByRange($jahresZahlenMitKursen, $hardFromDate, $hardToDate);
    }

    
    if (empty($jahresZahlenMitKursen)) {
      $jahresZahlenMitKursen[] = $this->addfdatetime->getYearFromValidDate($this->addfdatetime->getDateNow());
    }

    
    $kurseByMonth = $this->fillFullYears($jahresZahlenMitKursen);

    if ($this->settings->nurAbAktuellemMonatMonthsOverview) {
      $kurseByMonth = $this->removeUntilCurrentMonth($kurseByMonth);
    }
    if ($hardFromDate && $hardToDate) {
      $kurseByMonth = $this->removeByRange($kurseByMonth, $hardFromDate, $hardToDate);
    }

    return $kurseByMonth;
  }

  private function addJahresZahlenByKurse($kurse)
  {
    $jahresZahlenMitKursen = array();
    
    foreach ($kurse as $kurs) {
      if (!isset($jahresZahlenMitKursen[$kurs['jahr']])) {
        $jahresZahlenMitKursen[$kurs['jahr']] = true;
      }
    }

    return $jahresZahlenMitKursen;
  }

  private function addJahresZahlenByRange($jahresZahlenMitKursen, $hardFromDate, $hardToDate)
  {
    $dateFrom = DateTimeObj::createFromString($hardFromDate);
    $dateTo = DateTimeObj::createFromString($hardToDate);
    for ($i = $dateFrom->getYear(); $i <= $dateTo->getYear(); $i++) {
      if (!isset($jahresZahlenMitKursen[$i])) {
        $jahresZahlenMitKursen[$i] = true;
      }
    }

    return $jahresZahlenMitKursen;
  }

  private function fillFullYears($jahresZahlenMitKursen)
  {
    $kurseByMonth = array();
    foreach ($jahresZahlenMitKursen as $curYear => $foo) {
      foreach (ArrayOperations::xrange(1, 12) as $curMonth) {
        $monat = \StringOperations::pad($curMonth, 2, '0', STR_PAD_LEFT);
        $kurseByMonth[$curYear . '_' . $monat] = array(
          'monat' => $this->getNewMonat($curYear, $monat),
          'kurse' => array()
        );
      }
    }

    return $kurseByMonth;
  }

  private function removeUntilCurrentMonth($kurseByMonth)
  {
    $date = DateTimeObj::getNow();
    $keyToCompareTo = $date->getYear() . '_' . $date->getMonth();
    $keys = array_keys($kurseByMonth);
    foreach ($keys as $month) {
      if ($month < $keyToCompareTo) {
        unset($kurseByMonth[$month]);
      }
    }

    return $kurseByMonth;
  }

  private function removeByRange($kurseByMonth, $hardFromDate, $hardToDate)
  {
    $dateFrom = DateTimeObj::createFromString($hardFromDate);
    $keyToCompareTo = $dateFrom->getYear() . '_' . $dateFrom->getMonth();
    $keys = array_keys($kurseByMonth);
    foreach ($keys as $month) {
      if ($month < $keyToCompareTo) {
        unset($kurseByMonth[$month]);
      }
    }
    $dateTo = DateTimeObj::createFromString($hardToDate);
    $keyToCompareTo = $dateTo->getYear() . '_' . $dateTo->getMonth();
    $keys = array_keys($kurseByMonth);
    foreach ($keys as $month) {
      if ($month > $keyToCompareTo) {
        unset($kurseByMonth[$month]);
      }
    }

    return $kurseByMonth;
  }

  protected function fillKurseByMonth($kurseByMonth, $kurse)
  {
    foreach ($kurse as $kurs) {
      if (!key_exists($kurs['jahr'] . '_' . $kurs['monat'], $kurseByMonth)) {
        $kurseByMonth[$kurs['jahr'] . '_' . $kurs['monat']] = array(
          'monat' => $this->getNewMonat($kurs['jahr'], $kurs['monat']),
          'kurse' => array()
        );
      }
      $kurseByMonth[$kurs['jahr'] . '_' . $kurs['monat']]['kurse'][] = WBKursStore::getKurs($kurs['nr']);
    }

    return $kurseByMonth;
  }

  public function getNewMonat($pJahr, $pMonat)
  {
    $actMonth = new Monat();
    $actMonth->jahr = $pJahr;
    $actMonth->monat_id = $pMonat;
    $actMonth->monat_name = $this->addfdatetime->getNameofMonth($pMonat);
    $actMonth->monat_leiste = $pJahr . '_' . $pMonat;

    return $actMonth;
  }

  public function setDataForMonatsListe()
  {
    $data = array();
    foreach ($this->kurseSorted as $monat) {
      $monat['monat']->anzahl = count($monat['kurse']);
      $data[] = $monat['monat'];
    }

    $this->dataarraybody = $data;
  }

  public function _getClickPath($pName = 'Kalender Monatsübersicht')
  {
    
    return $pName;
  }

  protected function renderMonthList() : string
  {
    $expGruppiert = new ExpGruppiert();
    $this->exportadapter = $expGruppiert;
    $this->sight = SightsAPI::getSight(414);
    $this->setDataForMonatsListe();
    $result = $this->getheader();
    if (count($this->dataarraybody) > 0) {
      $result .= $this->getbody();
    } else {
      $result .= $this->getnodata();
    }
    $result .= $this->getfooter();

    return $result;
  }

  protected function renderAllKurse() : string
  {
    $result = '';
    
    $expKurse = new ExpKurse();
    $this->exportadapter = $expKurse;
    $expGruppiert = new ExpGruppiert();
    foreach ($this->kurseSorted as $monat) {
      $this->dataarrayheader = array($monat['monat']);
      $this->dataarraybody = $monat['kurse'];
      $this->dataarrayfooter = array($monat['monat']);
      $this->exportadapter = $expGruppiert;
      $result .= $this->getheader();
      if (count($this->dataarraybody) > 0) {
        $this->exportadapter = $expKurse;
        $result .= $this->getbody();
      } else {
        $result .= $this->getnodata();
      }
      $this->exportadapter = $expGruppiert;
      $result .= $this->getfooter();
    }

    return $result;
  }
}