<?php

/**
 * Backend API webových stránek RK.
 * Jednotlivé metody by měly odpovídat metodám na vzdáleném serveru.
 * Pro jejich volání je použito XML RPC.
 *
 * @category   Dalten
 * @package    Export
 * @subpackage Api
 */
class Dalten_Export_Api_Backend_Website implements Dalten_Export_Api_Backend_LoggableBackendInterface
{
	/**
	 * Adpatér pro volání metod přes XML RPC.
	 *
	 * @var Serenity_Rpc_XmlRpc
	 */
	protected $_adapter;

	/**
	 * Konstruktor.
	 *
	 * @param Serenity_Rpc_XmlRpc $adapter Adpatér pro volání metod přes XML RPC.
	 */
	public function __construct(Serenity_Rpc_XmlRpc $adapter)
	{
		$this->_adapter = $adapter;
	}


	/**
	 * Získání řetězce, který je použit pro hashování hesla.
	 *
	 * @param string $clientId Uživatelské jméno.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru. (Pod klíčem output klíče sessionId a hashKey.)
	 */
	public function getHash($clientId)
	{
		$response = (array) $this->_adapter->getHash(array('name' => $clientId));
		if (empty($response) || empty($response['output'])) {
			$response['output'] = array(null, null);
		}

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Potvrzení přihlášení.
	 * Heslo se vytvoří pomocí vzorce MD5(MD5('heslo') + hashKey).
	 *
	 * @param string $sessionId   Platné session Id.
	 * @param string $password    Zahashované heslo.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function login($sessionId, $password)
	{
		$response = $this->_adapter->login(
			array('session_id' => (string) $sessionId, 'password' => (string) $password)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Odhlášení.
	 *
	 * @param string $sessionId Platné session Id.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function logout($sessionId)
	{
		return new Dalten_Data_ArrayObject($this->_adapter->logout(array('session_id' => (string) $sessionId)));
	}

	/**
	 * Přidání a nebo úprava uživatele.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param array  $userData  Pole dat o uživateli.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function addUzivatel($sessionId, array $userData) {

		return new Dalten_Data_ArrayObject(
			$this->_adapter->addUzivatel(array('session_id' => $sessionId, 'uzivatel' => $userData))
		);
	}

	/**
	 * Vymazání uživatele.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $userId    Id uživatele.
	 *
	 * @return \Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function delUzivatel($sessionId, $userId)
	{
		return new Dalten_Data_ArrayObject($this->_adapter->delUzivatel(
			array('session_id' => $sessionId, 'uzivatel_id' => (int) $userId)
		));
	}

	/**
	 * Výpis existujících uživatelů.
	 *
	 * Příklad odpovědi:
	 * <code>
	 * array(
	 *     'status': ...,
	 *     'statusMessage': ...,
	 *     'output': (array) ['id1,id2,id3,id4,...,idX']
	 * )
	 * </code>
	 *
	 * @param string $sessionId Platné session Id.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru (s klíči output a count)..
	 */
	public function listUzivatel($sessionId)
	{
		$response = $this->_adapter->listUzivatel(
			array('session_id' => (string) $sessionId)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Přidání a nebo úprava nabídky.
	 *
	 * Pole $advertData má oproti normálním datům nabídky navíc i klíč priloha, obsahující pole řádků fotek.
	 *
	 * @param string $sessionId  Platné session Id.
	 * @param array  $advertData Zkonvertovaná data inzerátu (vč. fotek - viz popis metody).
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function addNabidka($sessionId, array $advertData)
	{
		$advertData = $this->_removeAdvertSensitiveData($advertData);
        $advertData = $this->posunoutPolozky($advertData);

        if (!empty($advertData['custom_advert_code'])) {
            $advertData['kod'] = $advertData['custom_advert_code'];
        }

		if (isset($advertData['nemovitost_energeticky_stitek_priloha'])) {
			$advertData['nemovitost_energeticky_stitek_priloha'] = $this->_wrapFileInBase64($advertData['nemovitost_energeticky_stitek_priloha']);
		}
        if (isset($advertData['nemovitost_pudorys_priloha'])) {
            $advertData['nemovitost_pudorys_priloha'] = $this->_wrapFileInBase64($advertData['nemovitost_pudorys_priloha']);
        }

		$response = $this->_adapter->addNabidka(
			array('session_id' => (string) $sessionId, 'nabidka' => $advertData)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vymazání nabídky (vč. fotografií).
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $advertId  Vlastní ID nabídky.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function delNabidka($sessionId, $advertId)
	{
		$response = $this->_adapter->delNabidka(
			array('session_id' => (string) $sessionId, 'nabidka_id' => (int) $advertId)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Výpis existujících nabídek.
	 *
	 * Oproti metodě na serveru vrací v odpovědi pole a ne string s trubkami.
	 *
	 * Příklad odpovědi:
	 * <code>
	 * array(
	 *     'status': ...,
	 *     'statusMessage': ...,
	 *     'output': (array) [id1,id2,id3,id4,...,idX]
	 * )
	 * </code>
	 *
	 * @param string $sessionId Platné session Id.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru (s klíči output a count)..
	 */
	public function listNabidka($sessionId)
	{
		$response = $this->_adapter->listNabidka(
			array('session_id' => (string) $sessionId)
		);

		$ids = empty($response['output']) ? array() : explode('|', $response['output']);
		unset($response['count']);
		$response['output'] = $ids;

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Nastaví logger pro backend.
	 *
	 * Logger bude použit pouze pokud to backend dovoluje.
	 *
	 * @param Dalten_Export_Api_Backend_Logger_LoggerInterface $logger Instance loggeru.
	 *
	 * @return Dalten_Export_Api_Backend_Website|\Dalten_Export_Api_LoggableApiInterface Fluent interface.
	 */
	public function setLogger(Dalten_Export_Api_Backend_Logger_LoggerInterface $logger)
	{
		if ($this->_adapter instanceof Dalten_Export_Api_Backend_LoggableBackendInterface) {
			$this->_adapter->setLogger($logger);
		}
		return $this;
	}

	/**
	 * Odstraní nastavený logger.
	 *
	 * @return \Dalten_Export_Api_Backend_Website|Dalten_Export_Api_LoggableApiInterface Fluent interface.
	 */
	public function removeLogger()
	{
		if ($this->_adapter instanceof Dalten_Export_Api_Backend_LoggableBackendInterface) {
			$this->_adapter->removeLogger();
		}
		return $this;
	}

	/**
	 * Odstraní citlivá data z nabídky.
	 *
	 * @param array $advertData Data nabídky.
	 *
	 * @return array Zcenzurovaná data nabídky.
	 */
	protected function _removeAdvertSensitiveData(array $advertData)
	{
		$sensitive = array(
			'id_klient',
			'zakazka_obchodovat',
			'zakazka_obchodovat_provize_castka',
			'zakazka_obchodovat_provize_procenta',
			'zakazka_provize_celkem',
			'zakazka_provize_procenta',
			'zakazka_provize_typ',
			'zakazka_doporucitelska_provize_typ',
			'zakazka_doporucitelska_provize_procenta',
			'zakazka_doporucitelska_provize_celkem',
			'zakazka_doporucitel_klient_id',
			'zakazka_neverejna_poznamka',
			'zakazka_obchodovani_zpusob',
			'nastaveni_exportu',
			'sreality_platnost',
			'zakazka_provize_od_pronajimatele',
			'zakazka_provize_od_najemce',
			'zakazka_referencni_provize_typ',
			'zakazka_referencni_provize_procenta',
			'zakazka_referencni_provize_celkem',
			'zakazka_referencni_provize_makler_id',
			'zakazka_referencni_provize_firma_id',
			'zakazka_referencni_provize_cizi_rk_id',
			'zakazka_referencni_provize_cizi_rk_text',
			'intrapoint',
			'preklad_status'
		);

		foreach ($sensitive as $toRemove) {
			if (isset($advertData[$toRemove])) {
				unset($advertData[$toRemove]);
			}
		}

		return $advertData;
	}

    /**
     * Posune položky, které měly číselníky v i1 od nuly a v i3 mají od jedničky.
     *
     * @param array $advertData Data nabídky.
     *
     * @return mixed Upravená data nabídky.
     */
	protected function posunoutPolozky($advertData)
    {
        $posunout = ['nemovitost_elektrina', 'nemovitost_voda'];
        foreach ($posunout as $nazev) {
            if (isset($advertData[$nazev]) && is_string($advertData[$nazev])) {
                $advertData[$nazev] = substr($advertData[$nazev], 1);
            }
        }
        return $advertData;
    }

	public function addFirma($sessionId, $firma)
	{
		$response = $this->_adapter->addFirma(
			array('session_id' => (string) $sessionId, 'firma' => $firma)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	public function delFirma($sessionId, $firmaId)
	{
		$response = $this->_adapter->delFirma(
			array('session_id' => (string) $sessionId, 'firma_id' => $firmaId)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	public function listFirma($sessionId)
	{
		$response = $this->_adapter->listFirma(
			array('session_id' => (string) $sessionId)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	public function addReferenceUzivatele($sessionId, $reference)
	{
		$response = $this->_adapter->addReferenceUzivatele(
			array('session_id' => (string) $sessionId, 'reference'=>$reference)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	public function delReferenceUzivatele($sessionId, $referenceId)
	{
		$response = $this->_adapter->delReferenceUzivatele(
			array('session_id' => (string) $sessionId, 'reference_id'=>$referenceId)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	public function version()
	{
		$response = $this->_adapter->version();

		return new Dalten_Data_ArrayObject($response);
	}

	public function addAktuality($sessionId, $aktualita)
	{
		$response = $this->_adapter->addAktuality(
			array('session_id' => (string) $sessionId, 'aktualita'=>$aktualita)
		);

		return new Dalten_Data_ArrayObject($response);
	}


	public function delAktuality($sessionId, $aktualitaId)
	{
		$response = $this->_adapter->delAktuality(
			array('session_id' => (string) $sessionId, 'aktualita_id'=>$aktualitaId)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vypíše všechny exportované projekty.
	 *
	 * Oproti metodě na serveru vrací v odpovědi pole a ne string s trubkami.
	 *
	 * @param string $sessionId  Platné session Id.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function listProject($sessionId)
	{
		$response = $this->_adapter->listProjekt(
			array('session_id' => (string) $sessionId)
		);

		$ids = empty($response['output']) ? array() : explode('|', $response['output']);
		unset($response['count']);
		$response['output'] = $ids;

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Přidání a nebo úprava projektu.
	 *
	 * Pole $projectData má oproti normálním datům projektu navíc i klíč priloha, obsahující pole řádků fotek.
	 *
	 * @param string $sessionId   Platné session Id.
	 * @param array  $projectData Zkonvertovaná data inzerátu (vč. fotek - viz popis metody).
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function addProjekt($sessionId, array $projectData)
	{
		$response = $this->_adapter->addProjekt(
			array('session_id' => (string) $sessionId, 'projekt' => $projectData)
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vymazání projektu (vč. fotografií).
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $projektID Vlastní ID projektu.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function delProjekt($sessionId, $projektId)
	{
		$response = $this->_adapter->delProjekt(
			array('session_id' => (string) $sessionId, 'projekt_id' => (int) $projektId)
		);

		return new Dalten_Data_ArrayObject($response);
	}

    /**
     * Načte předloženou cestu k souboru a vrátí obsah souboru obalený v base64.
     *
     * @param $pathToFile string Cesta k souboru.
     *
     * @return string|null Obsah souboru obalený v base64 nebo NULL, pokud soubor nejde přečíst.
     */
	protected function _wrapFileInBase64($pathToFile)
    {
        if (empty($pathToFile)) {
            return null;
        }
	    $absolutePath = realpath($pathToFile);
	    if ($absolutePath===false) {
	        return null;
        }
	    $fileContent = file_get_contents($absolutePath);
	    if ($fileContent===false) {
	        return null;
        }
        return $this->_adapter->setType($fileContent, 'base64');
    }
}
