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

use Kufer\Utils\Pdf\Helper\RenderObject;
use Kufer\Utils\Pdf\Helper\Row;
use Kufer\Utils\Pdf\Helper\Table;
use Kufer\Utils\Pdf\Helper\TextField;
use Kufer\Web\KuferTools\Utils\Spezial\MVHSUtils;


class Anwesenheitsliste3G extends AnwesenheitslisteBase
{
  public function getListID()
  {
    return 68;
  }

  public function getListTyp()
  {
    return '©';
  }

  protected function getOutputName(): string
  {
    return 'AnwesenheitslisteMit3GInfo.pdf';
  }

  public function getAnzahlAntwortboxen()
  {
    return 5;
  }

  public function getTNDarstellungEnabled($optionName)
  {
    switch ($optionName) {
      case 'option9': 
        return true;
    }

    return parent::getTNDarstellungEnabled($optionName);
  }

  public function getTNDarstellungText($optionName)
  {
    switch ($optionName) {
      case 'option8':
        return 'zusätzliche Leerzeile';
      case 'option9':
        return 'Anmeldestatus';
      default:
        return parent::getTNDarstellungText($optionName);
    }
  }

  public function getSpaltenanordnungText($optionName)
  {
    switch ($optionName) {
      case 'option1':
        return 'Mit Zusatzspalten';
      case 'option2':
        return 'Spalte für Geimpft';
      case 'option3':
        return 'Spalte für Genesen';
      case 'option4':
        return 'Spalte für Getestet';
      case 'option5':
        return '3G-Regel geprüft';
      case 'option6':
        return 'Mehrfach vorhandene Kurstage mit gleicher Uhrzeit anzeigen';
      case 'option7':
        return 'Spalte für Unterschrift anzeigen';
      case 'option8':
        return 'mit Geburtstagen';
      case 'option9':
        return 'nur eigene Kurstage anzeigen';
      default:
        return '';
    }
  }

  public function getSpaltenanordnungEnabled($optionName)
  {
    switch ($optionName) {
      case 'option5':
        return !\DBWorkBASysSettings::isMVHS() || $this->toolId != \ToolsAPI::TOOL_KURSUEBERSICHT_DOZ;
      case 'option9':
        return $this->toolId == \ToolsAPI::TOOL_KURSUEBERSICHT_DOZ && !parent::areOnlyKurstageVonEingeloggtemDozentAllowed();
      default:
        return $this->getSpaltenanordnungText($optionName) !== '';
    }
  }

  public function getSpaltenanordnungTextEnabled($optionName): bool
  {
    switch ($optionName) {
      default:
        return false;
      case 'option5':
        return true;
    }
  }

  public function getDruckbereichEnabled($optionName)
  {
    switch ($optionName) {
      case 'namegross':
        return true;
      default:
        return parent::getDruckbereichEnabled($optionName);
    }
  }

  protected function areOnlyKurstageVonEingeloggtemDozentAllowed(): bool
  {
    if (parent::areOnlyKurstageVonEingeloggtemDozentAllowed()) {
      
      return true;
    }

    return $this->settings->spaltenanordnung->option9 ?? false;
  }

  public function loadFactoryDefaults()
  {
    TNListe::loadFactoryDefaults();

    if (!isset($this->settings->tnDarstellung)) {
      $this->settings->tnDarstellung = new \webtools\lists\TNDarstellung();
    }
    $this->settings->tnDarstellung->option1 = true; 

    if (!isset($this->settings->spaltenanordnung)) {
      $this->settings->spaltenanordnung = new \webtools\lists\Spaltenanordnung();
    }
    $this->settings->spaltenanordnung->option2 = true; 
    $this->settings->spaltenanordnung->option4 = true; 
    $this->settings->spaltenanordnung->option5 = false;
    if (\DBWorkBASysSettings::isMVHS() && $this->toolId == \ToolsAPI::TOOL_KURSUEBERSICHT_DOZ) {
      $this->settings->spaltenanordnung->option5 = true;
    }
    $this->settings->spaltenanordnung->option5_text = '3G-Regel geprüft';
    $this->settings->spaltenanordnung->option6 = false; 
    $this->settings->spaltenanordnung->option7 = true; 
    $this->settings->spaltenanordnung->option9 = true; 

    if (!isset($this->settings->kopfbereich)) {
      $this->settings->kopfbereich = new \webtools\lists\Kopfbereich();
      $this->settings->kopfbereich->mitKursgebuehren = true;
      $this->settings->kopfbereich->mitDozentenTelNr = true;
    }
    $this->settings->fusszeile = LISTEN_FUSSZEILE_ALLE;
    $this->settings->fusszeilen = array_map(
      static function($str) {
        $result = new \webtools\lists\Fusszeile();
        $result->text = $str;

        return $result;
      },
      array(
        '*1: Ich versichere, dass ich mind. zweifach gegen Covid19 geimpft bin und die zweite Impfung mindestens 2 Wochen zurückliegt',
        'bzw. dass ich von einer max. 6 Monate zurückliegenden Corona-Erkrankung genesen bin.',
        '*2: Ich versichere, dass ich vor maximal 24 Stunden einen negativen Test absolviert bzw. durchgeführt habe.',
        '',
        ''
      )
    );

    $this->settings->caption = 'Anwesenheitsliste mit 3G-Info';
  }

