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

namespace Kufer\Web\KuferTools\Basis\Kursdetails\DetailsReiter\Teilnehmer\SammelEinzelBearbeitung;

use Kufer\KuferTools\Basis\UseCase\BasisResponse;
use Kufer\KuferTools\Utils\ResponseStrategies\ResponseMitRahmen;
use Kufer\KuferTools\Utils\ResponseStrategies\ResponseWssSammelEinzelnFormularStrategy;
use Kufer\KuferTools\Utils\ResponseStrategies\SammelEinzelnFormularResponse;
use Kufer\KuferTools\Utils\WssHandler;

abstract class HandleSammelEinzelBearbeitungUseCase extends \Kufer\KuferTools\Basis\UseCase\EinzelKursUseCase
{
  public const STATUS_UNKNOWN = 0;
  public const STATUS_SUCCESS = 1;
  public const STATUS_DMZ_ERROR = 2;
  public const STATUS_FORM_ERROR = 3;

  public function __construct($request, $response = null)
  {
    parent::__construct($request, $response ?? new HandleSammelEinzelBearbeitungResponse());
  }

  public function hasAccess($pToolsectionId = null)
  {
    if (!is_array($this->request->belids)) {
      return false;
    }

    if (!parent::hasAccess($pToolsectionId)) {
      return false;
    }

    if (!$this->request->isXsrfOk && !$this->request->isRefresh) {
      return false;
    }

    if (empty($this->request->belids)) {
      return false;
    }

    $alleIds = $this->getBelegungenIdsOhneFilter();
    foreach ($this->request->belids as $tnr) {
      if (!in_array($tnr, $alleIds)) {
        return false;
      }
    }

    return true;
  }

  public function action()
  {
    $this->handleResponseStrategies();

    $this->response->kurs = $this->getKurs($this->getRequestedId());

    $this->response->referer = $this->getBackLink();
    $this->response->refererLabel = $this->getBackButtonLabel();

    $this->response->status = static::STATUS_SUCCESS;

    $this->saveBelegungen();

    return $this->response;
  }

  private function saveBelegungen()
  {
    $this->response->status = self::STATUS_SUCCESS;
    $statusAndBelegungen = array_map(function(\Belegung $origBelegung) {
      $cacheKey = $origBelegung->getIdentifier()->getCacheKey();
      $columnValues = $this->request->columnValuesMap[$origBelegung->id];
      $changedBelegung = $this->request->wssHandler->getChangedDm($origBelegung, $columnValues, $cacheKey);
      $changedFields = $this->request->wssHandler->getChangedFieldnames($origBelegung, $columnValues, $cacheKey);
      $wrongFields = $this->request->wssHandler->checkColumnValues($columnValues, $cacheKey);

      if (count($wrongFields) > 0) {
        $this->response->status = self::STATUS_FORM_ERROR;

        return array(false, $changedBelegung);
      }

      if (!empty($changedFields)) {
        $success = $this->saveBelegung($origBelegung, $changedBelegung, $changedFields);

        if ($success) {
          return array(true, $changedBelegung);
        } else {
          $this->response->status = self::STATUS_DMZ_ERROR;

          return array(false, $changedBelegung);
        }
      } else {
        return array(false, $changedBelegung);
      }
    }, $this->getBelegungen());

    $this->response->datamoduls = array();
    foreach ($statusAndBelegungen as $statusAndBelegung) {
      list($status, $belegung) = $statusAndBelegung;
      $this->response->datamoduls[] = $belegung;
    }
  }

  
  private function saveBelegung($origBelegung, $changedBelegung, $changedFields)
  {
    if (count($changedFields) === 0) {
      return true;
    }

    return \BelegungAPI::updateBelegung($changedBelegung, $origBelegung);
  }

  protected function getBackLink(): string
  {
    return 'index.php?tool_id=' . $this->getToolId() . '&action=kursdetails&knr=' . $this->request->knr . '#reiterTeilnehmer';
  }

  protected function getBackButtonLabel(): string
  {
    return 'Zurück';
  }

  abstract public static function getDescriptionToolSectionId(): int;

  abstract public static function getFormToolSectionId(): int;

  protected function getResponseStrategies()
  {
    return array_merge(
      parent::getResponseStrategies(),
      array(
        new ResponseMitRahmen($this),
        new ResponseWssSammelEinzelnFormularStrategy(
          $this,
          $this->getDescriptionToolSectionId(),
          $this->getFormToolSectionId(),
          $this->getBelegungen()
        )
      )
    );
  }

  
  protected function getBelegungen(): array
  {
    return $this->getBelegungsHelper($this->getKurs($this->getRequestedId()))->getDatamoduleByIds($this->getBelegungenIds());
  }

  
  protected function getBelegungenIds(): array
  {
    return $this->request->belids;
  }

  
  protected function getBelegungenIdsOhneFilter(): array
  {
    return $this->getBelegungsHelper($this->getKurs($this->getRequestedId()))->getIdsOhneFilter();
  }

  protected function getBelegungsHelper(\Kurs $kurs): \Kufer\KuferTools\Utils\DatamodulHelper\BelegungsHelper\BelegungsHelper
  {
    return new \Kufer\KuferTools\Utils\DatamodulHelper\BelegungsHelper\ReiterTeilnehmerBelegungen($this->toolSettings, $this->request, $kurs->id);
  }
}

class HandleSammelEinzelBearbeitungRequest
{
  public $knr;
  public $belids; 
  public $columnValuesMap;
  
  public $wssHandler;
}

class HandleSammelEinzelBearbeitungResponse extends SammelEinzelnFormularResponse
{
  public $kurs;
  public $referer;
  public $refererLabel;
  public $status = HandleSammelEinzelBearbeitungUseCase::STATUS_UNKNOWN;
  public $belegungen = array();
}