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

namespace Kufer\KuferTools\Veranstalter\KursUebersicht\Detailsreiter\Teilnehmer\HandleBelegungBearbeiten;

use Kufer\Web\Classes\Api\Belegung\OldBelegungStatusAenderungHandler;

class HandleBelegungBearbeitenUseCase extends \Kufer\KuferTools\Basis\UseCase\ToolUseCase
{
  public const BELEGUNG_BEARBEITEN_KEINE_AENDERUNG = 'belegungBearbeitenKeineAenderung';
  public const BELEGUNG_BEARBEITEN_FEHLER = 'belegungBearbeitenFehler';
  public const BELEGUNG_BEARBEITEN_TECHNISCHER_FEHLER = 'belegungBearbeitenTechnischerFehler';
  public const BELEGUNG_BEARBEITEN_ERFOLGREICH = 'belegungBearbeitenErfolgreich';

  public $dbwBelegung;

  public function __construct($request)
  {
    parent::__construct($request, new HandleBelegungBearbeitenResponse());
    $this->dbwBelegung = new \DBWorkBelegung(1, true);
  }

  public static function getToolSectionId()
  {
    return 618;
  }

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

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

    return true;
  }

  public function action()
  {
    $result = $this->handleBelegungBearbeiten($this->request->belid);

    $statusCodes = $result['statusCode'];
    $belegung = $result['belegung'];

    $statusMessages = $this->getStatusMessages($statusCodes, $belegung);

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

  
  private function handleBelegungBearbeiten($belid)
  {
    $origBelegung = $this->dbwBelegung->getBelegung($belid);
    $changedBelegung = $this->request->wssHandler->getChangedDm($origBelegung, $this->request->columnValues);
    $changedFields = $this->request->wssHandler->getChangedFieldnames($origBelegung, $this->request->columnValues);
    $wrongFields = $this->request->wssHandler->checkColumnValues($this->request->columnValues);

    if (count($wrongFields) > 0) {
      return array('statusCode' => array(self::BELEGUNG_BEARBEITEN_TECHNISCHER_FEHLER), 'belegung' => $changedBelegung);
    }

    $statusCodes = array();

    $statusNeu = $changedBelegung->status;
    
    $changedBelegung->status = $origBelegung->status;

    
    if (count($changedFields) !== 1 || !in_array('status', $changedFields)) {
      $changedFieldsOhneStatus = array_diff($changedFields, array('status'));
      $statusCodes[] = $this->saveBelegung($origBelegung, $changedBelegung, $changedFieldsOhneStatus);
      unset($changedFieldsOhneStatus);
    }

    unset($changedFields, $origBelegung);

    if (!\APIGebuehren::hasKursFortlaufendeGebuehren($changedBelegung->knr)) {
      $oldStatusHandler = new OldBelegungStatusAenderungHandler(
        $this->toolSettings,
        $this->toolSettings->vhsEmailTool8Section242,
        $this->request->anmeldedatumNeuSetzen,
        $this->request->stornogrund,
        $this->request->austritt,
        array($this, 'sendBelegungStatusAendernMail')
      );
      $statusCodes[] = \BelegungAPI::handleStatusAenderung($changedBelegung, $statusNeu, $oldStatusHandler);
    }

    if (empty($statusCodes)) {
      $statusCodes[] = self::BELEGUNG_BEARBEITEN_KEINE_AENDERUNG;
    }

    return array('statusCode' => $statusCodes, 'belegung' => $changedBelegung);
  }

  
  private function saveBelegung($origBelegung, $changedBelegung, $changedFields)
  {
    if (count($changedFields) === 0) {
      return self::BELEGUNG_BEARBEITEN_KEINE_AENDERUNG;
    }

    $success = \BelegungAPI::updateBelegung($changedBelegung, $origBelegung);
    if ($success) {
      $statusCode = self::BELEGUNG_BEARBEITEN_ERFOLGREICH;
    } else {
      $statusCode = self::BELEGUNG_BEARBEITEN_FEHLER;
    }

    return $statusCode;
  }

  
  private function getStatusMessages($pStatusCodes, $pBelegung)
  {
    $result = $this->getStatusMessagesSuccess($pStatusCodes, $pBelegung);
    $result .= $this->getStatusMessagesError($pStatusCodes);
    $result .= $this->getStatusMessagesInfo($pStatusCodes, $pBelegung);

    return $result;
  }

  private function getStatusMessagesSuccess($pStatusCodes, $pBelegung)
  {
    $result = '';
    $allgsettings = \AllgSettingsAPI::getAllgSettings();
    $namevorname = \CleanOperations::cleanStringForHtml($pBelegung->teilnehmer->getVarValue('name_vorname_ohne_komma'));

    if (in_array(self::BELEGUNG_BEARBEITEN_ERFOLGREICH, $pStatusCodes)) {
      $result .= '<div>' . \CleanOperations::cleanStringForHtml($allgsettings->successMsgChangeBelegung) . '</div>';
    }

    if (in_array(\BelegungAPI::STATUS_AENDERUNG_ANMELDUNG_ERFOLGREICH, $pStatusCodes)) {
      $result .= '<div>Der/Die TeilnehmerIn ' . $namevorname . ' wurde erfolgreich angemeldet.</div>';
    }
    if (in_array(\BelegungAPI::STATUS_AENDERUNG_EINFACH_ERFOLGREICH, $pStatusCodes)) {
      $result .= '<div>Der Status des Teilnehmers/der Teilnehmerin ' . $namevorname . ' wurde erfolgreich geändert.</div>';
    }
    if (in_array(\BelegungAPI::STATUS_AENDERUNG_STORNO_ERFOLGREICH, $pStatusCodes)) {
      $result .= '<div>Der/Die TeilnehmerIn ' . $namevorname . ' wurde erfolgreich storniert.</div>';
    }

    if ($result !== '') {
      $result = '<div class="alert alert-success">' . $result . '</div>';
    }

    return $result;
  }

  private function getStatusMessagesError($pStatusCodes)
  {
    $result = '';
    $allgsettings = \AllgSettingsAPI::getAllgSettings();

    if (in_array(self::BELEGUNG_BEARBEITEN_FEHLER, $pStatusCodes)) {
      $result .= '<div>' . \CleanOperations::cleanStringForHtml($allgsettings->failSubmitMsgBelegung) . '</div>';
    } elseif (in_array(self::BELEGUNG_BEARBEITEN_TECHNISCHER_FEHLER, $pStatusCodes)) {
      $result .= '<div>Die Belegung konnte aus technischen Gründen nicht geändert werden.</div>';
    }

    if (in_array(\BelegungAPI::STATUS_AENDERUNG_ANMELDUNG_FEHLER, $pStatusCodes)) {
      $result .= '<div>Es wurde keine Anmeldung durchgeführt, da ein Fehler aufgetreten ist. Bitte versuchen Sie es erneut, oder wenden Sie sich an die Einrichtung.</div>';
    }
    if (in_array(\BelegungAPI::STATUS_AENDERUNG_EINFACH_FEHLER, $pStatusCodes)) {
      $result .= '<div>Es wurde keine Statusänderung durchgeführt, da ein Fehler aufgetreten ist. Bitte versuchen Sie es erneut, oder wenden Sie sich an die Einrichtung.</div>';
    }
    if (in_array(\BelegungAPI::STATUS_AENDERUNG_STORNO_FEHLER, $pStatusCodes)) {
      $result .= '<div>Es wurde keine Stornierung durchgeführt, da ein Fehler aufgetreten ist. Bitte versuchen Sie es erneut, oder wenden Sie sich an die Einrichtung.</div>';
    }
    if (in_array(\BelegungAPI::STATUS_AENDERUNG_BELEGUNGSDATEN_NICHT_AKTUELL, $pStatusCodes)) {
      $result .= '<div>Die Daten im Web sind nicht mehr aktuell und können daher nicht bearbeitet werden. Bitte warten Sie die nächste Aktualisierung ab, oder teilen Sie Ihre Änderung einem Mitarbeiter mit Zugang zu KuferSQL mit.</div>';
    }
    if (in_array(\BelegungAPI::STATUS_AENDERUNG_PER_MAIL_FEHLER, $pStatusCodes)) {
      $result .= '<div>Fehler beim Versand der E-Mail mit der Anfrage zur Statusänderung an die Einrichtung. Bitte versuchen Sie es erneut, oder wenden Sie sich an die Einrichtung.</div>';
    }

    if ($result !== '') {
      $result = '<div class="alert alert-danger">' . $result . '</div>';
    }

    return $result;
  }

  private function getStatusMessagesInfo($pStatusCodes, $pBelegung)
  {
    $result = '';
    $allgsettings = \AllgSettingsAPI::getAllgSettings();

    if (in_array(self::BELEGUNG_BEARBEITEN_KEINE_AENDERUNG, $pStatusCodes)) {
      $result .= '<div>' . \CleanOperations::cleanStringForHtml($allgsettings->failNoChangesMsgBelegung) . '</div>';
    }

    if ($result !== '') {
      $result = '<div class="alert alert-info">' . $result . '</div>';
    }

    if (in_array(\BelegungAPI::STATUS_AENDERUNG_PER_MAIL_VERSENDET, $pStatusCodes)) {
      
      $teilnehmerListe = '<div>' . \CleanOperations::cleanStringForHtml($pBelegung->teilnehmer->namevorname) . '</div>';
      $hinderungsGruendeAry = $this->getHinderungsGruende4StatusAenderungOhneStorno($pBelegung);
      if (count($hinderungsGruendeAry) > 0) {
        $teilnehmerListe .= '<ul>';
        foreach ($hinderungsGruendeAry as $grund) {
          $teilnehmerListe .= '<li> - ' . \CleanOperations::cleanStringForHtml($this->getText4HinderungsKonstanten($grund)) . '</li>';
        }
        $teilnehmerListe .= '</ul>';
      }

      $meldung = 'Für folgende Teilnehmer wurde eine E-Mail mit der Anfrage zur Statusänderung an die Einrichtung versendet:';
      $result .= \HTMLOperations::getInfoBox('<div class="infobox_text"><div>' . $meldung . '</div>'
                                       . BR_WT . $teilnehmerListe . '</div>', 'Statusänderung per E-Mail versendet', 'alert alert-info');
    }

    return $result;
  }

  
  public function sendBelegungStatusAendernMail($pBelegung, $pHinderungsGruende, $pStatus)
  {
    $pStornogrund = $this->request->stornogrund;
    $pAustritt = $this->request->austritt;
    $pAnmeldedatumNeuSetzen = $this->request->anmeldedatumNeuSetzen;

    $person = \SessionOperations::getCurrentWebToolsPerson();

    $betreff = 'Statusänderung von ' . $pBelegung->teilnehmer->namevorname . ' in ' . $this->response->sprachSettings->Kurs['Singular_mit_Artikel']['Dativ'] . ' ' . $pBelegung->knr . ' (' . $pBelegung->kurs->getVarValue('kurzbez_titel') . ')';

    $body = 'Veranstalter ' . $person->name . ' ' . $person->vorname . ' möchte den Status ' . $this->response->sprachSettings->Teilnehmer['Singular_mit_Artikel']['Genitiv']
            . ' ' . $pBelegung->teilnehmer->getVarValue('name_vorname_ohne_komma') . ' in ' . $this->response->sprachSettings->Kurs['Singular_mit_Artikel']['Dativ'] . ' "'
            . $pBelegung->kurs->getVarValue('kurzbez_titel') . '" (Kurs-Nr. ' . $pBelegung->knr . ') ändern.';
    $body = \CleanOperations::cleanStringForHtml($body) . '<br><br>';

    $austrittDatum = '';
    if (isset($pAustritt)) {
      $austrittDatum = $pAustritt !== '' ? $pAustritt : \DateTimeOperations::getDateNow();
    }

    if ($pStornogrund != '') {
      $body .= 'Dabei wurde vom Veranstalter folgender Grund angegeben: ' . '<br>' . $pStornogrund . '<br><br>';
    }
    $body .= 'alter Status: ' . $pBelegung->status . '<br>';
    $body .= '<b>neuer Status</b>: ' . $pStatus . '<br>';
    $body .= $pAnmeldedatumNeuSetzen ? 'Das Anmeldedatum soll neu gesetzt werden.' . '<br><br>' : '<br>';
    $body .= $austrittDatum !== '' ? 'Austritt: ' . $austrittDatum . '<br><br>' : '<br>';
    $gruendeCount = count($pHinderungsGruende);
    if ($gruendeCount > 0) {
      $body .= ' Eine direkte Statusänderung konnte ';
      $body .= 'aus folgende' . ($gruendeCount == 1 ? 'm Grund' : 'n Gründen');
      $body .= ' nicht durchgeführt werden:' . '<br><br>';
      foreach ($pHinderungsGruende as $grund) {
        $body .= '- ' . $this->getText4HinderungsKonstanten($grund) . '<br>';
      }
    }
    $body .= '<br><br><i>Diese E-Mail wurde am ' . \DateTimeOperations::getDateNow() . ' um ' . \DateTimeOperations::getTimeNow() . ' aus den ' . KUFERTOOLS . ' versandt.</i>';

    $mail = new \Kufer\Mail\EMail\EMailHTML($betreff, $body);
    $mail->addKuferToolsFooter('Statusänderung eines Teilnehmers im Kurs', $this->getUser(), $pBelegung->kurs);

    $sender = \Kufer\Mail\Sender\EMailSenderFactory::createForToolsWithCustomAddress($this->toolSettings->vhsEmailTool8Section242);
    $result = $sender->sendFromToolsUserToEinrichtung($mail, $this->getUser());

    return $result->hasSentAnyMails();
  }

  
  private function getText4HinderungsKonstanten($pHinterungsGrund)
  {
    $text = '';
    switch ($pHinterungsGrund) {
      case \BelegungAPI::STATUS_AENDERUNG_HINDERUNG_TEIL_EINER_MEHRFACHANMLEDUNG:
        $text = $this->response->sprachSettings->Teilnehmer['Singular_mit_Artikel']['Nominativ'] . ' gehört zu einer Mehrfach- oder Firmenanmeldung';
        break;
      case \BelegungAPI::STATUS_AENDERUNG_HINDERUNG_TEIL_EINER_ELTERN_KIND_ANMELDUNG:
        $text = 'Zu dieser Anmeldung gehören Kinderanmeldungen';
        break;
    }

    return $text;
  }

  protected function getResponse($statusMessage)
  {
    $this->response->statusMessage = $statusMessage;

    return $this->response;
  }
}

class HandleBelegungBearbeitenRequest
{
  public $belid;
  public $stornogrund;
  public $austritt;
  public $anmeldedatumNeuSetzen;
  public $columnValues;
  public $wssHandler;
}

class HandleBelegungBearbeitenResponse extends \Kufer\KuferTools\Basis\UseCase\ToolResponse
{
  public $statusMessage;
}