  public function header()
  {
    TNListe::header();
  }

  
  protected function createKurstageTable($kurs, array $kursetage): Table
  {
    $table = new Table($this->pdf, array(), array());
    $table->setFontSize(8);
    $table->setBorder(true);
    $table->setInnerBorders(true);

    $kurstageDatum = $table->createRow();
    $kurstageBeginn = $table->createRow();
    $kurstageEnde = $table->createRow();

    $headerColumnWidth = $this->getWidthKurstagColumn($kurs) . '%';
    $kurstageDatum->addColumn('Kurstag', $headerColumnWidth);
    $kurstageBeginn->addColumn('Beginn', $headerColumnWidth);
    $kurstageEnde->addColumn('Ende', $headerColumnWidth);
    foreach (array($kurstageDatum, $kurstageBeginn, $kurstageEnde) as $row) {
      $row->getChildAt(0)->setTextOrientation(RenderObject::TEXT_ORIENTATION_CENTER_VERTICAL | RenderObject::TEXT_ORIENTATION_RIGHT);
    }

    $columnWidth = $this->getWidthPerKurstag() . '%';
    foreach ($kursetage as $kurstag) {
      $kurstageDatum->addColumn(new TextField($this->pdf, $kurstag->getVarValue('datum_kurz')), $columnWidth);
      $kurstageBeginn->addColumn(new TextField($this->pdf, $kurstag->getVarValue('zeit_beg')), $columnWidth);
      $kurstageEnde->addColumn(new TextField($this->pdf, $kurstag->getVarValue('zeit_ende')), $columnWidth);
    }

    $this->createOptionalForKurstageTable($table, $headerColumnWidth, $columnWidth, $kurs, $kursetage);

    return $table;
  }

  
  protected function createOptionalForKurstageTable(Table $table, $headerColumnWidth, $columnWidth, $kurs, array $kurstage): void
  {
    $is3gEnabled = $this->is3GCheckedEnabled($kurs);
    if ($is3gEnabled) {
      $checked3g = $table->createRow();
      $checked3g->getChildAt($checked3g->addColumn($this->get3GRegelText(), $headerColumnWidth))
        ->setTextOrientation(RenderObject::TEXT_ORIENTATION_RIGHT | RenderObject::TEXT_ORIENTATION_CENTER_VERTICAL);
      foreach ($kurstage as $kurstag) {
        $checked3g->addColumn('', $columnWidth);
      }
    }
  }

  private function is3GCheckedEnabled(?\Kurs $kurs = null): bool
  {
    if (\DBWorkBASysSettings::isMVHS() && $this->toolId == \ToolsAPI::TOOL_KURSUEBERSICHT_DOZ) {
      $kurs = $kurs ?? \DBWorkKurse::getDefaultInstance()->getKurs($this->knr);

      return MVHSUtils::shouldShowEnable3GColumnInTnListe($kurs);
    }

    return $this->settings->spaltenanordnung->option5 ?? false;
  }

  private function get3GRegelText(): string
  {
    return empty($this->settings->spaltenanordnung->option5_text) ? '3G-Regel geprüft' : $this->settings->spaltenanordnung->option5_text;
  }

  private function isSignatureColumnEnabled(): bool
  {
    return $this->settings->spaltenanordnung->option7 ?? false;
  }

  private function isBirthdateColumnEnabled(): bool
  {
    return $this->settings->spaltenanordnung->option8 ?? false;
  }

