<?php

namespace Opentalent\OtCore\Domain\Repository;

use Opentalent\OtCore\Domain\Model\Organization;
use Opentalent\OtCore\Exception\ApiRequestException;

class OrganizationRepository extends BaseApiRepository
{
    protected const URI_TRAILING_PART = '/api/public/organizations';
    protected const HYDRA_TYPE = 'PortailOrganization';

    /**
     * Get the organization by Id
     *
     * @param int $id The id of the organization
     * @return object
     * @throws ApiRequestException
     */
    public function findById(int $id): object
    {
        $params = [];
        $params['filter[where][id]'] = $id;
        $organization = $this->getApiFirstRecord($params);
        if ($organization === null) {
            throw new ApiRequestException('Organization with id ' . $id . ' does not exist');
        }
        return $organization;
    }

    /**
     * Get the organization by name
     *
     * @param string name          The name of the organization
     * @return object
     * @throws \Exception
     * @throws ApiRequestException
     */
    public function findByName(string $name): object
    {
        $params = [];
        $params['filter[where][name]'] = $name;
        $organization = $this->getApiFirstRecord($params);
        if($organization === null) {
            throw new ApiRequestException('Organization with name "' . $name . '" does not exist');
        }
        return $organization;
    }

    /**
     * Get the organization's child structures by id
     *
     * @param int $id The id of the organization
     * @param array $searchParams An array of parameters which will be passed to the Api request as URI parameters
     * @param int $page
     * @return ApiPagedCollection
     * @throws ApiRequestException
     */
    public function findChildrenById(int $id, array $searchParams = [], int $page = 1): ApiPagedCollection
    {
        $params = [];
        $params['parentId'] = $id;
        $params['children'] = 1;
        $params['page'] = $page;

        $params = array_merge($params, $searchParams);

        return $this->getApiRecords($params);
    }

    /**
     * Get all organizations
     *
     * @return ApiPagedCollection
     * @throws ApiRequestException
     */
    public function getAll(): ApiPagedCollection
    {
        $params = [];
        $params['itemsPerPage'] = 999999;

        return $this->getApiRecords($params);
    }

    /**
     * Returns an Organization object from an Api record
     *
     * @param array $record
     * @return Organization|null
     */
    protected function memberToObject(array $record): ?Organization
    {
        if ($record['@type'] !== $this::HYDRA_TYPE) {
            return null;
        }

        $organization = new Organization();
        $a = explode('/', $record['@id']);
        $organization->setId(end($a));
        $organization->setSubdomain($record['subDomain']);
        $organization->setName($record['name']);
        $organization->setSlug($record['slug']);
        $organization->setPrincipalType($record['principalType']);
        $organization->setDescription($record['description']);
        $organization->setCategories($record['categories']);
        $organization->setAddressCity($record['addressCity']);
        $organization->setPostalCode($record['postalCode']);
        $organization->setStreetAddress($record['streetAddress']);
        $organization->setLatitude($record['latitude']);
        $organization->setLongitude($record['longitude']);
        $organization->setCountry($record['country']);
        $organization->setLogo($record['logo']);
        $organization->setPublicationDirectors($record['publicationDirectors']);
        $organization->setParentId($record['parentId']);
        $organization->setParentName($record['parentName']);
        $organization->setParentSubdomain($record['parentSubDomain']);
        return $organization;
    }

}
