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

namespace Kufer\KuferTools\Mitarbeiter\AdressInfo\UpdateAdress\HandleAdressUpdate;

class HandleAdressUpdateUseCase extends \Kufer\KuferTools\Basis\UseCase\ToolUseCase
{
  public const SUCCESS_ADRESS_ERFOLGREICH_UEBERMITTELT = 'adressdatenErfolgreichÜbermittelt';
  public const INFO_ADRESSEDATEN_NICHT_VERAENDERT = 'adressdatenNichtVerändert';
  public const ERROR_DOPPELT_AUFGERUFEN = 'doppeltAufgerufen';
  public const ERROR_UEBERTRAGUNG_FEHLGESCHLAGEN = 'übertragungFehlgeschlagen';
  public const ERROR_ADRESS_NICHT_ANGELEGT = 'adressNichtAngelegt';
  public const ERROR_ADRESSDATEN_NICHT_AKTUELL = 'adressdatenNichtAktuell';
  public const ERROR_ADRESSDATEN_FEHLERHAFT = 'adressdatenFehlerhaft';

  public function __construct($request)
  {
    parent::__construct($request, new HandleAdressUpdateResponse());
  }

  public static function getToolSectionId()
  {
    return 58;
  }

  public static function getToolId()
  {
    return \ToolsAPI::TOOL_ADRESSINFO_MA;
  }

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

    if (empty(\DBWorkAdresse::getDefaultInstance()->getAdresse($this->getRequestedIdentifier())->id)) {
      return false;
    }
    
    
    