  protected function createTable($pKurs, array $kurstage): Table
  {
    if (empty($kurstage)) {
      $kurs = \DBWorkKurseWT::getDefaultInstance()->getKurs($pKurs);
    } else {
      $kurs = \ArrayOperations::firstValue($kurstage)->getKurs();
    }

    $fontSizeHeader = 10;
    if ($this->_isHochformat()) {
      $fontSizeHeader = 7;
    }

    $kurstagTableDescColumnWidth = empty($kurstage) ? 0 : $this->getWidthKurstagColumn($kurs);
    $nameColumnWidth = $this->getWidthNameRow() - $kurstagTableDescColumnWidth;
    $kurstageColumnWidth = (count($kurstage) * $this->getWidthPerKurstag()) + $kurstagTableDescColumnWidth;
    $zzColumnWidth = (count($this->getZuzatzspalten(!empty($kurstage))) * $this->getWidthPerZusatzspalte());

    $widths = array(
      $nameColumnWidth . '%',
      $kurstageColumnWidth . '%',
      $zzColumnWidth . '%'
    );
    $titles = array(
      'Nr. Name, Vorname',
      '',
      ''
    );
    if ($this->isSignatureColumnEnabled()) {
      $signatureColumnWidth = 92.5 - $nameColumnWidth - $kurstageColumnWidth - $zzColumnWidth;
      $widths[] = $signatureColumnWidth . '%';
      $titles[] = 'Unterschrift';
    }

    $table = new Table(
      $this->pdf,
      $widths,
      $titles
    );
    $table->setFontSize(8);
    $table->setBorder(true);
    $table->setInnerBorders(true);
    $table->setRowDistance(0.0);
    $table->setHeadRowDistance(1);

    
    $head = $table->getHead();
    $head->getChildAt(0)->setFontSize($fontSizeHeader);

    
    
    $tnColumn = $head->getChildAt(0);
    $tnColumn->setTextOrientation(RenderObject::TEXT_ORIENTATION_BOTTOM | RenderObject::TEXT_ORIENTATION_LEFT);

    
    if (!empty($kurstage)) {
      $kurstageTable = $this->createKurstageTable($kurs, $kurstage);
      $kurstageTable->setWidth($head->getChildAt(1)->getComputedWidth() + $kurstagTableDescColumnWidth);
      $head->setChildAt(1, $kurstageTable);
    }

    
    if (!empty($this->getZuzatzspalten(!empty($kurstage)))) {
      $head->setChildAt(2, $this->createZusatzspalteHeaderRow($kurstage));
    }

    
    if ($this->isSignatureColumnEnabled()) {
      $head->getChildAt(3)->setFontSize($fontSizeHeader);
      $head->getChildAt(3)->setTextOrientation(RenderObject::TEXT_ORIENTATION_BOTTOM | RenderObject::TEXT_ORIENTATION_LEFT);
    }

    $this->createTeilnehmerRows($kurs, $kurstage, $table);

    return $table;
  }

  
  protected function createTeilnehmerRows($kurs, array $kurstage, Table $table): void
  {
    $anwesenheiten = $this->getAnwesenheitsAry();

    $belegungen = $this->_getBelegungen($kurs->id);
    $i = 0;
    foreach ($belegungen as $belegung) {
      $row = $this->createTeilnehmerRow($i, $belegung, $anwesenheiten, $kurstage, $table);
      if (!is_null($row)) {
        $table->addChild($row);
      }
      ++$i;
    }

    if (($this->settings->druckbereich->auffuellen ?? false)
        && ($this->settings->druckbereich->auffuellArt ?? '') === 'S') { 
      $table->setFillTillPageBreakFunction(
        function(Table $table, int $idx) use ($kurstage) {
          return $this->createTeilnehmerRow($idx, null, array(), $kurstage, $table);
        }
      );
    }
  }

  protected function createNameForTeilnehmer(\Belegung $belegung): string
  {
    $teilnehmer = $belegung->getTeilnehmer();
    $result = $teilnehmer->getVarValue('name_ggf_vorname');
    if ($this->settings->tnDarstellung->option9 ?? false) { 
      $result .= ' (' . $belegung->getVarValue('status_lang') . ')';
    }

    return $result;
  }

