<?php

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

namespace Kufer\KuferTools\Basis\Kursdetails\DetailsReiter\FeedbackBogen;

use Kufer\KuferTools\Utils\FeedbackHelper as FeedbackHelper;

abstract class FeedbackBogenUseCase extends \Kufer\KuferTools\Basis\UseCase\EinzelKursUseCase
{
  protected $userNr;
  protected $doAnonym;

  
  private $AktKurs;

  protected $fragebogen;

  
  protected $fragen4Bogen;

  protected $fragenCount;
  
  
  protected $feedbackBogenError;

  public function __construct($pRequest)
  {
    parent::__construct($pRequest, new FeedbackBogenResponse());
    $this->feedbackBogenError = false;

    $this->AktKurs = $this->getKurs($this->request->knr);
    $this->fragebogen = $this->getFrageBogen($this->AktKurs);
    
    if (isset($this->fragebogen->id) && $this->fragebogen->id >= 0) {
      $this->fragen4Bogen = $this->getFeedbackBogenFragen($this->fragebogen->id);
      $this->fragenCount = count($this->fragen4Bogen);
    } else {
      \Logger::logg('Es konnte kein Fragebogen ermittelt werden. Bitte einen Fragebogen in KuferSQL anlegen. ', 100);
      $this->feedbackBogenError = true;
    }
  }

  abstract protected function getBogenTyp();

  abstract protected function getRechteKey();

  abstract protected function getForwardBackwardLink();

  abstract protected function getBackToStartLink();

  public function hasAccess($pToolSectionId = null)
  {
    if (!parent::hasAccess()) {
      return false;
    }
    if (!$this->isRechtAllowed($this->getRechteKey())) {
      return false;
    }

    return true;
  }

