<?php
/**
 * @Copyright © 2002-2018 Acronis International GmbH. All rights reserved.
 */

use Modules_AcronisBackup_PmCachedRepository as PmCachedRepository;
use Modules_AcronisBackup_Srv_Client as SrvClient;
use Modules_AcronisBackup_View_OperationsList as OperationsList;
use Modules_AcronisBackup_Helpers_Arr as Arr;

class Modules_AcronisBackup_OperationsListAdapter extends CommonPanel_View_List_Paginator_Array
{
    private static $predefinedFilterParams = [];

    public $count;
    protected $srvClient;
    protected $filterParams = [];
    protected $orderParams = [];

    /**
     * Modules_AcronisBackup_Models_OperationsListAdapter constructor.
     * @param $data array In parent class, this required variable contains an array with list data, but we made other realization and use method getOperations() for array getting.
     * @throws pm_Exception
     */
    public function __construct(array $data = [])
    {
        $this->filterParams = array_merge($this->filterParams, static::$predefinedFilterParams);
        $this->srvClient = new SrvClient();
        parent::__construct($data);
    }

    public static function setPredefinedFilterParams(array $filterParams)
    {
        static::$predefinedFilterParams = $filterParams;
    }

    /**
     * @param $sortField
     * @param $sortDirection
     */
    public function applySortFilter($sortField, $sortDirection)
    {
        $this->orderParams = [[
            'field' => $sortField,
            'direction' => ($sortDirection == pm_View_List_Simple::SORT_DIR_UP) ? 'asc' : 'desc'
        ]];
    }

    /**
     * @param CommonPanel_View_List_SearchFilter $searchFilter
     * @throws \pm_Exception
     */
    public function applySearchFilter(CommonPanel_View_List_SearchFilter $searchFilter)
    {
        if ($searchFilter->getFields() === OperationsList::FILTER_CUSTOMER_LOGIN) {
            $this->applySearchFilterByCustomerLogin($searchFilter->getSearchText());
        } else {
            $this->filterParams[$searchFilter->getFields()] = [$searchFilter->getSearchText()];
        }

        $this->count = null;
    }

    /**
     * @param int $limit
     * @param int $offset
     * @return array
     * @throws pm_Exception
     */
    private function getOperations($limit, $offset)
    {
        try {
            $queryParams = array_merge(
                $this->filterParams,
                compact('limit', 'offset')
            );
            if ($this->orderParams) {
                $queryParams['order'] = $this->orderParams;
            }
            $operations = $this->srvClient->getOperations($queryParams);
        } catch (Exception $e) {
            throw new pm_Exception(pm_Locale::lmsg(OperationsController::MSG_ERR_DEFAULT));
        }

        return array_map(function (array $operation) {
            $operation[OperationsList::ACTION] = true;
            return $operation;
        }, $operations);
    }

    /**
     * @param $offset
     * @param $itemCountPerPage
     * @return array
     * @throws \pm_Exception
     */
    public function getItems($offset, $itemCountPerPage)
    {
        return array_map(function (array $operation) {
            return Arr::only($operation, [
                'id',
                'customerId',
                'creatorId',
                'type',
                'status',
                'startedAt',
                'finishedAt',
                'canceledAt',
                'duration',
                'action',
                'guid',
            ]);
        }, $this->getOperations($itemCountPerPage, $offset));
    }

    /**
     * @return int
     * @throws pm_Exception
     */
    public function count(): int
    {
        if (is_null($this->count)) {
            try {
                $this->count = $this->srvClient->getOperationsCount($this->filterParams);
            } catch (Exception $e) {
                throw new pm_Exception(pm_Locale::lmsg(OperationsController::MSG_ERR_DEFAULT));
            }
        }
        return $this->count;
    }

    /**
     * @return int
     * @throws pm_Exception
     */
    public function getTotalNumber()
    {
        try {
            return $this->srvClient->getOperationsCount(static::$predefinedFilterParams);
        } catch (Exception $e) {
            throw new pm_Exception(pm_Locale::lmsg(OperationsController::MSG_ERR_DEFAULT));
        }
    }

    /**
     * @param string $searchedLogin
     * @throws pm_Exception
     */
    private function applySearchFilterByCustomerLogin($searchedLogin)
    {
        if (is_null($searchedLogin) || $searchedLogin === '') {
            return;
        }

        try {
            $customersIds = $this->srvClient->getOperationsCustomersIds($this->filterParams);
        } catch (Exception $e) {
            throw new pm_Exception(pm_Locale::lmsg(OperationsController::MSG_ERR_DEFAULT));
        }

        $filterByCustomers = [];
        foreach ($customersIds as $customerId) {
            $client = PmCachedRepository::getClientById($customerId);
            if (!$client) {
                continue;
            }
            $login = $client->getLogin();
            if (mb_stripos($login, $searchedLogin) !== false) {
                $filterByCustomers[] = $customerId;
            }
        }
        $this->filterParams['customersIds'] = $filterByCustomers;
    }
}