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

namespace Kufer\KuferTools\Firma\MitarbeiterUebersicht\MitarbeiterNoten;

use Kufer\Web\Classes\Addfunctions\Guid;
use Kufer\Web\Classes\Identifier\Identifier;

class MitarbeiterNotenUseCase extends \Kufer\KuferTools\Basis\UseCase\ToolUseCase
{
  public function __construct($request)
  {
    parent::__construct($request, new MitarbeiterNotenResponse());
  }

  public static function getToolId()
  {
    return \ToolsAPI::TOOL_MITARBEITERUEBERSICHT_FA; 
  }

  public static function getToolSectionId()
  {
    return 481;
  }

  public function action()
  {
    
    
    $belegungTeilnehmerObjekt = $this->getBelegungsInfoArray($this->request->tnr, $this->request->tguid);

    
    
    return $this->getResponse($belegungTeilnehmerObjekt);
  }

  
  private function getBelegungsInfoArray($pTnr, $pTguid)
  {
    $tnId = new Identifier($pTnr, empty($pTguid) ? null : new Guid($pTguid));
    $tnStatus = $this->toolSettings->tnstatus;
    if ($this->toolSettings->tnstatus == '') {
      $tnStatus = 'ATP';
    }
    $tnStatus = \StringOperations::convertArray2InList(\StringOperations::str_split($tnStatus));
    if (\StringOperations::strstr($tnStatus, 'A') !== false) {
      $tnStatus .= ",'',' '";
    }
    $belegungshelper = new \Kufer\KuferTools\Utils\DatamodulHelper\BelegungsHelper\FirmaMitarbeiterNotenBelegungen($this->toolSettings, $tnId, $tnStatus);
    $belegungenDesMitarbeiters = $belegungshelper->getDatamoduleOhneFilter();
    $belegungIds = \ArrayOperations::mapAttribut($belegungenDesMitarbeiters, 'id');
    $kursnummern = $this->getKursnummernFromBelegungen($belegungenDesMitarbeiters);
    $dbwTnFach = new \DBWorkTNFach(1, true);
    $dbwTnNoten = new \DBWorkTNNoten(1, true);
    $dbwKursFach = new \DBWorkKursFach(1, true);

    $tempData = new \stdClass();
    $tempData->belegungen = $belegungenDesMitarbeiters;
    $tempData->tnFaecher = $dbwTnFach->getTNFachByBelIds($belegungIds);
    $tempData->tnNoten = $dbwTnNoten->getTNNotenByBelIds($belegungIds);
    $tempData->kursFach = $dbwKursFach->getFaecherByKursnummern($kursnummern);

    
    
    if (count($belegungenDesMitarbeiters) > 0) {
      $tempData->teilnehmer = $belegungenDesMitarbeiters[0]->teilnehmer;
    } else { 
      $dbwTeilnehmer = new \DBWorkTeilnehmer(1, true);
      $tempData->teilnehmer = $dbwTeilnehmer->getTeilnehm($tnId);
    }
    $tempData->ohneNotenloseFaecher = $this->toolSettings->notenOhneNotenloseFaecher;
    $tempData->ohneFaecherloseBelegungen = $this->toolSettings->notenOhneFaecherloseBelegungen;
    $tempData->tnFaecherJeBelegung = $this->gruppiereTnFaecherNachBelegId($tempData->tnFaecher);
    $tempData->tnNotenJeBelegungUndTnFach = $this->gruppiereTnNotenNachBelegIdUndFach($tempData->tnNoten);

    
    
    $tempBelTeilnObj = new \stdClass();
    $tempBelTeilnObj->belegAry = $this->getBelegInfoAry($tempData->belegungen, $tempData);
    
    $tempBelTeilnObj->teilnehmer = $tempData->teilnehmer;

    return $tempBelTeilnObj;
  }

  
  private function getKursnummernFromBelegungen($pBelegungen)
  {
    return array_map(function($pBelegung) {
      return $pBelegung->kurs->id;
    }, $pBelegungen);
  }