  public function action()
  {
    $feedbackObj = $this->getFeedbackObj();

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

  private function getFeedbackObj()
  {
    $feedbackObj = $this->createFeedBackObj($this->getToolId(), $this->AktKurs);
    $feedbackObj->vorspann = 'Feedback zum Kurs ' . $this->AktKurs->nr_anzeige;

    
    if ($this->feedbackBogenError) {
      return $feedbackObj;
    }

    if ($this->feedbackbogenBereitsGesendet()) {
      $feedbackObj->advanceState = 'fragenErfasst';

      return $feedbackObj;
    }
    if (!$this->feedbackfragenForFeedbackbogenVorhanden()) {
      $feedbackObj->advanceState = 'keineFragen';

      return $feedbackObj;
    }

    $feedbackObj->bogenId = $this->fragebogen->id;
    $feedbackObj->fragenCount = $this->fragenCount;
    $feedbackObj->forwardLink = $this->getForwardBackwardLink();
    $feedbackObj->backwardLink = $this->getForwardBackwardLink();
    $feedbackObj->vorspann = $this->getVorspann();
    $feedbackObj->nachspann = $this->getNachspann();

    if ($this->isFirstPage()) {
      $feedbackObj = $this->setFirstPageAttributes($feedbackObj);
    } elseif ($this->isNeitherFirstOrLastPage()) {
      $feedbackObj = $this->setPageAttributes($feedbackObj);
    } else {
      $feedbackObj = $this->setLastPageAttributes($feedbackObj);
    }

    return $feedbackObj;
  }

  private function setFirstPageAttributes($feedbackObj)
  {
    $feedbackObj->advanceState = 'fragenStart';
    $feedbackObj->frageNrForward = 1;
    $feedbackObj->frageNrBackward = '';
    $feedbackObj->aktuelleSeite = 1;

    $this->setSessionVarsForFirstPage($feedbackObj);

    return $feedbackObj;
  }

  private function setPageAttributes($feedbackObj)
  {
    $feedbackObj->advanceState = 'fragenHandle';
    $feedbackObj->frageNrForward = $this->request->frageNr + 1;
    $feedbackObj->frageNrBackward = $this->request->frageNr > 1 ? $this->request->frageNr - 1 : '';
    $feedbackObj->aktuelleSeite = $this->request->frageNr + 1;
    $feedbackObj = $this->setAntwort2FeedbackObj($feedbackObj);
    $feedbackObj = $this->setAktuelleFrageToObject($feedbackObj);

    $this->setSessionVarsForPage($feedbackObj);

    return $feedbackObj;
  }

  private function setLastPageAttributes($feedbackObj)
  {
    $feedbackObj->advanceState = 'fragenEnde';
    $feedbackObj->forwardLink = $this->getFormularSendAction();
    $feedbackObj->frageNrForward = '';
    $feedbackObj->frageNrBackward = $this->fragenCount;
    $feedbackObj->aktuelleSeite = $this->request->frageNr + 1;

    $this->setSessionVarsForLastPage($feedbackObj);

    return $feedbackObj;
  }

  private function isFirstPage()
  {
    return empty($this->request->frageNr);
  }

  private function isNeitherFirstOrLastPage()
  {
    return $this->request->frageNr <= $this->fragenCount;
  }

  private function feedbackbogenBereitsGesendet()
  {
    $anzGesendeteFeedBackBoegen = $this->getAnzahlGesendeteFeedbackBoegen($this->AktKurs->id, $this->fragebogen->id);

    return $anzGesendeteFeedBackBoegen > 0;
  }

  private function feedbackfragenForFeedbackbogenVorhanden()
  {
    return $this->fragenCount > 0;
  }

  private function setAktuelleFrageToObject($feedbackObj)
  {
    if ($this->fragenCount > 0) {
      $aktBogenFragenObj = $this->fragen4Bogen[$this->request->frageNr - 1];
      $feedbackObj = $this->setFragen2FeedbackObject($feedbackObj, $aktBogenFragenObj);
    }

    return $feedbackObj;
  }

  private function getVorspann()
  {
    if (!empty($this->fragebogen->vorspann)) {
      return $this->fragebogen->vorspann;
    } else {
      return 'Feedback zum Kurs ' . $this->AktKurs->nr_anzeige;
    }
  }

  private function getNachspann()
  {
    if (!empty($this->fragebogen->nachspann)) {
      return $this->fragebogen->nachspann;
    } else {
      return 'Feedback zum Kurs ' . $this->AktKurs->nr_anzeige . ' abgeschlossen. Danke';
    }
  }

  private function setSessionVarsForFirstPage($feedbackObj)
  {
    if (isset($this->request->direction) && $this->request->direction == 'backward') {
      FeedbackHelper::getFeedbackRequest2Session($feedbackObj, $this->request);
    } else {
      FeedbackHelper::initFeedbackSessionVars($feedbackObj, $this->fragebogen, $this->fragen4Bogen);
    }
  }

  private function setSessionVarsForPage($feedbackObj)
  {
    FeedbackHelper::getFeedbackRequest2Session($feedbackObj, $this->request);
  }

  private function setSessionVarsForLastPage($feedbackObj)
  {
    if (isset($this->request->direction) && $this->request->direction == 'forward') {
      FeedbackHelper::getFeedbackRequest2Session($feedbackObj, $this->request);
    }
  }

  protected function shouldOnlyUseWebDatabase(): bool
  {
    $connInfo = new \DBConnectionInfo();
    $tool0Settings = \ToolSettingsAPI::getToolSettings(0);

    return ($tool0Settings->useFeedbackOnlyInReplikatsDb ?? false)
      && $connInfo->db_replikat
      && $connInfo->db_typ == \DBTypeEnum::MYSQLI;
  }

  
  protected function getAnzahlGesendeteFeedbackBoegen($pKursNr, $pBogenId = 0)
  {
    
    
    $dbwFeedBackGedruckt = $this->shouldOnlyUseWebDatabase() ? new \DBWorkFeedBackGedruckt2() : new \DBWorkFeedBackGedruckt();

    return $dbwFeedBackGedruckt->getCountFeedBackGedruckt($pKursNr, $this->getBogenTyp(), $this->userNr);
  }

  
  protected function getFormularSendAction()
  {
    $xsrf = new \Xsrf();
    $xsrfKey = $xsrf->generateKey4Action('sendFeedbackBogenFragen', $this->request->knr);
    
    return 'index.php?tool_id=' . $this->getToolId() . '&amp;action=sendFeedbackBogenFragen&amp;knr=' . $this->request->knr . '&amp;xsrf=' . $xsrfKey;
  }

  private function createFeedBackObj($pToolId, $pKurs)
  {
    $feedbackObj = new \stdClass();
    $feedbackObj->kurs = $pKurs;
    $feedbackObj->bogenId = '';
    $feedbackObj->fragenCount = 0;
    $feedbackObj->advanceState = '';
    $feedbackObj->toolId = $pToolId;
    $feedbackObj->aktuelleSeite = '';
    $feedbackObj->forwardLink = '';
    $feedbackObj->backwardLink = '';
    $feedbackObj->frageNrForward = '';
    $feedbackObj->frageNrBackward = '';
    $feedbackObj->backToStartLink = $this->getBackToStartLink();
    
    $feedbackObj->feedbackBogenError = $this->feedbackBogenError;

    return $this->addFeedbackFragenAttributes($feedbackObj);
  }

  private function addFeedbackFragenAttributes($feedbackObj)
  {
    $feedbackObj->vorspann = '';
    $feedbackObj->nachspann = '';
    $feedbackObj->aktfrage = '';
    $feedbackObj->anzeigeTextAry = array();
    $feedbackObj->bogenAnzeigeText = '';
    $feedbackObj->ausgabeTyp = '';
    $feedbackObj->inputAntwortWert = '';
    $feedbackObj->bemerkungsAntwort = '';
    
    $feedbackObj->isInline = false;

    return $feedbackObj;
  }

  
  private function setAntwort2FeedbackObj($pFeedbackObj)
  {
    $feedBackAntworten = \SessionOperations::getVarValueWTIntern('feedback_Antworten');
    if (isset($this->request->frageNr)) {
      $feedBackBogenFrage = unserialize(\SessionOperations::getVarValueWTIntern('feedback_Frage_' . $this->request->frageNr));
      
      
      if (array_key_exists($feedBackBogenFrage->id, $feedBackAntworten)) {
        $aktAntwort = $feedBackAntworten[$feedBackBogenFrage->id];
        if (isset($aktAntwort['warum'])) {
          $pFeedbackObj->bemerkungsAntwort = $aktAntwort['warum'];
        }
        $pFeedbackObj->inputAntwortWert = $aktAntwort['wert'];
      }
    }

    return $pFeedbackObj;
  }

  private function setFragen2FeedbackObject($pFeedbackObj, $pBogenFragenObj)
  {
    $pFeedbackObj->bogenAnzeigeText = $pBogenFragenObj->anzeigetext;
    $aktFrage = $pBogenFragenObj->feedbackfrage;

    $anzeigeTextAry = array();
    
    
    $anzeigeTextMaxLen = $aktFrage->anzeigeanzahl;
    
    $anzeigeTextLen = min(count($aktFrage->anzeigetexte), $anzeigeTextMaxLen);
    $anzeigeTyp = $aktFrage->typ;

    
    
    $antwortWert = $pFeedbackObj->inputAntwortWert;
    if (!is_array($antwortWert)) {
      $antwortWert = array($antwortWert);
    }
    if ($anzeigeTextLen > 0 && !$this->isInputTextTyp($anzeigeTyp)) {
      for ($i = 0; $i < $anzeigeTextLen; $i++) {
        $anzeigeText = new class() extends \Datamodul {
          public $anzeigeWert;
          public $anzeigeText;
          public $anzeigeChecked;
        };
        
        $singleRadioInhalt = $aktFrage->anzeigetexte[$i];
        
        $singleRadioInhalt = preg_replace('/^\\s*\\d+\\s*-\\s*/', '', $singleRadioInhalt);

        
        $anzeigeText->anzeigeWert = $i + 1;
        $anzeigeText->anzeigeText = trim($singleRadioInhalt); 
        $anzeigeText->anzeigeChecked = '';
        if (in_array($anzeigeText->anzeigeWert, $antwortWert)) {
          $anzeigeText->anzeigeChecked = 'checked="checked"';
        }
        $anzeigeTextAry[$i] = $anzeigeText;
      }
      if ($this->isRadioTyp($anzeigeTyp)) {
        $ausgabeTyp = 'radio';
        if ($anzeigeTyp == FEEDBACK_PUNKTE) { 
          $anzeigeTextAry = array_map(static function($i) use ($antwortWert) {
            $anzeigeText = new class() extends \Datamodul {
              public $anzeigeWert;
              public $anzeigeText;
              public $anzeigeChecked;
            };

            $anzeigeText->anzeigeWert = 10 - $i + 1;
            $anzeigeText->anzeigeText = '' . (10 - $i + 1);
            $anzeigeText->anzeigeChecked = '';
            if (in_array($anzeigeText->anzeigeWert, $antwortWert)) {
              $anzeigeText->anzeigeChecked = 'checked="checked"';
            }

            return $anzeigeText;
          }, range(1, 10));
        } elseif ($anzeigeTyp == FEEDBACK_NOTEN) { 
          $anzeigeTextAry = array_map(static function($i) use ($antwortWert) {
            $anzeigeText = new class() extends \Datamodul {
              public $anzeigeWert;
              public $anzeigeText;
              public $anzeigeChecked;
            };

            $anzeigeText->anzeigeWert = $i;
            $anzeigeText->anzeigeText = '' . $i;
            $anzeigeText->anzeigeChecked = '';
            if (in_array($anzeigeText->anzeigeWert, $antwortWert)) {
              $anzeigeText->anzeigeChecked = 'checked="checked"';
            }

            return $anzeigeText;
          }, range(1, 6));
        } elseif ($anzeigeTyp == FEEDBACK_JA_NEIN) {
          $anzeigeTextAry = array_map(static function($i) use ($antwortWert) {
            $anzeigeText = new class() extends \Datamodul {
              public $anzeigeWert;
              public $anzeigeText;
              public $anzeigeChecked;
            };

            $anzeigeText->anzeigeWert = $i;
            $anzeigeText->anzeigeText = $i === 1 ? 'Ja' : 'Nein';
            $anzeigeText->anzeigeChecked = '';

            if (in_array($anzeigeText->anzeigeWert, $antwortWert)) {
              $anzeigeText->anzeigeChecked = 'checked="checked"';
            }

            return $anzeigeText;
          }, range(1, 2));
        }
      } elseif ($this->isCheckBoxTyp($anzeigeTyp)) {
        $ausgabeTyp = 'checkbox';
      }
      
      $pFeedbackObj->isInline = $this->isInlineArrangement($anzeigeTyp, $ausgabeTyp ?? '');
    } else {
      
      $anzeigeText = new \Datamodul();
      $anzeigeText->inputText = $aktFrage->anzeigetexte[0];
      $anzeigeTextAry[0] = $anzeigeText;
      $ausgabeTyp = 'textinput';
    }
    $pFeedbackObj->aktfrage = $aktFrage;
    $pFeedbackObj->anzeigeTextAry = $anzeigeTextAry;
    
    $pFeedbackObj->ausgabeTyp = $ausgabeTyp;

    return $pFeedbackObj;
  }

  
  private function isRadioTyp($pTyp)
  {
    $radioTypAry = array(1, 4, 5, 6, 7);

    return in_array($pTyp, $radioTypAry);
  }

  
  private function isInlineArrangement($pTyp, $pAusgabeTyp)
  {
    if ($pAusgabeTyp === 'radio') {
      $inlineTypAry = array(1, 4, 5, 6);
    } else {
      $inlineTypAry = array(2);
    }

    return in_array($pTyp, $inlineTypAry);
  }

  
  private function isCheckBoxTyp($pTyp)
  {
    $checkBoxTypAry = array(2, 3);

    return in_array($pTyp, $checkBoxTypAry);
  }

  
  private function isInputTextTyp($pTyp)
  {
    $inputTextTypAry = array(0);

    return in_array($pTyp, $inputTextTypAry);
  }

  
  private function getFrageBogen($pKurs)
  {
    
    
    return \FeedBackAPI::getFrageBogen($pKurs, $this->toolSettings->includeSubFachbereich, $this->getBogenTyp());
  }

  
  private function getFeedbackBogenFragen($pBogenId)
  {
    
    

    $dbwBogenFragen = new \DBWorkFeedBackBogenFragen();

    return $dbwBogenFragen->getFeedBackFragenByBogenID($pBogenId);
  }

  protected function getResponse($pFeedBackObj)
  {
    $this->handleResponseStrategies();
    $this->response->kurs = $pFeedBackObj->kurs;
    $this->response->toolId = $pFeedBackObj->toolId;
    $this->response->advanceState = $pFeedBackObj->advanceState;
    $this->response->backwardLink = $pFeedBackObj->backwardLink;
    $this->response->forwardLink = $pFeedBackObj->forwardLink;

    
    $this->response->backToStartLink = $pFeedBackObj->backToStartLink;

    $this->response->frageNrForward = $pFeedBackObj->frageNrForward;
    $this->response->frageNrBackward = $pFeedBackObj->frageNrBackward;

    $this->response->fragenCount = $pFeedBackObj->fragenCount;
    $this->response->aktuelleSeite = $pFeedBackObj->aktuelleSeite;
    
    $this->response->anzahlSeiten = $pFeedBackObj->fragenCount + 2;

    
    $this->response->vorspann = $pFeedBackObj->vorspann;
    $this->response->nachspann = $pFeedBackObj->nachspann;

    $this->response->bogenId = $pFeedBackObj->bogenId;
    $this->response->aktfrage = $pFeedBackObj->aktfrage;
    $this->response->anzeigeTextAry = $pFeedBackObj->anzeigeTextAry;
    $this->response->bogenAnzeigeText = $pFeedBackObj->bogenAnzeigeText;
    $this->response->ausgabeTyp = $pFeedBackObj->ausgabeTyp;
    
    $this->response->isInline = $pFeedBackObj->isInline;
    $this->response->bemerkungsAntwort = $pFeedBackObj->bemerkungsAntwort;
    
    
    $this->response->inputAntwortWert = $pFeedBackObj->inputAntwortWert;
    $this->response->feedbackBogenError = $pFeedBackObj->feedbackBogenError;

    return $this->response;
  }

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

class FeedbackBogenRequest
{
  public $knr;
  public $frageNr;
  public $direction;
  public $feedback_bemerkung;
  public $feedback_input;
}

class FeedbackBogenResponse extends \Kufer\KuferTools\Basis\UseCase\ToolResponse
{
  public $kurs;
  public $fragenCount;
  public $bogenId;
  public $advanceState;
  public $backwardLink;
  public $forwardLink;
  public $backToStartLink;
  public $vorspann;
  public $nachspann;
  public $aktuelleSeite;
  public $anzahlSeiten;
  public $aktfrage;
  public $anzeigeTextAry;
  public $bogenAnzeigeText;
  public $ausgabeTyp;
  public $itemsInline;
  public $bemerkungsAntwort;
  public $inputAntwortWert;
  
  public $feedbackBogenError;
}