<?php

namespace Opentalent\OtTemplating\Domain\Repository;

use GuzzleHttp\Exception\GuzzleException;
use Opentalent\OtTemplating\Domain\Model\Organization;
use Opentalent\OtTemplating\Exception\ApiRequestException;

class OrganizationRepository extends BaseApiRepository
{
    CONST URI = BaseApiRepository::BASE_URI . 'public/organizations';
    const HYDRA_TYPE = 'PortailOrganization';

    /**
     * Returns an Organization object from an Api record
     *
     * @param $record
     * @return Organization|null
     */
    private function organizationFromJson($record) {
        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->setStreetAdress($record->{'streetAddress'});
        $organization->setLatitude($record->{'latitude'});
        $organization->setLongitude($record->{'longitude'});
        $organization->setCountry($record->{'country'});
        $organization->setLogo($record->{'logo'});
        $organization->setParentId($record->{'parentId'});
        $organization->setParentName($record->{'parentName'});
        $organization->setParentSubdomain($record->{'parentSubDomain'});
        return $organization;
    }

    /**
     * Returns an array of Organization objects from an array of Api records
     *
     * @param $records
     * @return array
     */
    private function organizationsFromJson($records) {
        $organizations = [];
        foreach ($records as $record) {
            $organizations[] = $this->organizationFromJson($record);
        }
        return $organizations;
    }

    /**
     * Get the organization by Id
     *
     * @param int $id The id of the organization
     * @return Organization
     * @throws ApiRequestException
     */
    public function findById($id) {
        $params = [];
        $params['organization_id'] = $id;
        $record = $this->getApiFirstRecord($this::URI, $params);
        $organization = $this->organizationFromJson($record);
        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 Organization
     * @throws \Exception
     * @throws ApiRequestException
     */
    public function findByName($name)
    {
        $params = [];
        $params['filter[where][name]'] = $name;
        $data = $this->getApiFirstRecord($this::URI, $params);
        $organization = $this->organizationFromJson($data);
        if($organization == null) {
            throw new \Exception('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
     * @return array
     * @throws ApiRequestException
     */
    public function findChildrenById($id, $searchParams = [])
    {
        $params = [];
        $params['parentId'] = $id;
        $params['children'] = 1;

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

        $record = $this->getApiRecords($this::URI, $params);
        return $this->organizationsFromJson($record);
    }

}