  protected function createTextForTeilnehmer(\Belegung $belegung): string
  {
    $teilnehmer = $belegung->getTeilnehmer();
    $cellText = '';

    if ($this->settings->tnDarstellung->option2 ?? false) { 
      $cellText .= "\n$teilnehmer->zusatz";
    }
    if ($this->isBirthdateColumnEnabled()) {
      $cellText .= "\n$teilnehmer->gebdat";
    }
    if ($this->settings->tnDarstellung->option3 ?? false) { 
      $cellText .= "\n$teilnehmer->strasse";
    }
    if ($this->settings->tnDarstellung->option4 ?? false) { 
      $cellText .= "\n$teilnehmer->ort";
    }
    if ($this->settings->tnDarstellung->option5 ?? false) { 
      $cellText .= "\n" . $teilnehmer->getTelNrs();
    }
    if ($this->settings->tnDarstellung->option6 ?? false) { 
      $cellText .= "\n" . ((isset($teilnehmer->email->wert)) ? $teilnehmer->email->wert : '');
    }
    if ($this->settings->tnDarstellung->option7 ?? false) { 
      $cellText .= "\n" . ((isset($teilnehmer->fax->wert)) ? 'Fax: ' . $teilnehmer->fax->wert : '');
    }
    if ($this->settings->tnDarstellung->option8 ?? false) { 
      $cellText .= "\n";
    }

    return $cellText;
  }

  protected function getNameFontSize(): float
  {
    if ($this->settings->druckbereich->namegross ?? false) {
      return 12;
    }

    return 8;
  }

  
  protected function createTeilnehmerRow(int $idx, ?\Belegung $belegung, array $anwesenheiten, array $kurstage, Table $table): ?Row
  {
    $row = $table->createRow(false);

    
    $name = '';
    $additional = '';
    if (!is_null($belegung)) {
      $name = $this->createNameForTeilnehmer($belegung);
      $additional = $this->createTextForTeilnehmer($belegung);
    }

    $rowIdxName = new Row($this->pdf);
    $widthNum = $this->_isHochformat() ? 3 : 2;
    $rowIdxName->addColumn((string)($idx + 1), $widthNum . '%');
    $widthName = ($this->getWidthNameRow() - $widthNum) . '%';
    if ($additional === '') {
      $rowIdxName->addColumn(array($name), $widthName);
      $rowIdxName->getChildAt(1)->setFontSize($this->getNameFontSize());
    } else {
      $tableName = new Table($this->pdf, array(), array());
      $tableName->createRow()->addColumn(array($name), $widthName);
      $tableName->createRow()->addColumn(array($additional), $widthName);
      $tableName->getChildAt(0)->setFontSize($this->getNameFontSize());
      $rowIdxName->addColumn($tableName, $widthName);
    }
    $rowIdxName->getChildAt(0)->setTextOrientation(RenderObject::TEXT_ORIENTATION_TOP | RenderObject::TEXT_ORIENTATION_RIGHT);
    $row->addColumn($rowIdxName, $this->getWidthNameRow() . '%');

    
    if (!empty($kurstage)) {
      $rowKurstage = new Row($this->pdf);
      $rowKurstage->setInnerBorders(true);
      $rowKurstage->setBorder(true);
      foreach ($kurstage as $kurstag) {
        $text = '';
        if ($this->isAnwesenheitenInKurstageEnabled() && !is_null($belegung) && isset($anwesenheiten[$belegung->id])) {
          $anw = $anwesenheiten[$belegung->id][$kurstag->id] ?? null;
          if (!is_null($anw)) {
            $text = $anw->astatus;
          }
        }

        $rowKurstage->addColumn($text, $this->getWidthPerKurstag() . '%');
      }
      $row->addColumn($rowKurstage, $rowKurstage->getComputedWidth());
    } else {
      $row->addColumn('', 0);
    }

    
    if (!empty($this->getZuzatzspalten(!empty($kurstage)))) {
      $zzRow = $this->createZusatzspaltenEmptyRow($belegung, $kurstage);
      $row->addColumn($zzRow, $zzRow->getComputedWidth());
    } else {
      $row->addColumn('', 0);
    }

    
    if ($this->isSignatureColumnEnabled()) {
      $row->addColumn('', '');
    }

    $row->setInnerBorders(true);
    $row->setBorder(true);
    $row->setHeight(max($row->getAutoHeight(), $this->getMinTeilnehmerRowHeight()));

    return $row;
  }

  protected function getMinTeilnehmerRowHeight(): float
  {
    return 6;
  }

  protected function getWidthNameRow(): float
  {
    return 23.8;
  }

  protected function getWidthKurstagColumn(\Kurs $kurs): float
  {
    $result = $this->getWidthPerKurstag() * 1.4;
    if ($this->is3GCheckedEnabled($kurs)) {
      $textFieldDemo = new TextField($this->pdf, $this->get3GRegelText());
      $textFieldDemo->setFontSize(8);

      return max($this->pdf->getWidthRelative($textFieldDemo->getComputedWidth()) + 0.5, $result);
    } else {
      return $result;
    }
  }