    return true;
  }

  protected function getRequestedId()
  {
    return $this->request->anr;
  }

  protected function getRequestedGuid(): ?\Kufer\Web\Classes\Addfunctions\Guid
  {
    return !empty($this->request->aguid) ? new \Kufer\Web\Classes\Addfunctions\Guid($this->request->aguid) : null;
  }

  protected function getRequestedIdentifier(): ?\Kufer\Web\Classes\Identifier\Identifier
  {
    return new \Kufer\Web\Classes\Identifier\Identifier($this->getRequestedId(), $this->getRequestedGuid());
  }

  public function action()
  {
    list($statusCode, $anr, $wrongFields) = array_values($this->handleAdressUpdate());
    \SessionOperations::setVarValueWTIntern('newAdrStatusCode', $statusCode);
    \SessionOperations::setVarValueWTIntern('newAdrWrongFields', $wrongFields);

    return $this->getResponse($anr, $this->request->aguid);
  }

  
  protected function transformColumnValues($columnValues)
  {
    return $columnValues;
  }

  
  protected function preAdressUpdateHook($adresse, $changedFields)
  {
    $kennung = $this->getMitarbeiterKennung();
    if (!empty($kennung)) {
      $adresse->bearbeiter = $kennung;
      $changedFields[] = 'bearbeiter';
    }

    return array($adresse, $changedFields);
  }

  private function getMitarbeiterKennung(): string
  {
    return \SessionOperations::getCurrentWebToolsMitarbeiterOrEmpty()->kennung;
  }

  
  private function handleAdressUpdate()
  {
    $dbwAdresse = new \DBWorkAdresse();
    
    if ($this->request->adressUpdate) {
      $origAdress = $dbwAdresse->getAdresse($this->getRequestedIdentifier(), true);
    } else {
      throw new \Exception('Fehler: Adress neu anlegen oder bearbeiten nicht angegeben!');
    }
    $columnValues = $this->transformColumnValues($this->request->columnValues);
    $changedAdress = $this->request->wssHandler->getChangedDm($origAdress, $columnValues);
    $changedFields = $this->request->wssHandler->getChangedFieldnames($origAdress, $columnValues);
    
    $wrongFields = $this->request->wssHandler->checkColumnValues($columnValues);
    if (count($wrongFields) > 0) {
      $statusCode = self::ERROR_ADRESSDATEN_FEHLERHAFT;
      $anr = $this->request->anr;
    } else {
      list($changedAdress, $changedFields) = $this->preAdressUpdateHook($changedAdress, $changedFields);
      list($statusCode, $anr) = array_values($this->saveAdress($origAdress, $changedAdress, $changedFields));
    }

    return array($statusCode, $anr, $wrongFields);
  }

  
  private function saveAdress($pOrigAdress, $pAdress, $pChangedFields)
  {
    $statusCode = '';
    $dbwAdresse = new \DBWorkAdresse(1, true);
    $adressAndChangedFields = self::aktualisiereBerechneteAdressDaten($pOrigAdress, $pAdress);
    $pAdress = $adressAndChangedFields['adresse'];
    $pChangedFields = array_merge($pChangedFields, $adressAndChangedFields['changedFields']);
    
    $pChangedFields = array_merge($pChangedFields, $pAdress->getKommAnzeigeAry($pOrigAdress));
    if (count($pChangedFields) == 0) {
      $statusCode .= self::INFO_ADRESSEDATEN_NICHT_VERAENDERT;

      return array('statusMessage' => $statusCode, 'dozId' => $this->request->anr);
    } 

    $insertedAdrId = $this->request->anr;
    try {
      if (\SessionOperations::isDmzBetrieb()) {
        
        
        $correctMode = 'update';
        
        
        $pAdress->updateKommAnzeige();
        $adressTuple = new \Tuple($pAdress, $pChangedFields, $pOrigAdress);
        \AdressAPI::correctAdresse($adressTuple, $correctMode);
        
        
        
        $origKommAry = \KommunikationsAPI::getOrigKommunikation($pAdress);

        
        
        $pAdress = $dbwAdresse->updateAdresse($pAdress, true);
        
        
        \KommunikationsAPI::buildAndSendKommunikation($pAdress, $origKommAry);
        $insertedAdrId = $pAdress->id;
      } 
      
      else {
        
        
        $dbwAdresse->updateAdresse($pAdress, false);
      }
      $statusCode .= self::SUCCESS_ADRESS_ERFOLGREICH_UEBERMITTELT;
    } 
    catch (\AbgleichApiException $aae) {
      \Logger::logg('Adresskorrektur - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);

      if ($aae->errorType == \AbgleichApiResult::CONFLICT) {
        $statusCode .= self::ERROR_ADRESSDATEN_NICHT_AKTUELL;
      } else {
        $statusCode .= self::ERROR_UEBERTRAGUNG_FEHLGESCHLAGEN;
      }
    }
    
    
    catch (\Exception $e) {
      $statusCode .= self::INFO_ADRESSEDATEN_NICHT_VERAENDERT;
      \Logger::logg('Adresskorrektur - folgende Exception ist aufgetreten: ' . $e->getMessage() . "\n" . ' [' . $e->getTraceAsString() . ']', 200);
    }

    return array('statusMessage' => $statusCode, 'adrId' => $insertedAdrId);
  }

  
  private static function aktualisiereBerechneteAdressDaten($pOrigAdresse, $pAdresse)
  {
    $changedFields = array();
    if (\StringOperations::substr(\StringOperations::strtoupper($pOrigAdresse->name), 0, 16) == $pAdresse->suchbegriff) {
      $pAdresse->suchbegriff = \StringOperations::substr(\StringOperations::strtoupper($pAdresse->name), 0, 16); 
      $changedFields[] = 'suchbegriff';
    }

    if ($pOrigAdresse->ansprache !== '' && $pOrigAdresse->ansprache == $pAdresse->ansprache) {
      $pAdresse->ansprache = str_replace($pOrigAdresse->name, $pAdresse->name, $pAdresse->ansprache);
      $pAdresse->ansprache = str_replace($pOrigAdresse->vorname, $pAdresse->vorname, $pAdresse->ansprache);
      $changedFields[] = 'ansprache';
    }

    return array('adresse' => $pAdresse, 'changedFields' => $changedFields);
  }

  protected function getResponse($anr, $aguid)
  {
    $this->response->anr = $anr;
    $this->response->aguid = $aguid;

    return $this->response;
  }
}

class HandleAdressUpdateRequest
{
  public $anr;
  public $aguid;
  public $adressUpdate;
  public $columnValues;
  public $wssHandler;
}

class HandleAdressUpdateResponse extends \Kufer\KuferTools\Basis\UseCase\ToolResponse
{
  public $anr;
  public $aguid;
}