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

namespace Kufer\Web\KuferTools\Dozent\Anwesenheiten\NotenSpeichern;

class NotenSpeichernUseCase extends \Kufer\Web\KuferTools\Basis\UseCase\ToolUseCase
{
  public const UEBERTRAGUNG_SUCCESS = 1;
  public const SPEICHERN_SUCCESS = 2;
  public const SUBMIT_FAILED = 3;
  public const DOPPELT_AUFGERUFEN = 4;

  private $dbwTnNoten;

  public function __construct($request)
  {
    parent::__construct($request, new NotenSpeichernResponse());
    $this->dbwTnNoten = new \DBWorkTNNoten();
  }

  public static function getToolId()
  {
    return 18;
  }

  public static function getToolSectionId()
  {
    return 288;
  }

  public function hasAccess($pToolSectionId = null)
  {
    if (!parent::hasAccess()) {
      return false;
    }
    if (!$this->request->isXsrfOk && !$this->request->isRefresh) {
      return false;
    }
    if (!$this->isRechtAllowed('273.0.4')) {
      return false;
    }

    return true;
  }

  private function getKurs($knr)
  {
    $dbwKurse = new \DBWorkKurseWT(1, true);

    return $dbwKurse->getKurs($knr);
  }

  public function action()
  {
    $kurs = $this->getKurs($this->request->knr);

    if ($this->request->isRefresh) {
      $status = self::DOPPELT_AUFGERUFEN;
    } else {
      $fachArry = $this->getFaecher($this->request->knr);
      $belegungen = $this->getBelegungen($kurs);
      $status = $this->setNoten($belegungen, $fachArry);
    }

    return $this->getResponse($kurs, $status);
  }

  private function setNoten($aryBelegung, $aryFach, $pruefId = 0)
  {
    $result = null;
    $dbwTNFach = new \DBWorkTNFach(1, true);
    $notenApi = new \NotenAPI();
    $notenAry = array();
    try {
      $niveauBelAry = array();
      $nichtbenotetAry = array();
      $notenendeIDsAry = array();
      foreach ($aryBelegung as $teilnehmer) {
        if(empty($teilnehmer->id)) { 
          continue;
        }

        $notenendeIDsAry[] = $teilnehmer->id;
        
        
        if ($teilnehmer->notenende == 'W') {
          continue;
        }
        
        foreach ($aryFach as $fach) {
          $tnFach = $dbwTNFach->getTNFachByIDs($teilnehmer->id, $fach->id);
          
          if (!empty($tnFach) && !empty($tnFach->id)) {
            
            
            $return = $this->generateNote($teilnehmer->id, $tnFach, $fach, $pruefId);
            if (!empty($return)) {
              
              $notenAry[] = $return;
            }
            $nichtbenotet = $this->setNichtBenotet($tnFach);
            if (!empty($nichtbenotet)) {
              $nichtbenotetAry[] = $nichtbenotet;
            }
          }
        }
        
        $niveau = $this->getNiveau($teilnehmer);
        if (!empty($niveau)) {
          $niveauBelAry[] = $niveau;
        }
      }
      if ($this->request->einreichenPressed == 1) {
        if (\SessionOperations::isDmzBetrieb()) {
          
          $notenApi->sendDataToDmz($notenAry, $notenendeIDsAry, $niveauBelAry, $nichtbenotetAry);
          
          
          $notenApi->updateNotenInDB($notenAry, true);
          
          $notenApi->updateBelegungInDB($niveauBelAry, true);
          
          $notenApi->updateTnFachInDB($nichtbenotetAry, true);
          
          $notenApi->setNotenEnde($aryBelegung, true);
        } else {
          $notenApi->updateNotenInDB($notenAry, false);
          
          $notenApi->updateBelegungInDB($niveauBelAry, false);
          
          $notenApi->updateTnFachInDB($nichtbenotetAry, false);
          
          $notenApi->setNotenEnde($aryBelegung, false);
        }
        $result = self::UEBERTRAGUNG_SUCCESS;
      } else {
        if (!empty($notenAry) || !empty($niveauBelAry) || !empty($nichtbenotetAry)) {
          if (\SessionOperations::isDmzBetrieb()) {
            
            $notenApi->sendDataToDmz($notenAry, array(), $niveauBelAry, $nichtbenotetAry);
            
            $notenApi->updateNotenInDB($notenAry, true);
            
            $notenApi->updateBelegungInDB($niveauBelAry, true);
            
            $notenApi->updateTnFachInDB($nichtbenotetAry, true);
          } else {
            
            $notenApi->updateNotenInDB($notenAry, false);
            
            $notenApi->updateBelegungInDB($niveauBelAry, false);
            
            $notenApi->updateTnFachInDB($nichtbenotetAry, false);
          }
          $result = self::SPEICHERN_SUCCESS;
        }
      }
    } catch (\AbgleichApiException $e) {
      
      $notenApi->revertNotenInDB($notenAry);
      \Logger::logg('Noten eintragen - folgende Exception ist aufgetreten: ' . $e->getMessage() . ' [' . $e->getTraceAsString() . ']', 200);
      $result = self::SUBMIT_FAILED;
    }

    return $result;
  }

