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

namespace Kufer\KuferTools\Basis\Feedbackauswertung\FeedbackAuswertungenUebersicht;

abstract class FeedbackAuswertungenUebersichtUseCase extends \Kufer\KuferTools\Basis\UseCase\ToolUseCase
{
  public function __construct($request)
  {
    parent::__construct($request, new FeedbackAuswertungenUebersichtResponse());
  }

  public function hasAccess($pToolSectionId = null)
  {
    if (!parent::hasAccess()) {
      return false;
    }

    return true;
  }

  public function action()
  {
    return $this->getResponse();
  }

  protected function getResponse()
  {
    $this->handleResponseStrategies();

    $this->response->referrer = $this->request->referrer;
    $this->response->referrerLabel = $this->request->referrerLabel;

    $dbwFeedBackRetour = $this->createDBWFeedBackRetour();
    if (count($this->getFeedbackGedrucktByKnrs($dbwFeedBackRetour)) > 0) {
      $fragenDataAry = $this->getFeedBackFragenAufBogen($dbwFeedBackRetour);

      $this->response->bogenDetailsAry = $this->getFeedBackBogenByBogenIds($dbwFeedBackRetour);

      foreach ($fragenDataAry as $bogenFrage) {
        if (!isset($this->response->bogenDetailsAry[$bogenFrage->bogenid]->feedbackBogenFragen)) {
          $this->response->bogenDetailsAry[$bogenFrage->bogenid]->feedbackBogenFragen = array();
        }
        $this->response->bogenDetailsAry[$bogenFrage->bogenid]->feedbackBogenFragen[] = $bogenFrage;
      }

      $this->response->countAntwortFragenAry = $this->getCountAntworten($dbwFeedBackRetour);
    } else {
      $this->response->noData = true;
    }

    $this->response->buttons = $this->getButtons();

    return $this->response;
  }

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

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

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

  private function createDBWFeedBackRetour(): \DBWorkFeedBackRetour
  {
    if ($this->shouldOnlyUseWebDatabase()) {
      return \DBWorkFeedBackRetour2::getDefaultInstance(1, true);
    } else {
      return \DBWorkFeedBackRetour::getDefaultInstance(1, true);
    }
  }

  private function initDBWFeedbackBogenFragen(): \DBWorkFeedBackBogenFragen
  {
    return \DBWorkFeedBackBogenFragen::getDefaultInstance(1, true);
  }

  private function initDBWFeedbackBogen(): \DBWorkFeedBackBogen
  {
    return \DBWorkFeedBackBogen::getDefaultInstance(1, true);
  }

  private function getBogenIds(\DBWorkFeedBackRetour $dbwFeedBackRetour)
  {
    static $bogenIds = null;
    if (!isset($bogenIds)) {
      $feedbackRetourByFeedbackGedrucktArry = $this->getFeedbackRetourByFeedbackGedruckt($dbwFeedBackRetour);
      $bogenIds = \ArrayOperations::mapAttribut($feedbackRetourByFeedbackGedrucktArry, 'bogenid');
      $bogenIds = array_unique($bogenIds);
    }

    return $bogenIds;
  }

  private function getFeedBackFragenAufBogen(\DBWorkFeedBackRetour $dbwFeedBackRetour)
  {
    $bogenIds = $this->getBogenIds($dbwFeedBackRetour);

    $dbWorkFeedbackBogenFragen = $this->initDBWFeedbackBogenFragen();
    $result = $dbWorkFeedbackBogenFragen->getFeedBackBogenFragenByBogenIDs($bogenIds);

    $result = array_filter($result, function($bogenFrage) { return $bogenFrage->frageid > 0;});

    return $this->updateAntwortMoeglichkeiten($result);
  }

