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

namespace Kufer\Web\KuferTools\Basis\BenachrichtigungNachBearbeiten;

use Kufer\Web\Classes\Mail\Sender\Settings\RecipientEinrichtung\EMailEinrichtungRecipientToolsKursSettings;
use Kufer\Web\Classes\Mail\Sender\Settings\RecipientEinrichtung\IEMailEinrichtungRecipientSettings;
use Kufer\Web\KuferTools\Basis\UseCaseBuilder\SpecificToolSection;
use Kufer\Web\KuferTools\Basis\UseCaseBuilder\ToolSection;

class BenachrichtigungUtils
{
  
  public static function sendeBenachrichtigungEmailKursdaten(
    $pColumns,
    $pOrigKurs,
    $pChangedKurs,
    $pChangedFields,
    $pChangedFieldsLabels,
    $pFooterText,
    $pUser,
    \ToolSettings $toolSettings,
    $pToolId,
    $pToolSectionId
  ) {
    if (empty($pOrigKurs) || empty($pChangedKurs) || empty($pChangedFields)) {
      return;
    }

    $origKurse = array($pOrigKurs->id => $pOrigKurs);
    $resultAry = self::setChangedFieldValuesToDatamodule(
      new SpecificToolSection($pToolId, $pToolSectionId),
      $toolSettings,
      $pColumns,
      $origKurse,
      array($pChangedKurs),
      $pChangedFields,
      $pChangedFieldsLabels
    );

    if ($resultAry['nothingChanged']) {
      return;
    }

    $changedKurse = $resultAry['changedDatamodule'];
    $changedKurs = $changedKurse[0];

    $view = self::getBenachrichtigungKursdatenAenderungView($changedKurs);
    $subject = self::getEmailSubject($view);
    $body = self::getEmailBody($view);

    self::sendEmailToEinrichtung(
      $subject,
      $body,
      $pFooterText,
      $pUser,
      self::createEinrichtungRecipientsWithKurs($pOrigKurs, $pToolId)
    );
  }

  
  public static function sendeBenachrichtigungEmailTermindaten(
    $pColumns,
    $pKurs,
    $pOrigKurstage,
    $pChangedKurstage,
    $pChangedFields,
    $pChangedFieldsLabels,
    $pFooterText,
    $pUser,
    \ToolSettings $toolSettings,
    $pToolId,
    $pToolSectionId
  ) {
    if (empty($pOrigKurstage) || empty($pChangedKurstage) || empty($pChangedFields)) {
      return;
    }

    $origKurstage = \ArrayOperations::setAttributAsKey($pOrigKurstage, 'id');
    $resultAry = self::setChangedFieldValuesToDatamodule(
      new SpecificToolSection($pToolId, $pToolSectionId),
      $toolSettings,
      $pColumns,
      $origKurstage,
      $pChangedKurstage,
      $pChangedFields,
      $pChangedFieldsLabels
    );

    if ($resultAry['nothingChanged']) {
      return;
    }

    $changedKurstage = $resultAry['changedDatamodule'];
    $view = self::getBenachrichtigungTermindatenAenderungView($pKurs, $changedKurstage);
    $subject = self::getEmailSubject($view);
    $body = self::getEmailBody($view);

    self::sendEmailToEinrichtung(
      $subject,
      $body,
      $pFooterText,
      $pUser,
      self::createEinrichtungRecipientsWithKurs($pKurs, $pToolId, $pToolSectionId)
    );
  }

  
  public static function sendeBenachrichtigungEmailBelegungsdaten(
    $pColumns,
    $pKurs,
    $pOrigBelegung,
    $pChangedBelegung,
    $pChangedFields,
    $pChangedFieldsLabels,
    $pFooterText,
    $pUser,
    \ToolSettings $toolSettings,
    $pToolId,
    $pToolSectionId
  ) {
    if (empty($pOrigBelegung) || empty($pChangedBelegung) || empty($pChangedFields)) {
      return;
    }

    $origBelegungen = array($pOrigBelegung->id => $pOrigBelegung);
    $resultAry = self::setChangedFieldValuesToDatamodule(
      new SpecificToolSection($pToolId, $pToolSectionId),
      $toolSettings,
      $pColumns,
      $origBelegungen,
      array($pChangedBelegung),
      $pChangedFields,
      $pChangedFieldsLabels
    );

    if ($resultAry['nothingChanged']) {
      return;
    }

    $changedBelegungen = $resultAry['changedDatamodule'];
    $changedBelegung = $changedBelegungen[0];

    $view = self::getBenachrichtigungBelegungsdatenAenderungView($changedBelegung);
    $subject = self::getEmailSubject($view);
    $body = self::getEmailBody($view);

    self::sendEmailToEinrichtung(
      $subject,
      $body,
      $pFooterText,
      $pUser,
      self::createEinrichtungRecipientsWithKurs($pKurs, $pToolId)
    );
  }

  
  public static function createEinrichtungRecipientsWithKurs(\Kurs $kurs, int $toolId): EMailEinrichtungRecipientToolsKursSettings
  {
    $recipients = self::getSettingsMailEmpfaenger($toolId);
    $result = new EMailEinrichtungRecipientToolsKursSettings($kurs);
    $anMa = $recipients['PlanMa'] || $recipients['VerwMa'];
    $result->setSettingMailToEinrichtung($recipients['Einrichtung'] ? true : ($anMa ? null : false)) 
      ->setSettingMailToPlanendenMitarbeiter($recipients['PlanMa'])
      ->setSettingMailToVerwaltendenMitarbeiter($recipients['VerwMa'])
      ->setSettingMailToVerantwortendenMitarbeiter($recipients['VerantwMa']);

    return $result;
  }

  
  private static function sendEmailToEinrichtung(
    string $subject,
    string $body,
    string $footerReason,
    $user,
    ?IEMailEinrichtungRecipientSettings $recipientSettings
  ): bool {
    $sender = \Kufer\Mail\Sender\EMailSenderFactory::create();
    $mail = new \Kufer\Mail\EMail\EMailHTML(\StringOperations::html_entity_decode($subject), $body);
    $mail->addKuferToolsFooter($footerReason, $user);
    $emailSentResult = $sender->informEinrichtung($mail, null, $recipientSettings);

    return $emailSentResult->hasSentAnyMails();
  }

  
  private static function getBenachrichtigungTermindatenAenderungView($pKurs, $pKurstage)
  {
    $viewModel = new BenachrichtigungTermindatenAenderungViewModel();
    $viewModel->kurs = $pKurs;
    $viewModel->kurstage = $pKurstage;

    return new BenachrichtigungTermindatenAenderungView($viewModel);
  }

  
  private static function getBenachrichtigungKursdatenAenderungView($pKurs)
  {
    $viewModel = new BenachrichtigungKursdatenAenderungViewModel();
    $viewModel->kurs = $pKurs;

    return new BenachrichtigungKursdatenAenderungView($viewModel);
  }

  
  private static function getBenachrichtigungBelegungsdatenAenderungView($pBelegung)
  {
    $viewModel = new BenachrichtigungBelegungsdatenAenderungViewModel();
    $viewModel->belegung = $pBelegung;

    return new BenachrichtigungBelegungsdatenAenderungView($viewModel);
  }

  
  public static function setChangedFieldValuesToDatamodule(
    ToolSection $toolSection,
    \ToolSettings $toolSettings,
    $pColumns,
    $pOrigDatamodule,
    $pChangedDatamodule,
    $pChangedFields,
    $pChangedFieldsLabels
  ) {
    $nothingChanged = true;
    $columns = \ArrayOperations::setAttributAsKey($pColumns, 'fieldname');

    foreach ($pChangedDatamodule as $changedDatamodul) {
      $changedDatamodul->changedFieldValues = array();
      foreach ($pChangedFields as $field) {
        if ($pOrigDatamodule[$changedDatamodul->id]->getVarValue($field) == $changedDatamodul->getVarValue($field) || !isset($pChangedFieldsLabels[$field])) {
          continue;
        }
        $nothingChanged = false;
        $column = isset($columns[$field]) ? $columns[$field] : null;
        $changedFieldValue = new class() extends \Datamodul {
          public $field;
          public $value_old;
          public $value_new;
        };

        $changedFieldValue->field = $pChangedFieldsLabels[$field];
        $changedFieldValue->value_old = !is_null($column) ? self::getInputField(
          $toolSection,
          $toolSettings,
          $pOrigDatamodule[$changedDatamodul->id],
          $column
        ) : $pOrigDatamodule[$changedDatamodul->id]->getVarValue($field);
        $changedFieldValue->value_new = !is_null($column) ? self::getInputField(
          $toolSection,
          $toolSettings,
          $changedDatamodul,
          $column
        ) : $changedDatamodul->getVarValue($field);
        $changedDatamodul->changedFieldValues[] = $changedFieldValue;
      }
    }

    return array('changedDatamodule' => $pChangedDatamodule, 'nothingChanged' => $nothingChanged);
  }

  
  private static function getEmailSubject($pView)
  {
    return $pView->getNoColumn();
  }

  
  private static function getEmailBody($pView)
  {
    return $pView->getHeader() . $pView->getBody() . $pView->getFooter();
  }

  
  private static function getSettingsMailEmpfaenger($pToolId)
  {
    $toolSettings = \ToolSettingsAPI::getToolSettings($pToolId);

    return $toolSettings->getSettingsDatenAenderungMailAn();
  }

  
  private static function getWssField(ToolSection $toolSection, \ToolSettings $toolSettings, $pDatamodulColumn)
  {
    static $wssFactory = null;
    if (is_null($wssFactory)) {
      $wssFactory = new \Kufer\Web\KuferTools\Utils\WssField\WssFactory();
    }

    return $wssFactory->getWss($toolSection, $toolSettings, $pDatamodulColumn);
  }

