<?php

namespace Fifa\ConnectId\Sdk\ApiClient\Organisation;

use Fifa\ConnectId\Sdk\Api\Model\FindOrganisationsRequestType;
use Fifa\ConnectId\Sdk\Api\Model\FindOrganisationsResponseType;
use Fifa\ConnectId\Sdk\Api\Model\MemberAssociationResponseType;
use Fifa\ConnectId\Sdk\Api\Model\NationalAssociationsOnboardedRequestType;
use Fifa\ConnectId\Sdk\Api\Model\NationalAssociationsOnboardedResponseType;
use Fifa\ConnectId\Sdk\Api\Model\OrganisationLocalType;
use Fifa\ConnectId\Sdk\Exception\FifaConflictException;
use Fifa\ConnectId\Sdk\Exception\FifaConnectIdException;
use Fifa\ConnectId\Sdk\Exception\FifaDuplicatedOrganisationFoundException;
use Fifa\ConnectId\Sdk\Exception\FifaEntityNotFoundException;
use Fifa\ConnectId\Sdk\Exception\FifaOrganisationMergedException;
use Fifa\ConnectId\Sdk\Exception\InvalidClientDataException;
use Fifa\ConnectId\Sdk\Exception\TooManyRequestsException;
use Fifa\ConnectId\Sdk\Registration\ValidationException;
use Fifa\ConnectServiceBus\Sdk\Exception\AuthenticationException;
use Fifa\ConnectServiceBus\Sdk\Exception\UnauthorizedException;

/**
 * Interface OrganisationApiInterface
 * @package Fifa\ConnectId\Sdk\ApiClient\Organisation
 */
interface OrganisationApiInterface
{
    /**
     * Registers a new organisation and assigns FIFA Unique Identifier.
     * Uses organisation data as defined in FIFA Data Standard.
     *
     * @param OrganisationLocalType $organisation - object containing information about the organisation.
     * @param bool $force - registers organisation even if possible duplicates are detected
     * @return string - FIFA Unique Identifier
     *
     * @throws InvalidClientDataException
     * @throws FifaConnectIdException
     * @throws FifaDuplicatedOrganisationFoundException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     * @throws ValidationException
     * @throws TooManyRequestsException
     */
    public function register(OrganisationLocalType $organisation, bool $force = false): string;

    /**
     * Gets organisation data associated with the specified FIFA Unique Identifier.
     *
     * @param string $organisationFifaId - FIFA Unique Identifier
     * @return OrganisationLocalType
     *
     * @throws InvalidClientDataException
     * @throws FifaEntityNotFoundException
     * @throws FifaConnectIdException
     * @throws FifaOrganisationMergedException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     * @throws ValidationException
     * @throws TooManyRequestsException
     */
    public function getOrganisation(string $organisationFifaId): OrganisationLocalType;

    /**
     * Updates the organisation.
     *
     * @param OrganisationLocalType $organisation - Object containing information about the organisation to update
     * @param bool $force - updates organisation even if possible duplicates are detected
     * @return OrganisationLocalType
     *
     * @throws InvalidClientDataException
     * @throws FifaEntityNotFoundException
     * @throws FifaConflictException
     * @throws FifaConnectIdException
     * @throws FifaDuplicatedOrganisationFoundException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     * @throws ValidationException
     * @throws TooManyRequestsException
     */
    public function update(OrganisationLocalType $organisation, bool $force = false): OrganisationLocalType;

    /**
     * Merges two organisations. Returns the primary organisation.
     *
     * @param $primaryOrganisationFifaId - Primary organisation FIFA Unique Identifier
     * @param $secondaryOrganisationFifaId - Secondary organisation FIFA Unique Identifier
     * @return OrganisationLocalType
     *
     * @throws InvalidClientDataException
     * @throws FifaEntityNotFoundException
     * @throws FifaConnectIdException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     * @throws ValidationException
     * @throws TooManyRequestsException
     */
    public function mergeOrganisations($primaryOrganisationFifaId, $secondaryOrganisationFifaId): OrganisationLocalType;

    /**
     * Reverts merge operation. Returns the secondary organisation when unmerge operations is completed.
     *
     * @param $primaryOrganisationFifaId - Primary organisation FIFA Unique Identifier
     * @param $secondaryOrganisationFifaId - Secondary organisation FIFA Unique Identifier
     *
     * @return OrganisationLocalType
     * @throws InvalidClientDataException
     * @throws FifaEntityNotFoundException
     * @throws FifaConflictException
     * @throws FifaConnectIdException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     * @throws ValidationException
     * @throws TooManyRequestsException
     */
    public function unmergeOrganisations($primaryOrganisationFifaId, $secondaryOrganisationFifaId): OrganisationLocalType;

    /**
     * Searches for organisation.
     *
     * @param FindOrganisationsRequestType $request - Object containing search criteria
     * @return FindOrganisationsResponseType
     *
     * @throws FifaConnectIdException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     * @throws ValidationException
     * @throws TooManyRequestsException
     */
    public function findOrganisations(FindOrganisationsRequestType $request): FindOrganisationsResponseType;

    /**
     * Gets a list of organisations this organisation may be duplicated with.
     * Uses organisation data as defined in FIFA Data Standard.
     *
     * @param OrganisationLocalType $organisation - Object containing information about the organisation
     * @return array
     *
     * @throws InvalidClientDataException
     * @throws FifaConnectIdException
     * @throws UnauthorizedException
     * @throws AuthenticationException
     * @throws ValidationException
     * @throws TooManyRequestsException
     */
    public function getDuplicates(OrganisationLocalType $organisation): array;

    /**
     * Verify in Connect ID if organisations are onboarded.
     *
     * @param NationalAssociationsOnboardedRequestType $request
     * @return NationalAssociationsOnboardedResponseType - List of objects containing organisations FIFA ID and boolean which indicates if an organisation is onboarded.
     *
     * @throws InvalidClientDataException
     * @throws FifaConnectIdException
     * @throws FifaEntityNotFoundException
     * @throws ValidationException
     * @throws TooManyRequestsException
     * @throws AuthenticationException
     * @throws UnauthorizedException
     */
    public function getNationalAssociationsOnboardedStatus(NationalAssociationsOnboardedRequestType $request): NationalAssociationsOnboardedResponseType;

    /**
     * Verify in Connect ID all National Associations onboarded status.
     *
     * @return NationalAssociationsOnboardedResponseType - List of objects containing organisations FIFA ID and boolean which indicates if an organisation is onboarded.
     *
     * @throws UnauthorizedException
     * @throws FifaConnectIdException
     * @throws TooManyRequestsException
     * @throws AuthenticationException
     */
    public function getAllNationalAssociationsOnboardedStatus(): NationalAssociationsOnboardedResponseType;

    /**
     * Gets FIFA Id and short name of the Member Association the searched organisation belongs to.
     *
     * @param string $organisationFifaId - FIFA Unique Identifier
     * @return MemberAssociationResponseType
     *
     * @throws FifaEntityNotFoundException
     * @throws FifaConnectIdException
     * @throws AuthenticationException
     * @throws UnauthorizedException
     * @throws ValidationException
     * @throws TooManyRequestsException
     * @throws InvalidClientDataException
     */
    public function getMemberAssociationForFifaId(string $organisationFifaId): MemberAssociationResponseType;

    /**
     * Returns ID Directory API client
     * @return \Fifa\ConnectId\Sdk\Api\Resource\OrganisationApi
     */
    public function getIdDirectoryApiClient(): \Fifa\ConnectId\Sdk\Api\Resource\OrganisationApi;
}