  protected function getWidthPerKurstag(): float
  {
    if ($this->_isHochformat()) {
      return 4.4;
    } else {
      return 3.10;
    }
  }

  protected function getWidthPerZusatzspalte(): float
  {
    return 6.4;
  }

  protected function createZusatzspaltenEmptyRow(?\Belegung $belegung, array $kurstage): Row
  {
    $cnt = count($this->getZuzatzspalten(!empty($kurstage)));

    $row = new Row($this->pdf);
    $row->setFontStyle('');
    $row->setFontSize($this->getFontSizeZusatzspalten());
    $row->setBorder(RenderObject::BORDER_RIGHT);
    $row->setInnerBorders(true);

    for ($i = 0; $i < $cnt; ++$i) {
      $row->addColumn('', $this->getWidthPerZusatzspalte() . '%');
    }

    return $row;
  }

  protected function createZusatzspalteHeaderRow(array $kurstage): Row
  {
    $zzColumn = $this->getZuzatzspalten(!empty($kurstage));

    $row = new Row($this->pdf);
    $row->setFontStyle('');
    $row->setFontSize($this->getFontSizeZusatzspalten());
    $row->setBorder(true);
    $row->setInnerBorders(true);
    foreach ($zzColumn as $column) {
      $row->addColumn(array($column), $this->getWidthPerZusatzspalte() . '%');
    }

    return $row;
  }

  protected function getFontSizeZusatzspalten(): float
  {
    return 8.2;
  }

  private function isZusatzspaltenEnabled(): bool
  {
    return $this->settings->spaltenanordnung->option1 ?? false;
  }

  private function isGeimpftEnabled(): bool
  {
    return $this->settings->spaltenanordnung->option2 ?? false;
  }

  private function isGenesenEnabled(): bool
  {
    return $this->settings->spaltenanordnung->option3 ?? false;
  }

  private function isGetestetEnabled(): bool
  {
    return $this->settings->spaltenanordnung->option4 ?? false;
  }

  protected function getZuzatzspalten(bool $hasKurstage): array
  {
    $result = array();

    if (!$hasKurstage && $this->is3GCheckedEnabled(null)) {
      $result[] = $this->get3GRegelText();
    }

    if ($this->isZusatzspaltenEnabled()) {
      $SpaltenUeb = 'SpaltenUeb';
      for ($i = 1; $i <= $this->getAnzahlAntwortboxen(); $i++) {
        $temp = $SpaltenUeb . $i;
        if (isset($this->settings->antwortboxen->{$temp}) && $this->settings->antwortboxen->{$temp} != '') {
          $zusatzspalten = $this->settings->antwortboxen->{$temp};
          $result[] = $zusatzspalten;
        }
      }
    }

    $i = 0;
    if ($this->isGeimpftEnabled()) {
      $result[] = 'Impfung (*' . ++$i . ')';
    }
    if ($this->isGetestetEnabled()) {
      $result[] = 'Test (*' . ++$i . ')';
    }
    if ($this->isGenesenEnabled()) {
      $result[] = 'Genesen (*' . ++$i . ')';
    }

    return $result;
  }

  protected function showKurstageWithSameDateTime(): bool
  {
    return $this->settings->spaltenanordnung->option6 ?? false;
  }

  public function _createContent($pKurs = '')
  {
    if (empty($this->kursetage)) {
      $this->createTable($this->knr, array())->render();
    } else {
      $kurstage = array_merge($this->kursetage, $this->uebrigeKurstage);
      (new \Kufer\Web\Classes\Stream\ArrayStream($kurstage))
        ->chunks($this->getMaxKurstageAufSeite())
        ->applyOnFirst(function(array $kurstage) {
          $this->createTable($this->knr, $kurstage)->render();
        })
        ->each(function(array $kurstage) {
          $this->pdf->AddPage();
          $this->createTable($this->knr, $kurstage)->render();
        });
    }
  }

  protected function getMaxKurstageAufSeite()
  {
    
    if ($this->_isHochformat()) {
      return max(1, (int)(10 - (count($this->getZuzatzspalten(true)) * 1.4)));
    } else {
      return max(2, (int)(16 - count($this->getZuzatzspalten(true)) * 1.8));
    }
  }

  public function getListBezeichnungForHTML()
  {
    return 'Anwesenheitsliste mit 3G-Info';
  }

  protected function isAnwesenheitenInKurstageEnabled(): bool
  {
    return $this->druckTnListeSettingsAry['anwAnzeigen' . $this->getListID()] ?? false;
  }
}