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

namespace Kufer\Web\KuferTools\Basis\Dokumente\DokumenteUpload;

use EMailAttachment;
use Kufer\Mail\EMail\EMailHTML;
use Kufer\Mail\EMail\IEMail;
use Kufer\Mail\Sender\EMailSenderFactory;
use Kufer\Mail\Sender\Result\EMailSentResult;
use Kufer\Web\Classes\Identifier\Identifier;
use Kufer\Web\Classes\Pdf\Convert\ConvertToPDF;
use Kufer\Web\KuferTools\Utils\StatusMessages\StatusMessage;

abstract class DokumenteUploadUseCase extends \Kufer\Web\KuferTools\Basis\UseCase\ToolUseCase
{
  public function __construct($request, $response = null)
  {
    parent::__construct($request, \is_null($response) ? new DokumenteUploadResponse() : $response);
  }

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

    return true;
  }

  abstract protected function isUploadAllowed(): bool;

  public function action()
  {
    if (!$this->request->isRefresh) {
      $success = $this->saveDokument();
      if ($success && $this->shouldSendInfoAnEinrichtung()) {
        $this->sendInfoMailAnEinrichtung();
      }
    } else {
      $success = true;
    }

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

  abstract protected function shouldSendInfoAnEinrichtung(): bool;

  protected function getResponse($success)
  {
    $this->handleResponseStrategies();
    $this->response->success = $success;
    $this->response->externeDokumenteKategorien = $this->getExterneDokumenteKategorien();

    return $this->response;
  }

  private function getExterneDokumenteKategorien()
  {
    $dbw = new \DBWorkHLExterneDokumenteKategorien(1, true);

    return $dbw->getAll();
  }

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

  private function createCheckFiles(): \CheckFiles
  {
    $toolAdmin = \ToolSettingsAPI::getToolSettings(0);

    if ($toolAdmin->convertUploadDocumentsToPDF) {
      return new \Kufer\Web\Classes\Fileupload\CheckFilesKuferToolsConvertToPDF();
    } else {
      return new \CheckFilesKuferTools();
    }
  }

  private function saveDokument()
  {
    $toolSettingsAdmin = \ToolSettingsAPI::getToolSettings(0);

    $checkFiles = $this->createCheckFiles();
    $statusCode = $checkFiles->checkSingleFile($this->request->file);

    if ($statusCode !== \CheckFilesKuferTools::UPLOAD_OK) {
      $message = $checkFiles->getErrorMessage($statusCode, $this->request->file);
      if ($statusCode == \CheckFilesKuferTools::UPLOAD_ERROR_DATEINAME_MIT_UNERLAUBTER_ENDUNG) {
        $message .= \DokuUploadUserAPI::getStatusMessagePart4FileExt(\ToolSettingsAPI::getToolSettings(0));
      }

      $this->response->statusMeldungen->addStatusMessageObj(new \Kufer\Web\KuferTools\Utils\StatusMessages\PlainStatusMessage(StatusMessage::MSG_BOX_ERROR, $message));

      return false;
    }

    $datDoc = $this->getDatDocAry();
    try {
      $content = $this->getFileContent();
      if ($toolSettingsAdmin->convertUploadDocumentsToPDF) {
        $newcontent = ConvertToPDF::create()->convert($content, $this->getFileMimeType());
        if (is_null($newcontent)) {
          $this->response->statusMeldungen->addStatusMessageObj(new \Kufer\Web\KuferTools\Utils\StatusMessages\PlainStatusMessage(StatusMessage::MSG_BOX_ERROR, 'Die Datei enthält Fehler'));

          return false;
        } else {
          $result = \DatDocAPI::sendAllgDokument2DMZ($datDoc, $newcontent);
        }
      } else {
        $result = \DatDocAPI::sendAllgDokument2DMZ($datDoc, $content);
      }

      if ($result == 'sendDone') {
        $this->response->statusMeldungen->addStatusMessageObj(new \Kufer\Web\KuferTools\Utils\StatusMessages\PlainStatusMessage(StatusMessage::MSG_BOX_SUCCESS, 'Das Dokument wurde erfolgreich hochgeladen.'));

        return true;
      } else {
        $this->response->statusMeldungen->addStatusMessageObj(new \Kufer\Web\KuferTools\Utils\StatusMessages\PlainStatusMessage(StatusMessage::MSG_BOX_ERROR, 'Das Hochladen von Dokumenten ist derzeit deaktiviert.'));

        return false;
      }
    } catch (\Exception $e) {
      \Logger::logg('Dokumentenupload: Fehler beim Hochladen: ' . $e->getMessage(), 515);
      $this->response->statusMeldungen->addStatusMessageObj(new \Kufer\Web\KuferTools\Utils\StatusMessages\PlainStatusMessage(StatusMessage::MSG_BOX_ERROR, 'Beim Hochladen der Datei ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.'));
    }

    return false;
  }

  
  private $cache_file_contents;

  private function getFileContent()
  {
    if (is_null($this->cache_file_contents)) {
      $this->cache_file_contents = file_get_contents($this->request->file['tmp_name']);
    }

    return $this->cache_file_contents;
  }

  
  private $cache_file_mimetype;

  
  private function getFileMimeType(): string
  {
    if (is_null($this->cache_file_mimetype)) {
      $this->cache_file_mimetype = $this->request->file['type'];
    }

    return $this->cache_file_mimetype;
  }

  protected function createInfoMailAnEinrichtungViewModel(): InfoMailAnEinrichtungViewModel
  {
    return new InfoMailAnEinrichtungViewModel();
  }

  abstract protected function createInfoMailAnEinrichtungView($viewModel): InfoMailAnEinrichtungView;

  protected function createEMail(): IEMail
  {
    $viewModel = $this->createInfoMailAnEinrichtungViewModel();
    $viewModel->datDocs = $this->getDatDocAry();
    $emailView = $this->createInfoMailAnEinrichtungView($viewModel);

    $emailBody = $emailView->getHeader() . $emailView->getBody() . $emailView->getFooter();
    $emailBetreff = \StringOperations::html_entity_decode($emailView->getNoData());

    $attachments = array();
    if ($this->shouldSendUploadInfoMailMitAnhang()) {
      $content = $this->getFileContent();
      $attachments[] = new \Kufer\Mail\Attachment\EMailAttachmentCustom(
        $this->request->file['name'],
        $content,
        $this->request->file['type'] ?? null
      );
    }

    return new EMailHTML($emailBetreff, $emailBody, $attachments);
  }

  protected function sendInfoMailAnEinrichtung(): EMailSentResult
  {
    $sender = EMailSenderFactory::createForToolsWithCustomAddress($this->getEMailAddressFromToolSettings());

    return $sender->sendFromPersonToEinrichtung($this->createEMail(), \SessionOperations::getCurrentWebToolsPerson());
  }

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

  abstract protected function shouldSendUploadInfoMailMitAnhang(): bool;

  
  abstract protected function getDbTypAndId(): array;

  protected function getDatDocObj()
  {
    $toolSettingsAdmin = \ToolSettingsAPI::getToolSettings(0);

    $user = $this->getUser();
    $datDoc = new \Dat_doc();
    $datDoc->datum = \DateTimeOperations::getDateNow();
    $datDoc->lfdnr = '';
    $datDoc->typ = 'D_D'; 
    list($dbTyp, $id) = $this->getDbTypAndId();
    if (!is_null($id) && !is_null($dbTyp) && $dbTyp !== '' && !$id->isEmpty()) {
      $datDoc->setValue2Var('ktErstelltVonId', $id->getId());
      $datDoc->setValue2Var('ktErstelltVonGuid', $id->getGuid());
      $datDoc->setValue2Var('ktErstelltVonTyp', $dbTyp);
    }

    $datDoc->pfaddok = '';
    $datDoc->pfadvorlage = $datDoc->pfaddok;
    $datDoc->datnamdok = '';
    $datDoc->datnamvorlage = '';
    $datDoc->name = $this->request->file['name'];
    if ($toolSettingsAdmin->convertUploadDocumentsToPDF) {
      $datDoc->name = preg_replace(':\\..*?$:', '.pdf', $datDoc->name);
    }
    $datDoc->versandtam = \DateTimeOperations::getDateTimeNow();

    $datDoc->beschreibung = $this->request->bezeichnung;
    if (trim($this->request->bezeichnung) == '') {
      $datDoc->beschreibung = $datDoc->name;
    }

    $username = $user->getVarValue('name_vorname_ohne_komma');
    $datDoc->versandtvom = $username;
    $datDoc->info = 'Von ' . $username . ' hochgeladen';
    $datDoc->hlextdokumentekat_id = $this->request->hlExtDokumenteKatId;

    return $datDoc;
  }

  private function getDatDocAry()
  {
    return array($this->getDatDocObj());
  }
}

class DokumenteUploadRequest
{
  public $knr;
  public $hlExtDokumenteKatId;
  public $bezeichnung;
  public $file;
  public $isXsrfOk;
  public $isRefresh;
}

class DokumenteUploadResponse extends \Kufer\Web\KuferTools\Basis\UseCase\ToolResponse
{
  public $user;
  public $menuPunkte = array();
  public $success;
  public $externeDokumenteKategorien;
}