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

namespace Kufer\Web\KuferTools\Ausgaben\SammelEMail;

use Kufer\Web\KuferTools\Ausgaben\CommonTasks\SendPrepare as SendPrepare;
use Kufer\Mail\EMail\EMailHTML;
use Kufer\Mail\EMail\EMailPlaintext;
use Kufer\Mail\EMail\IEMail;
use Kufer\Mail\Sender\EMailSenderFactory;
use Kufer\Mail\Sender\IEMailSender;
use Kufer\Mail\Sender\Result\EMailSentResult;
use Kufer\Mail\Sender\Result\EMailSentStatusCode;
use Kufer\Web\Classes\Mail\Sender\Settings\RecipientEinrichtung\EMailEinrichtungRecipientToolsKursSettings;

abstract class SendSammelEMailUseCase extends \Kufer\Web\KuferTools\Basis\UseCase\EinzelKursUseCase
{
  public const EMAILVERSAND_SUCCESS = 0;
  public const EMAILVERSAND_FEHLER_BEIM_VERSENDEN = 1;
  public const EMAILVERSAND_UNGUELTIGE_ODER_LEERE_EMAIL = 2;
  public const EMAILVERSAND_STANDBY = 3;

  
  protected $sendPreparer;

  
  protected $kurs;

  public function __construct($request, $response = null)
  {
    parent::__construct($request, $response ?? new SendSammelEMailResponse());
    $this->sendPreparer = $this->createSendPreparer();
  }

  protected function createSendPreparer(): SendPrepare
  {
    return new SendPrepare();
  }

  
  protected function getAttachments(): array
  {
    return array();
  }

  protected function isUploadFault(): bool
  {
    return false;
  }

  protected function deleteUploadFiles(): void
  {
  }

  public function action()
  {
    $errorMessage = '';
    $emailStatus = new EMailSentResult(array());
    $this->kontaktUser = array();
    $this->kurs = $this->getKurs($this->request->knr);

    
    try {
      if ($this->isUploadFault()) {
        $this->response->uploadFailed = true;
      } elseif ($this->request->isRefresh) {
        $this->response->doppeltSenden = true;
      }
      
      else {
        $email = $this->createEMail();
        $sender = $this->createEMailSender();
        $emailStatus = $this->sendEMail($sender, $email);
      } 
      $this->deleteUploadFiles();
    } catch (\Exception $ex) {
      $errorMessage = $ex->getMessage(); 
    }

    return $this->getResponse($errorMessage, $emailStatus);
  }

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