  private function updateAntwortMoeglichkeiten($pFeedbackBogenFragen)
  {
    foreach ($pFeedbackBogenFragen as $feedbackBogenFrage) {
      if ($feedbackBogenFrage->feedbackfrage->typ === FEEDBACK_NOTEN) {
        $feedbackBogenFrage->feedbackfrage->anzeigetexte = $this->getAntworten4FeedbackNoten();
      } elseif ($feedbackBogenFrage->feedbackfrage->typ === FEEDBACK_JA_NEIN) {
        $feedbackBogenFrage->feedbackfrage->anzeigetexte = array('Ja', 'Nein');
      } elseif ($feedbackBogenFrage->feedbackfrage->typ === FEEDBACK_PUNKTE) {
        $feedbackBogenFrage->feedbackfrage->anzeigetexte = $this->getAntworten4FeedbackPunkte();
      }
    }

    return $pFeedbackBogenFragen;
  }

  private function getAntworten4FeedbackNoten()
  {
    return range(1, 6);
  }

  private function getAntworten4FeedbackPunkte()
  {
    return range(1, 10);
  }

  
  private function getFeedBackBogenByBogenIds(\DBWorkFeedBackRetour $dbwFeedBackRetour)
  {
    $bogenIds = $this->getBogenIds($dbwFeedBackRetour);

    $dbWorkFeedbackBogen = $this->initDBWFeedbackBogen();
    $result = $dbWorkFeedbackBogen->getFeedBackBogenByBogenIDs($bogenIds);

    return \ArrayOperations::setAttributAsKey($result, 'id');
  }

  private function correctAnzeigeIds($FeedBackFragen)
  {
    foreach ($FeedBackFragen as $feedbackfrage) {
      $anzeigetexte = $feedbackfrage->anzeigetexte;
      $newanzeigetexte = array();
      foreach ($anzeigetexte as $key => $anzeigetext) {
        $anzeigetext = \trim($anzeigetext);
        if (\preg_match('&^[0-9] - &', $anzeigetext) === 1) {
          $newkey = (int)\explode(' ', $anzeigetext, 2)[0];
          $newanzeigetexte[$newkey] = $anzeigetext;
        } else {
          $newanzeigetexte[$key + 1] = $anzeigetext;
        }
      }
      $feedbackfrage->anzeigetexte = $newanzeigetexte;
    }
  }

  
  private function getCountAntworten(\DBWorkFeedBackRetour $dbwFeedBackRetour)
  {
    $countAry = array();
    $fragenRetourDetailsAry = $this->getFeedBackRetourDetailsByFeedbackRetour($dbwFeedBackRetour);

    $feedBackFragenAufBogenArry = \ArrayOperations::setAttributAsKey(
      \ArrayOperations::mapAttribut($this->getFeedBackFragenAufBogen($dbwFeedBackRetour), 'feedbackfrage'),
      'id'
    );
    $this->correctAnzeigeIds($feedBackFragenAufBogenArry);

    foreach ($fragenRetourDetailsAry as $fragenRetour) {
      $anzeigetexte = $feedBackFragenAufBogenArry[$fragenRetour->frageid]->anzeigetexte;
      $anzeigeanzahl = $feedBackFragenAufBogenArry[$fragenRetour->frageid]->anzeigeanzahl;
      $antwortmoeglichkeit = $anzeigetexte[$fragenRetour->wert] ?? 'n/a';

      $wertAnwortmoeglichkeit = $fragenRetour->wert;
      if (!isset($countAry[$fragenRetour->bogenfragenid . '_' . $wertAnwortmoeglichkeit])) {
        $countAry[$fragenRetour->bogenfragenid . '_' . $wertAnwortmoeglichkeit] = 0;
      }
      if (!isset($countAry[$fragenRetour->bogenfragenid])) {
        $countAry[$fragenRetour->bogenfragenid] = 0;
      }
      $countAry[$fragenRetour->bogenfragenid . '_' . $wertAnwortmoeglichkeit] += 1;
      $countAry[$fragenRetour->bogenfragenid] += 1;


      $antwort = \trim($fragenRetour->antwort);
      if ($antwort !== '') {
        $antwort = '<div class="col-sm-8 feedbackbogenbemerkung">' . \CleanOperations::cleanStringForHtml($antwort) . '</div>';
        if ($anzeigeanzahl > 0) {
          $antwort .= '<span class="col-sm-4 feedbackbogenbemerkunganw">' . \CleanOperations::cleanStringForHtml('zu ' . $antwortmoeglichkeit) . '</span>';
        }
      }
      if (!isset($countAry[$fragenRetour->bogenfragenid . '_bemerkung']) || $countAry[$fragenRetour->bogenfragenid . '_bemerkung'] === '') {
        $countAry[$fragenRetour->bogenfragenid . '_bemerkung'] = $antwort;
      } elseif ($antwort != '') {
        $countAry[$fragenRetour->bogenfragenid . '_bemerkung'] .= $antwort;
      }
    }

    return $countAry;
  }

  
  private function getFeedBackRetourDetailsByFeedbackRetour(\DBWorkFeedBackretour $dbwFeedBackRetour)
  {
    $retourAry = $this->getFeedbackRetourByFeedbackGedruckt($dbwFeedBackRetour);

    $dbWorkFeedBackRetourDetails = $dbwFeedBackRetour->createDBWorkFeedBackRetourDetails();
    $feedbackRetourIds = \ArrayOperations::mapAttribut($retourAry, 'id');

    return $dbWorkFeedBackRetourDetails->getAllDataByFeedbackRetourID($feedbackRetourIds);
  }

  
  private function getFeedbackRetourByFeedbackGedruckt(\DBWorkFeedBackRetour $dbwFeedBackRetour)
  {
    $feedbackGedrucktByKnrsArry = $this->getFeedbackGedrucktByKnrs($dbwFeedBackRetour);
    $feedbackGedrucktIds = \ArrayOperations::mapAttribut($feedbackGedrucktByKnrsArry, 'id');
    $feedbackRetourArry = $dbwFeedBackRetour->getAllData4FeedbackRetourByGedrucktID($feedbackGedrucktIds);

    return \ArrayOperations::setAttributAsKey($feedbackRetourArry, 'gedrucktid');
  }

  
  protected function getFeedbackGedrucktByKnrs(\DBWorkFeedBackRetour $dbwFeedBackRetour)
  {
    static $cache = null;
    if (!isset($cache)) {
      $alleKurseArry = $this->getAlleKursNummern();
      if (count($alleKurseArry) === 0) {
        $cache = array();
      } else {
        $dbWorkFeedbackgedruckt = $dbwFeedBackRetour->createDBWorkFeedBackGedruckt();
        $cache = $dbWorkFeedbackgedruckt->getAlldataByKnrAndTyp($alleKurseArry, $this->getBogenTyp());
      }
    }

    return $cache;
  }