  private function formatNote($noteFloat)
  {
    return \MathOperations::floatToStringTruncateNull(round($noteFloat, 2));
  }

  
  private function berechneNoten($tnNoten)
  {
    $anzahl = 0;
    $notenSumme = 0.00;
    $gewichtungSumme = 0;
    foreach ($tnNoten as $tnNote) {
      $note = \MathOperations::stringToFloat($tnNote->note);
      $gewichtung = \MathOperations::stringToFloat($tnNote->gewichtung);
      if ($note > 0) {
        $anzahl++;
        $notenSumme += $note * $gewichtung;
        $gewichtungSumme += $gewichtung;
      }
    }

    if (!$notenSumme == 0 && !$gewichtungSumme == 0) {
      $durchschnitt = $notenSumme / $gewichtungSumme;
    } else {
      $durchschnitt = 0;
    }

    return array('durchschnitt' => $this->formatNote($durchschnitt), 'anzahl' => $anzahl);
  }

  private function getNotenEinerBelegung($belegung, $tempData)
  {
    if (isset($tempData->tnNotenJeBelegungUndTnFach[$belegung->id])) {
      return array_reduce($tempData->tnNotenJeBelegungUndTnFach[$belegung->id], function($result, $noten) {
        return array_merge($result, $noten);
      }, array());
    } else {
      return array();
    }
  }

  private function berechneNoten4TnFach($tnFach, $tempData)
  {
    if (isset($tempData->tnNotenJeBelegungUndTnFach[$tnFach->beleg_id][$tnFach->id])) {
      $notenAry = $tempData->tnNotenJeBelegungUndTnFach[$tnFach->beleg_id][$tnFach->id];
    } else {
      $notenAry = array();
    }

    return $this->berechneNoten($notenAry);
  }

  private function sollFachHinzugefuegtWerden($pFachInfo, $tempData)
  {
    if ($tempData->ohneNotenloseFaecher && count($pFachInfo['noten']) == 0) {
      return false;
    } else {
      return true;
    }
  }

  private function sollBelegungHinzugefuegtWerden($pBelegungInfo, $tempData)
  {
    if ($tempData->ohneFaecherloseBelegungen && count($pBelegungInfo['faecher']) == 0) {
      return false;
    } else {
      return true;
    }
  }

  private function getFachInfoAry($belegung, $tempData)
  {
    $faecherInfo = array();
    if (isset($tempData->tnFaecherJeBelegung[$belegung->id])) {
      foreach ($tempData->tnFaecherJeBelegung[$belegung->id] as $tnFach) {
        $fachinfo = $this->getFachInfo($tnFach, $tempData);
        if ($this->sollFachHinzugefuegtWerden($fachinfo, $tempData)) {
          $faecherInfo[] = $fachinfo;
        }
      }
    }

    return $faecherInfo;
  }

  private function getNotenInfo($tnNoten)
  {
    return array('tnNote' => $tnNoten);
  }

  private function getNotenInfoZuFach($tnFach, $tempData)
  {
    $notenInfo = array();
    if (isset($tempData->tnNotenJeBelegungUndTnFach[$tnFach->beleg_id][$tnFach->id])) {
      foreach ($tempData->tnNotenJeBelegungUndTnFach[$tnFach->beleg_id][$tnFach->id] as $tnNote) {
        $notenInfo[] = $this->getNotenInfo($tnNote);
      }
    }

    return $notenInfo;
  }

  private function getKursFachById($fachId, $tempData)
  {
    foreach ($tempData->kursFach as $fach) {
      if ($fach->id == $fachId) {
        return $fach;
      }
    }

    return new \KursFach();
  }

  private function getFachInfo($tnFach, $tempData)
  {
    $notenInfo = $this->berechneNoten4TnFach($tnFach, $tempData);
    $fach = $this->getKursFachById($tnFach->fach_id, $tempData);

    return array('tnFach' => $tnFach,
                 'name' => $fach->fach,
                 'notenAnzahl' => $notenInfo['anzahl'],
                 'notenDurchschnitt' => $notenInfo['durchschnitt'],
                 'isPflichtfach' => $tnFach->artwp == 0,
                 'noten' => $this->getNotenInfoZuFach($tnFach, $tempData));
  }