  private function getNiveau($pBelegung)
  {
    $niveau = trim(\PostOperations::getVarValue('niveau_' . $pBelegung->id, ''));
    if (trim($pBelegung->niveau) != $niveau) {
      $pBelegung->niveau = $niveau;

      return $pBelegung;
    } else {
      return null;
    }
  }

  
  private function generateNote($belId, $tnFach, $kursFach, $pruefID = 0)
  {
    $id = trim(\PostOperations::getVarValue('tnnotenid_' . $belId . '_' . $tnFach->id . '_' . $pruefID, ''));
    $pruefung = trim(\PostOperations::getVarValue('typ_' . $belId . '_' . $tnFach->id . '_' . $pruefID, ''));
    $note = trim(\PostOperations::getVarValue('note_' . $belId . '_' . $tnFach->id . '_' . $pruefID, ''));
    $bemerkung = trim(\PostOperations::getVarValue('bemerkung_' . $belId . '_' . $tnFach->id . '_' . $pruefID, ''));
    $datum = trim(\PostOperations::getVarValue('datum_' . $belId . '_' . $tnFach->id . '_' . $pruefID, ''));


    
    $altNotenAry = $this->dbwTnNoten->getTNNotenByBelFachPruefIDs($belId, $tnFach->id, $pruefID);


    if (empty($id) && sizeof($altNotenAry) > 0 && $this->toolSettings->vereinfachteNotenEingabe) {
      throw new \AbgleichApiException("Konflikt: Doppelte Note für BelegID $belId FachID, $tnFach->id PruefID, $pruefID");
    }

    
    if (empty($id)) {
      
      if ($note == '') {
        return null;
      }

      
      $tnnote = new \TNNoten();
      $tnnote->beleg_id = $belId;
      $tnnote->fach_id = $tnFach->id;
      $tnnote->pruef_id = $pruefID;
      $tnnote->gewichtung = 1;
      $tnnote->erfasstam = \DateTimeOperations::getDateTimeNow();
      $tnnote->bearbdatum = \DateTimeOperations::getDateTimeNow();
      $tnnote->typ = '';
      $tnnote->knr = '';

      $tnnote->pruefung = $pruefung;
      if ($this->doesFachUseIndividualNotenCached($kursFach)) {
        $tnnote->indnote = $note;
      } else {
        $tnnote->note = $note;
      }
      $tnnote->bemerkung = $bemerkung;

      if (empty($datum)) {
        $tnnote->datum = \DateTimeOperations::getDateTimeNow();
      } else {
        $tnnote->datum = $datum;
      }

      
      
      if (\SessionOperations::isReplikat() && \AllgSettingsAPI::getAllgSettings()->dmzEnabled) {
        $this->dbwTnNoten->insertNote($tnnote, true);
        $tnnote->replikatgeneriert = true;
      } else {
        $this->dbwTnNoten->insertNote($tnnote, false);
      }

      
      return new \Tupel($tnnote, true);
    
    } else {
      $tnnote = $this->dbwTnNoten->getTNNoteByID($id);
      $saveMe = false;
      if (trim($tnnote->pruefung) != $pruefung) {
        $saveMe = true;
        $tnnote->pruefung = $pruefung;
      }

      if ($this->doesFachUseIndividualNotenCached($kursFach)) {
        if ($tnnote->indnote != $note) {
          $saveMe = true;
          $tnnote->indnote = $note;
        }
      } else {
        if (\MathOperations::stringToFloat(trim($tnnote->note)) != \MathOperations::stringToFloat($note)) {
          if (($this->toolSettings->vereinfachteNotenEingabe) && ($note === '') && ($tnnote->note === '0')) {
            
          } else {
            $saveMe = true;
            $tnnote->note = $note;
          }
        }
      }
      if (trim($tnnote->bemerkung) != $bemerkung) {
        $saveMe = true;
        $tnnote->bemerkung = $bemerkung;
      }

      if (!empty($datum) && trim($tnnote->datum) != $datum) {
        $saveMe = true;
        $tnnote->datum = $datum;
      }
      if ($saveMe) {
        $tnnote->bearbdatum = \DateTimeOperations::getDateTimeNow();
        

        
        return new \Tupel($tnnote, false);
      } else {
        
        return null;
      }
    }
  }