    return true;
  }

  protected function createEMail(): IEMail
  {
    $subject = $this->request->emailBetreff;
    $content = $this->request->emailBody;
    if (isset($this->request->isHtml) && $this->request->isHtml) {
      return new EMailHTML($subject, $content, $this->getAttachments());
    } else {
      return new EMailPlaintext($subject, $content, $this->getAttachments());
    }
  }

  protected function getCustomEinrichtungEMailAddress(): ?string
  {
    return null;
    
  }

  protected function createEMailSender(): IEMailSender
  {
    return EMailSenderFactory::createForToolsWithCustomAddress($this->getCustomEinrichtungEMailAddress());
  }

  protected function getPositionStatus(EMailSentResult $result, string $positionName): int
  {
    $recipient = $result->findByPosition($positionName);
    if (\is_null($recipient)) {
      return self::EMAILVERSAND_STANDBY; 
    }

    if ($recipient->isError()) {
      if ($recipient->getStatusCode() == EMailSentStatusCode::FAILURE_EMAIL_NOT_FOUND) {
        return self::EMAILVERSAND_UNGUELTIGE_ODER_LEERE_EMAIL; 
      }

      return self::EMAILVERSAND_FEHLER_BEIM_VERSENDEN; 
    }

    return self::EMAILVERSAND_SUCCESS; 
  }

  protected function sendEMail(IEMailSender $sender, IEMail $mail): EMailSentResult
  {
    $kopieAnEinrichtung = ($this->shouldSendMail2Einrichtung()
      || $this->isSetEinrichtungToolSettings());
    $kopieAnPlanendenMitarbeiter = $this->shouldSendMail2PlanendenMitarbeiter();
    $kopieAnVerwaltendenMitarbeiter = $this->shouldSendMail2VerwaltendemMitarbeiter();
    $kopieAnVerantwortendenMitarbeiter = $this->shouldSendMail2VerantwortendenMitarbeiter();

    $result = new EMailSentResult(array());
    if ($kopieAnEinrichtung
      || $kopieAnPlanendenMitarbeiter
      || $kopieAnVerwaltendenMitarbeiter
      || $kopieAnVerantwortendenMitarbeiter) {
      
      $recipientSettings = new EMailEinrichtungRecipientToolsKursSettings($this->kurs);
      $recipientSettings
        ->setSettingMailToEinrichtung($kopieAnEinrichtung ? true : null)
        ->setSettingMailToPlanendenMitarbeiter($kopieAnPlanendenMitarbeiter)
        ->setSettingMailToVerwaltendenMitarbeiter($kopieAnVerwaltendenMitarbeiter)
        ->setSettingMailToVerantwortendenMitarbeiter($kopieAnVerantwortendenMitarbeiter)
        ->setSettingsVhsEMail($this->getCustomEinrichtungEMailAddress());
      $resultEmailEinrichtung = $sender->sendFromPersonToEinrichtung($mail, \SessionOperations::getCurrentWebToolsPerson(), $recipientSettings);
      $result = $result->merge($resultEmailEinrichtung);
      $this->response->einrichtungMailStatus = $this->getPositionStatus($resultEmailEinrichtung, EMailEinrichtungRecipientToolsKursSettings::RECIPIENT_EINRICHTUNG);
      $this->response->mitarbeiterPlanendMailStatus = $this->getPositionStatus($resultEmailEinrichtung, EMailEinrichtungRecipientToolsKursSettings::RECIPIENT_PLANENDER_MITARBEITER);
      $this->response->mitarbeiterVerwaltendMailStatus = $this->getPositionStatus($resultEmailEinrichtung, EMailEinrichtungRecipientToolsKursSettings::RECIPIENT_VERWALTENDER_MITARBEITER);
      $this->response->mitarbeiterVerantwortendMailStatus = $this->getPositionStatus($resultEmailEinrichtung, EMailEinrichtungRecipientToolsKursSettings::RECIPIENT_VERANTWORTENDER_MITARBEITER);
    } 

    $kopieAnAbsender = $this->doSendKopieAnAbsender();
    if ($kopieAnAbsender) {
      $resultEmailCopy = $sender->sendCopyToToolsUser($mail, $this->getUser());
      $result = $result->merge($resultEmailCopy);
      $this->response->personMailStatus = $resultEmailCopy->hasSentAllMails() ? 0 : 1;
    } 

    return $result;
  }

  
  protected function getResponse(string $errorMessage, $emailStatus)
  {
    $this->handleResponseStrategies();
    $this->response->errorMessage = $errorMessage;
    $this->response->kurs = $this->kurs;
    $this->response->emailStatus = $emailStatus;
    $this->response->isRefresh = $this->request->isRefresh;

    $allgSettings = \AllgSettingsAPI::getAllgSettings();
    $this->response->einrichtungName = $allgSettings->vhsname;

    return $this->response;
  }

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

  
  protected function doSendKopieAnAbsender(): bool
  {
    switch ($this->getToolId()) {
      case \ToolsAPI::TOOL_KURSUEBERSICHT_DOZ:
        return isset($this->toolSettings->sendMail2Dozent) && !empty($this->toolSettings->sendMail2Dozent);
      case \ToolsAPI::TOOL_KURSPLANUNG_MA:
        return isset($this->toolSettings->sendMail2Ma) && !empty($this->toolSettings->sendMail2Ma);
      case \ToolsAPI::TOOL_RAUMBELEGUNG_HM: 
        return false;
      case \ToolsAPI::TOOL_KURSUEBERSICHT_FA:
        return isset($this->toolSettings->sendMail2Fa) && !empty($this->toolSettings->sendMail2Fa);
    }

    return false;
  }

  
  protected function isSetEinrichtungToolSettings(): bool
  {
    return false;
  }

  protected function shouldSendMail2Einrichtung(): bool
  {
    return $this->toolSettings->sendMail2Einrichtung ?? false;
  }

  protected function shouldSendMail2PlanendenMitarbeiter(): bool
  {
    return $this->toolSettings->sendMail2PlanendenMitarbeiter ?? false;
  }

  protected function shouldSendMail2VerwaltendemMitarbeiter(): bool
  {
    return $this->toolSettings->sendMail2VerwaltendenMitarbeiter ?? false;
  }

  protected function shouldSendMail2VerantwortendenMitarbeiter(): bool
  {
    return $this->toolSettings->sendMail2VerantwortendenMitarbeiter ?? false;
  }
}