  private function getBelegInfo($belegung, $tempData)
  {
    $noten = $this->getNotenEinerBelegung($belegung, $tempData);
    $notenInfo = $this->berechneNoten($noten);

    return array('belegung' => $belegung,
                 'notenAnzahl' => $notenInfo['anzahl'],
                 'notenDurchschnitt' => $notenInfo['durchschnitt'],
                 'faecher' => $this->getFachInfoAry($belegung, $tempData));
  }

  protected function getBelegInfoAry($belegungen, $tempData)
  {
    $belegungenInfo = array();
    foreach ($belegungen as $belegung) {
      $belegungInfo = $this->getBelegInfo($belegung, $tempData);
      if ($this->sollBelegungHinzugefuegtWerden($belegungInfo, $tempData)) {
        $belegungenInfo[] = $belegungInfo;
      }
    }

    return $belegungenInfo;
  }

  
  private function gruppiereTnNotenNachBelegIdUndFach($pTnNoten)
  {
    return array_reduce($pTnNoten, function($pResult, $tnNote) {
      if (!isset($pResult[$tnNote->beleg_id])) {
        $pResult[$tnNote->beleg_id] = array();
      }
      if (!isset($pResult[$tnNote->beleg_id][$tnNote->fach_id])) {
        $pResult[$tnNote->beleg_id][$tnNote->fach_id] = array();
      }
      $pResult[$tnNote->beleg_id][$tnNote->fach_id][] = $tnNote;

      return $pResult;
    }, array());
  }

  
  private function gruppiereTnFaecherNachBelegId($pTnFaecher)
  {
    return array_reduce($pTnFaecher, function($pResult, $tnFach) {
      if (!isset($pResult[$tnFach->beleg_id])) {
        $pResult[$tnFach->beleg_id] = array();
      }
      $pResult[$tnFach->beleg_id][] = $tnFach;

      return $pResult;
    }, array());
  }

  protected function getButtons()
  {
    $buttons = array();
    
    
    if (count($this->response->belegungsInfo) > 0) {
      if (!$this->toolSettings->notenOhneEinzelnoten) {
        $buttons[] = array(new \Kufer\KuferTools\Basis\Button\HtmlButton(
          'Einzelnoten anzeigen',
          'notenuebersicht_button_alles_aufklappen',
          '',
          '',
          'Einzelnoten und Fächer anzeigen',
          '',
          'default'
        ));
      }

      $buttons[] = array(new \Kufer\KuferTools\Basis\Button\HtmlButton(
        'Fächer anzeigen',
        'notenuebersicht_button_fach_aufklappen',
        '',
        '',
        'Fächer ohne Einzelnoten anzeigen',
        '',
        'default'
      ));
      $buttons[] = array(new \Kufer\KuferTools\Basis\Button\HtmlButton(
        'Kurse anzeigen',
        'notenuebersicht_button_alles_zuklappen',
        '',
        '',
        'Teilnehmer ohne Fächer und Einzelnoten anzeigen',
        '',
        'default'
      ));
    } 

    $buttons[] = array(new \Kufer\KuferTools\Basis\Button\HtmlButton(
      'Zurück zur Übersicht',
      '',
      'index.php?tool_id=22',
      'reply',
      'Zurück zur Übersicht'
    ));

    return $buttons;
  }

  protected function getResponse($pBelegungTeilnehmerObjekt)
  {
    $this->response->belegungsInfo = $pBelegungTeilnehmerObjekt->belegAry;
    $this->response->teilnehmer = $pBelegungTeilnehmerObjekt->teilnehmer;

    $this->handleResponseStrategies();
    $this->response->buttons = $this->getButtons();
    $this->response->notenOhneEinzelnoten = $this->toolSettings->notenOhneEinzelnoten;

    return $this->response;
  }

  protected function getResponseStrategies()
  {
    return array(
        new \Kufer\KuferTools\Utils\ResponseStrategies\ResponseMitRahmen($this)
    );
  }
}

class MitarbeiterNotenRequest extends \Kufer\KuferTools\Basis\Uebersicht\UebersichtMitWssRequest
{
  public $tnr;
  public $tguid;
}

class MitarbeiterNotenResponse extends \Kufer\KuferTools\Basis\Uebersicht\UebersichtMitWssResponse
{
  public $belegungsInfo = array();
  public $buttons;
  
  
  public $teilnehmer;
}