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

namespace Kufer\Web\KuferTools\Basis\Kursdetails\Detailsreiter\Teilnehmer\HandleBelegungBearbeiten;

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

abstract class HandleBelegungBearbeitenUseCase extends \Kufer\Web\KuferTools\Basis\UseCase\EinzelKursUseCase
{
  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 function hasAccess($pToolsectionId = null)
  {
    if (!\CleanOperations::isInt($this->request->belid)) {
      return false;
    }

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

    if (!in_array($this->getKursId(), $this->getKursHelper()->getIdsOhneFilter())) {
      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 $belegung;

  protected function getBelegung(): \Belegung
  {
    if (is_null($this->belegung)) {
      $this->belegung = $this->dbwBelegung->getBelegung($this->request->belid);
    }

    return $this->belegung;
  }

  protected function getRequestedId()
  {
    return $this->request->belid;
  }

  protected function getKursId(): string
  {
    return $this->getBelegung()->knr;
  }

  protected function getAllowedIds()
  {
    return $this->getBelegungsHelper($this->getKurs($this->getKursId()))->getIdsOhneFilter();
  }

  protected function getBelegungsHelper(\Kurs $kurs): \Kufer\Web\KuferTools\Utils\DatamodulHelper\Belegungen\BelegungsHelper
  {
    return new \Kufer\Web\KuferTools\Utils\DatamodulHelper\Belegungen\ReiterTeilnehmerBelegungen(
      $this->toolSettings,
      $this->request,
      $kurs->id,
      \ToolSettingsAPI::getToolSettings(0)->allowKinder5InTeilnehmerReiter ?? false
    );
  }

  
  private function handleBelegungBearbeiten($belid)
  {
    $origBelegung = $this->getBelegung();
    $changedBelegung = $this->request->wssHandler->getChangedDm(
      $this->toolSettings,
      $origBelegung,
      $this->request->columnValues
    );
    $changedFields = $this->request->wssHandler->getChangedFieldnames(
      $this->toolSettings,
      $origBelegung,
      $this->request->columnValues
    );
    $wrongFields = $this->request->wssHandler->checkColumnValues($this->toolSettings, $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 role="status" 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 role="status" 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 role="status" 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 = \BelegungAPI::getHinderungsGruende4StatusAenderungOhneStorno($pBelegung);
      if (!empty($hinderungsGruendeAry)) {
        $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;
  }

  
  abstract public function sendBelegungStatusAendernMail($pBelegung, $pHinderungsGruende, $pStatus): bool;

  
  protected 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;
  }
}