  private static function getInputField(
    ToolSection $toolSection,
    \ToolSettings $toolSettings,
    $pDataModulWert,
    $pDatamodulColumn,
    $pIsFormular = false
  ) {
    $wssField = self::getWssField($toolSection, $toolSettings, $pDatamodulColumn);

    return $wssField->getField($pDataModulWert, $pIsFormular);
  }

  
  public static function getChangesUpdate(
    ToolSection $toolSection,
    \ToolSettings $toolSettings,
    array $columns,
    \Datamodul $orig,
    \Datamodul $changed,
    array $changedFields
  ): array {
    $wssFactory = new \Kufer\Web\KuferTools\Utils\WssField\WssFactory();
    $changes = array();
    foreach ($columns as $column) {
      if (in_array($column->fieldname, $changedFields)) {
        $change = new class() extends \Datamodul {
          public $label;
          public $new;
          public $old;
        };

        $wssField = $wssFactory->getWss($toolSection, $toolSettings, $column);
        $change->label = $column->title;
        $change->new = $wssField->getHtmlEncodedValue($changed, false);
        $change->old = $wssField->getHtmlEncodedValue($orig, false);

        $changes[] = $change;
      }
    }

    return $changes;
  }

  
  public static function getChangesInsert(
    ToolSection $toolSection,
    \ToolSettings $toolSettings,
    array $columns,
    \Datamodul $changed
  ): array {
    $wssFactory = new \Kufer\Web\KuferTools\Utils\WssField\WssFactory();
    $changes = array();
    foreach ($columns as $column) {
      $change = new class() extends \Datamodul {
        public $label;
        public $wert;
      };

      $wssField = $wssFactory->getWss($toolSection, $toolSettings, $column);
      $change->label = $column->title;
      $change->wert = $wssField->getHtmlEncodedValue($changed, false);

      $changes[] = $change;
    }

    return $changes;
  }
}