<?php

/**
 * Backend API RealityMixu.
 * 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_RealityMix implements Dalten_Export_Api_Backend_LoggableBackendInterface
{
	/**
	 * Adpatér pro volání metod přes XML RPC.
	 *
	 * @var Serenity_Rpc_XmlRpc
	 */
	private $_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 int $clientId Id klienta.
	 *
	 * @return Dalten_Data_ArrayObject Po zavolání se správným clientId je vrácen objekt:
	 *                                 <code>
	 *                                 {
	 *                                     status: 200,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                         sessionId: '...',
	 *                                         hashKey: '...'
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function getHash($clientId)
	{
		$response = (array) $this->_adapter->getHash((int) $clientId);
		if (empty($response) || !is_array($response['output'])) {
			$response['output'] = array(null, null);
		}
		$response['output'] = array(
			'sessionId' => current($response['output']),
			'hashKey' => next($response['output'])
		);

		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.
	 * @param string $softwareKey Softwarový klíč.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {}
	 *                                 }
	 *                                 </code>
	 */
	public function login($sessionId, $password, $softwareKey)
	{
		$response = $this->_adapter->login(
			(string) $sessionId,
			(string) $password,
			(string) $softwareKey
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Odhlášení.
	 *
	 * @param string $sessionId Platné session Id.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {}
	 *                                 }
	 *                                 </code>
	 */
	public function logout($sessionId)
	{
		return new Dalten_Data_ArrayObject($this->_adapter->logout((string) $sessionId));
	}

	/**
	 * Přidání nového makléře.
	 * Aby makléř byl vložen, je potřeba vyplnit tyto povinné položky: sessionId, clientName (jméno a přijmení),
	 * contactGsm (mobil), contactEmail (email). SellerRkId je nepovinná položka a slouží též jako identifikátor
	 * konkrétního makléře. Je to alternativa k sellerId. Při vkládaní inzerátu, pokud má vlastního makléře,
	 * je tedy na výběr mezi sellerRkId a sellerId. Ostatní položky contactPhone (telefon), contactIcq (ICQ),
	 * brokerNote (poznámka makléře) a photo (fotografie makléře) jsou nepovinné.
	 * U korektně vloženého makléře je získáno sellerId číslo.
	 *
	 * @param string $sessionId    Platné session Id.
	 * @param string $clientName   Jméno a příjmení makléře.
	 * @param string $contactGsm   Mobilní telefon.
	 * @param string $contactEmail Email.
	 * @param string $sellerRkId   Vlastní id makléře.
	 * @param string $contactPhone Pevná linka.
	 * @param string $contactIcq   ICQ.
	 * @param string $brokerNote   Poznámka makléře.
	 * @param string $photo        Fotografie makléře v base64.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                         sellerId: xxx
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function addSeller(
		$sessionId,
		$clientName,
		$contactGsm,
		$contactEmail,
		$sellerRkId = '',
		$contactPhone = '',
		$contactIcq = '',
		$brokerNote = '',
		$photo = ''
	)
	{
		$response = $this->_adapter->addSeller(
			(string) $sessionId,
			(string) $clientName,
			(string) $contactGsm,
			(string) $contactEmail,
			(string) $sellerRkId,
			(string) $contactPhone,
			(string) $contactIcq,
			(string) $brokerNote,
			$this->_adapter->setType($photo, 'base64')
		);

		$response['output'] = array(
			'sellerId' => current($response['output'])
		);

		return new Dalten_Data_ArrayObject($response);
	}


    /**
     * Přidání nového makléře.
     *
     * @param $sessionId
     * @param $sellerRkId
     * @param $sellerData
     * @return Dalten_Data_ArrayObject
     */
    public function addSellerData(
        $sessionId,
        $sellerRkId,
        $sellerData
    )
    {
        $sellerData['photo'] = $this->_adapter->setType($sellerData['photo'], 'base64');

        $response = $this->_adapter->addSellerData(
            (string) $sessionId,
            (string) $sellerRkId,
            (array) $sellerData
        );

        $response['output'] = array(
            'sellerId' => current($response['output'])
        );

        return new Dalten_Data_ArrayObject($response);
    }

	/**
	 * Vložení fotografie k již uloženému inzerátu.
	 *
	 * Vstupními parametry jsou advertId nebo rkId, JPEG soubor zakódovaný pomocí base64, příznak, zda jde
	 * o hlavní či vedlejší fotografie (main = 1 – hlavní, main = 0 – vedlejší, main = 2 - časopis)
	 * a český nebo anglický popisek obrázku (alt, altEn). Fotografie s main hodnotou 2 není zobrazena na webu,
	 * slouží pouze pro případné vložení inzerátu do tištěného časopisu. Např. pro fotografii bez vodotisku.
	 * Pomocí advertId nebo rkId se identifikuje inzerát. Vždy má přednost advertId před rkId.
	 * Výstupem je photoId, které je vhodné si uložit pro mazání fotky. Pokud je vkládána vedlejší fotografie,
	 * a přitom není u inzerátu žádná, stává se tato automaticky hlavní fotografií.
	 * Pokud je vkládána hlavní fotografie, a přitom u inzerátu již jedna je, stane se hlavní fotografie vedlejší
	 * a nová hlavní. Minimální rozlišení fotografie je 640x480 a maximální velikost souboru 100kB.
	 * Po překročení této velikosti server vrací chybu a fotografii nezpracuje.
	 * Fotografie jsou seřazeny podle pořadí vložení.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $advertId  Id nabídky z realitymixu.
	 * @param string $rkId      Vlastní id nabídky.
	 * @param string $data      Data fotografie v base64.
	 * @param int    $main      Je fotografie hlavní?
	 * @param string $alt       Popisek fotografie.
	 * @param string $photoRkId Vlastní id fotografie.
	 * @param string $altEn     Popisek fotografie v angličtině.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                         photoId: xxx
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function addPhoto($sessionId, $advertId, $rkId, $data, $main, $alt, $photoRkId, $altEn)
	{
		$response = $this->_adapter->addPhoto(
			(string) $sessionId,
			(int) $advertId,
			(string) $rkId,
			$this->_adapter->setType($data, 'base64'),
			(int) $main,
			(string) $alt,
			(string) $photoRkId,
			(string) $altEn
		);

		$response['output'] = array(
			'photoId' => current($response['output'])
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vymazání fotografie.
	 *
	 * Identifikací fotografie je photoRkId nebo photoId, které má přednost. Pokud je mazána hlavní fotografie,
	 * hlavní se automaticky stane první vedlejší.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $photoId   Id fotografie z realitymixu.
	 * @param string $photoRkId Vlastní id fotografie.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {}
	 *                                 }
	 *                                 </code>
	 */
	public function delPhoto($sessionId, $photoId, $photoRkId)
	{
		return new Dalten_Data_ArrayObject($this->_adapter->delPhoto(
			(string) $sessionId,
			(int) $photoId,
			(string) $photoRkId
		));
	}

	/**
	 * Přidání / editace inzerátu.
	 *
	 * Metodě se předají parametry podle dále definovaných datových struktur Advert
	 * a pro adekvátní druh. Zpět je vrácen status a advertId, které je dobré
	 * si uchovat pro další operace s uloženým inzerátem.
	 * Pokud je vyplněn parametr rkId, musí být v rámci inzerce konkrétního
	 * klienta unikátní. Tento parametr obsahuje vlastní identifikátor inzerátu
	 * a tento identifikátor se bude zobrazovat na webovém serveru místo advertId.
	 * Je ho možné také použít při práci s importním rozhraním, kde opět
	 * zastupuje advertId. Editace inzerátu se zajistí vyplněním advertId
	 * již uloženého inzerátu, nebo je možno zadat existující rkId (viz. identifikace inzerátu).
	 * Adresu inzerátu lze vyplnit buď klasicky nebo s použitím UIR-ADR.
	 * UIR-ADR má tu výhodu, že se adrese doplní automaticky tak, jak je uvedena
	 * v katastru nemovitostí. Více informací je uvedeno v kapitole UIR-ADR.
	 *
	 * "advertData" ... parametry definované v tabulce "Inzerát - základní údaje"
	 * "typeData" ... parametry definované v tabulkách jednotlivých typů nemovitostí
	 *
	 * @param string $sessionId  Platné session Id.
	 * @param array  $advertData Zkonvertovaná data inzerátu.
	 * @param array  $typeData   Data pro konkrétní typ nemovitosti.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                         advertId: xxx
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function addAdvert($sessionId, array $advertData, array $typeData)
	{
		if (isset($advertData['energy_performance_attachment'])) {
			$advertData['energy_performance_attachment'] = $this->_adapter->setType($advertData['energy_performance_attachment'], 'base64');
		}

		$response = $this->_adapter->addAdvert(
			(string) $sessionId,
			$advertData,
			$typeData
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Přidání / editace developerského projektu.
	 *
	 * Metodě se předají parametry podle dále definovaných datových struktur Developer (devel_data) a pole spárovaných
	 * inzerátů za pomoci advert_id nebo rkid. Zpět je vrácen status a developer_id, které je dobré si uchovat
	 * pro další operace s uloženým developerským projektem. Pokud je vyplněn parametr devel_rkid, musí být v rámci
	 * inzerce konkrétního klienta unikátní. Je ho možné také použít při práci s importním rozhraním,
	 * kde opět zastupuje developer_id. Editace inzerátu se zajistí vyplněním developer_id již uloženého projektu,
	 * nebo je možno zadat existující devel_rkid (viz. odstavec 1.1). Spárovat k devel. projektu inzerát je též
	 * možné v metodě addAdvert vyplněním položek developer_id nebo devel_rkid. Devel. projekt již musí existovat,
	 * jinak spárování neproběhne. Při editaci devel. projektu je nutné uvádět v poli parametru advert_id
	 * nebo rkid všechny inzeráty, které projektu patří, jinak bude vazba mezi devel. projektem a inzerátem zrušena.
	 *
	 * @param string $sessionId   Platné session Id.
	 * @param array  $projectData Zkonvertovaná data projektu.
	 * @param array  $advertIds   Pole advert_id nabídek, které patří k projektu.
	 * @param array  $rkIds       Pole rk_id nabídek, které patří k projektu.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                         developerId: xxx
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function addDevel($sessionId, array $projectData, array $advertIds = array(), array $rkIds = array())
	{
		$response = $this->_adapter->addDevel(
			(string) $sessionId,
			$projectData,
			$advertIds,
			$rkIds
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vymazání inzerátu.
	 *
	 * Pomocí advertId čísla nebo rkId řetězce je inzerát smazán.
	 * Uložené fotografie u inzerátu budou smazány.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $advertId  ID nabídky z realitymixu.
	 * @param string $rkId      Vlastní ID nabídky.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {}
	 *                                 }
	 *                                 </code>
	 */
	public function delAdvert($sessionId, $advertId, $rkId)
	{
		$response = $this->_adapter->delAdvert(
			(string) $sessionId,
			(int) $advertId,
			(string) $rkId
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Výpis fotografie existujícího inzerátu.
	 *
	 * V output je vráceno pole, kde každý prvek pole obsahuje photo_id, main
	 * (main = 1 – hlavní fotografie, main = 0 – vedlejší fotografie) a photo_rkid.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $advertId  ID nabídky z realitymixu.
	 * @param string $rkId      Vlastní ID nabídky.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                          0: {
	 *                                              photo_id: xxx
	 *                                              main: 1|0
	 *                                              photo_rkid: xxx
	 *                                          }
	 *                                          1: ...
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function listPhoto($sessionId, $advertId, $rkId)
	{
		$response = $this->_adapter->listPhoto(
			(string) $sessionId,
			(int) $advertId,
			(string) $rkId
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Výpis fotografie existujícího developerského projektu.
	 *
	 * V output je vráceno pole, kde každý prvek pole obsahuje photo_id, main
	 * (main = 1 – hlavní fotografie, main = 0 – vedlejší fotografie) a photo_rkid.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $developerId  ID nabídky z realitymixu.
	 * @param string $developerRkId      Vlastní ID nabídky.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                          0: {
	 *                                              photo_id: xxx
	 *                                              main: 1|0
	 *                                              photo_rkid: xxx
	 *                                          }
	 *                                          1: ...
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function listDevelPhoto($sessionId, $developerId, $developerRkId)
	{
		$response = $this->_adapter->listDevelPhoto(
			(string) $sessionId,
			(int) $developerId,
			(string) $developerRkId
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vymazání devel. projektu.
	 *
	 * Pomocí developer_id čísla nebo devel_rkid řetězce je devel. projekt smazán. Uložené fotografie budou smazány.
	 * Všechny navázané inzeráty zůstanou beze změny, pouze ztratí vazbu na devel. projekt.
	 *
	 * @param string $sessionId     Platné session Id.
	 * @param int    $developerId   Id projektu z realitymixu.
	 * @param string $developerRkId Vlastní id projektu.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {}
	 *                                 }
	 *                                 </code>
	 */
	public function delDevel($sessionId, $developerId, $developerRkId)
	{
		$response = $this->_adapter->delDevel(
			(string) $sessionId,
			(int) $developerId,
			(string) $developerRkId
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vložení fotografie k již uloženému deleveloperskému projektu.
	 *
	 * Vstupními parametry jsou developer_id nebo devel_rkid, JPEG soubor zakódovaný pomocí base64, příznak,
	 * zda jde o hlavní či vedlejší fotografie (main = 1 – hlavní, main = 0 – vedlejší) a český popisek obrázku (alt).
	 * Pomocí developer_id nebo devel_rkid slouží k identifikaci. Vždy má přednost developer_id před devel_rkid
	 * (viz. odstavec 1.1). Výstupem je photo_id, které je vhodné si uložit pro mazání fotografie. Pokud je vkládána
	 * vedlejší fotografie, a přitom není u inzerátu žádná, stává se tato automaticky hlavní fotografií.
	 * Pokud je vkládána hlavní fotografie, a přitom u inzerátu již jedna je, stane se hlavní fotografie
	 * vedlejší a nová hlavní. Minimální rozlišení fotografie je 640x480 a maximální velikost souboru 100kB.
	 * Po překročení této velikosti server vrací chybu a fotografii nezpracuje.
	 * Fotografie jsou seřazeny podle pořadí vložení.
	 *
	 * @param string $sessionId     Platné session id.
	 * @param int    $developerId   Id projektu z realitymixu.
	 * @param string $developerRkId Vlastní id projektu.
	 * @param string $data          Data fotografie v base64.
	 * @param int    $main          Je fotografie hlavní?
	 * @param string $alt           Popisek fotografie.
	 * @param string $photoRkId     Vlastní id fotografie.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {
	 *                                         photoId: xxx
	 *                                     }
	 *                                 }
	 *                                 </code>
	 */
	public function addDevelPhoto($sessionId, $developerId, $developerRkId, $data, $main, $alt, $photoRkId)
	{
		$response = $this->_adapter->addDevelPhoto(
			(string) $sessionId,
			(int) $developerId,
			(string) $developerRkId,
			$this->_adapter->setType($data, 'base64'),
			(int) $main,
			(string) $alt,
			(string) $photoRkId
		);

		$response['output'] = array(
			'photoId' => current($response['output'])
		);

		return new Dalten_Data_ArrayObject($response);
	}

	/**
	 * Vymazání fotografie.
	 *
	 * Identifikací fotografie je photoRkId nebo photoId, které má přednost. Pokud je mazána hlavní fotografie,
	 * hlavní se automaticky stane první vedlejší.
	 *
	 * @param string $sessionId     Platné session id.
	 * @param int    $photoId       Id fotografie z realitymixu.
	 * @param string $photoRkId     Vlastní id fotografie.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {}
	 *                                 }
	 *                                 </code>
	 */
	public function delDevelPhoto($sessionId, $photoId, $photoRkId)
	{
		return new Dalten_Data_ArrayObject($this->_adapter->delDevelPhoto(
			(string) $sessionId,
			(int) $photoId,
			(string) $photoRkId
		));
	}

	/**
	 * 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_RealityMix 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_RealityMix Fluent interface.
	 */
	public function removeLogger()
	{
		if ($this->_adapter instanceof Dalten_Export_Api_Backend_LoggableBackendInterface) {
			$this->_adapter->removeLogger();
		}
		return $this;
	}

	/**
	 * Vypíše statistiky.
	 *
	 * @param $sessionId string ID relace.
	 * @param $advertId  string Pole ID nabídky.
	 * @param $rkId      string Pole vlastních ID nabídky.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function listStat($sessionId, $advertId, $rkId)
	{
		return new Dalten_Data_ArrayObject(
			$this->_adapter->listStat($sessionId, $advertId, $rkId)
		);
	}

	/**
	 * Vypíše statistiky.
	 *
	 * @param $sessionId string ID relace.
	 * @param $advertId  array  Pole ID nabídky.
	 * @param $rkId      array  Pole vlastních ID nabídky.
	 *
	 * @return Dalten_Data_ArrayObject Odpověď serveru.
	 */
	public function listStatMultiple($sessionId, array $advertId, array $rkId)
	{
		return new Dalten_Data_ArrayObject(
			$this->_adapter->listStatMultiple($sessionId, $advertId, $rkId),
			false
		);
	}

	/**
	 * Topování inzerátu.
	 *
	 * Pomocí advertId čísla nebo rkId řetězce je inzerát vytopován.
	 *
	 * @param string $sessionId Platné session Id.
	 * @param int    $advertId  ID nabídky z realitymixu.
	 * @param string $rkId      Vlastní ID nabídky.
	 *
	 * @return Dalten_Data_ArrayObject <code>
	 *                                 {
	 *                                     status: xxx,
	 *                                     statusMessage: '...',
	 *
	 *                                     output: {}
	 *                                 }
	 *                                 </code>
	 */
	public function topAdvert($sessionId, $advertId, $rkId)
	{
		$response = $this->_adapter->topAdvert(
			(string) $sessionId,
			(int) $advertId,
			(string) $rkId
		);

		return new Dalten_Data_ArrayObject($response);
	}

    /**
     * Vypíše vyexportované nabídky.
     *
     * @param string $sessionId Platné session Id.
     *
     * @return Dalten_Data_ArrayObject Odpověď serveru.
     */
    public function listAdvert($sessionId)
    {
        $response = $this->_adapter->listAdvert(
            (string) $sessionId
        );

        if (!empty($response['output'])) {
            foreach ($response['output'] as $ord=>$output) {
                //
                $response['output'][$ord]['kod'] = $output['rkid'];
            }
        }

        return new Dalten_Data_ArrayObject($response);
    }

    /**
     * Výpis celých zpráv, ze všech inzerátu, odeslaných na RK v zadané datum.
     *
     * @param string $sessionId ID relace.
     * @param string $date      Datum, kterého se statistika týká.
     * @return Dalten_Data_ArrayObject Odpověď serveru.
     */
    public function listFullInquiry($sessionId, $date)
    {
        $date = $this->_adapter->setType($date, 'datetime');
        $response = $this->_adapter->listFullInquiry((string) $sessionId, $date);
        return new Dalten_Data_ArrayObject($response, false);
    }
}