  abstract protected function getBogenTyp();

  
  protected function getAlleKursNummern()
  {
    static $cache = null;
    if (!isset($cache)) {
      $requestSuchParam = $this->request->suchParameter;
      $requestEinstieg = $this->request->einstieg;
      $kursHelper = \Kufer\KuferTools\Utils\DatamodulHelper\KursHelper\KursHelperFactory::getKursHelperByToolID($this->getToolId(), $this->toolSettings);

      $cache = $kursHelper->getIdsMitFilter($this->getToolId(), $requestSuchParam, $requestEinstieg, false);
    }

    return $cache;
  }

  protected function isFilterGesetzt()
  {
    $suchApi = new \KurssuchAPI();

    return $suchApi->isFilterGesetzt($this->getToolId());
  }

  abstract protected function getUeberschrift();

  
  abstract protected function getButtons();
}

class FeedbackAuswertungenUebersichtRequest extends \Kufer\KuferTools\Basis\Uebersicht\UebersichtMitWssRequest
{
  public $nr;
  public $knrAry;
  public $suchParameter;
  public $einstieg;
  public $isFilterSet = false;
  public $referrer;
  public $referrerLabel;
}

class FeedbackAuswertungenUebersichtResponse extends \Kufer\KuferTools\Basis\Uebersicht\UebersichtMitWssResponse
{
  public $noData = false;
  public $bogenDetailsAry;
  public $countAntwortFragenAry;
  public $buttons;
  public $ueberschrift;
  public $referrer;
  public $referrerLabel;
}