  private function setNichtBenotet($tnFach, $pruefID = 0)
  {
    $nichtben = \PostOperations::getVarValue('nichtben_' . $tnFach->beleg_id . '_' . $tnFach->id . '_' . $pruefID, '') == 'nichtben';
    if ($nichtben !== $tnFach->nichtbeurteilt) {
      $tnFach->nichtbeurteilt = $nichtben;

      return $tnFach;
    } else {
      return null;
    }
  }

  private function getFaecher($pKnr)
  {
    $dbwFack = new \DBWorkKursFach(1, true);

    return $dbwFack->getFaecherByKurs($pKnr);
  }

  private function getBelegungen(\Kurs $kurs)
  {
    $dbwBeleg = new \DBWorkBelegung(1, true);
    $dbwBeleg->newSearch();

    if (!\DateTimeOperations::isEmptyOrDefault($kurs->beginn_dat)) {
      $restrictStatusByDate = \Kufer\Web\Classes\db\searchobject\BelegungToObjectStatusByDate::createFromSettings(
        \ToolSettingsAPI::getToolSettings(0),
        $kurs->beginn_dat
      );
      $dbwBeleg->toobject->restrictStatusByDate = $restrictStatusByDate;
    }

    return $dbwBeleg->getBelegungenbyKursNR($kurs->id);
  }

  private function doesFachUseIndividualNoten($kursFach)
  {
    $hlFach = $this->getHlFach();
    foreach ($hlFach as $fach) {
      if ($kursFach->fach_nr == $fach->id) {
        return $fach->individualnoten;
      }
    }

    return false;
  }

  private function doesFachUseIndividualNotenCached($kursFach)
  {
    static $indNoten = array();
    if (!isset($indNoten[$kursFach->fach_nr])) {
      $indNoten[$kursFach->fach_nr] = $this->doesFachUseIndividualNoten($kursFach);
    }

    return $indNoten[$kursFach->fach_nr];
  }

  private function getHlFach()
  {
    $dbwHLFach = new \DBWorkHLFach(1, true);
    static $hlfach = null;
    if (is_null($hlfach)) {
      $hlfach = $dbwHLFach->getAll();
    }

    return $hlfach;
  }

  protected function getResponse($pKurs, $pStatusCode)
  {
    $this->handleResponseStrategies();
    $this->response->knr = $pKurs->id;
    $this->response->status = $pStatusCode;
    $this->response->datum = $this->request->datum;

    return $this->response;
  }

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

class NotenSpeichernRequest
{
  public $knr;
  public $einreichenPressed;
  public $datum;
  public $isRefresh;
  public $isXsrfOk;
}

class NotenSpeichernResponse extends \Kufer\Web\KuferTools\Basis\UseCase\ToolResponse
{
  public $user;
  public $status;
  public $knr;
  public $datum;
}