<?php

namespace AuthStack\UserDirectoryAPI\Service;

use AuthStack\UserDirectoryAPI\Model\Account as AccountModel;
use AuthStack\UserDirectoryAPI\Exception\UserDirectoryException;

class Account extends RESTService
{
    /**
     * @param string $username
     * @param string $password
     * @param callable|null $after
     * @return array
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function authenticate(string $username, string $password, callable $after = null): array
    {
        return $this->remote(function() use ($username, $password): array
        {
            $data = $this->json('authenticate', ['username' => $username, 'password' => $password]);

            return $data;

        }, UserDirectoryException::class, $after);
    }

    /**
     * @param $id
     * @param callable|null $after
     * @return bool
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function activate($id, callable $after = null): bool
    {
        return $this->remote(function() use ($id): bool
        {
            $this->json('activate', [], [$id]);

            return true;

        }, UserDirectoryException::class, $after);
    }

    /**
     * @param array $model
     * @param callable|null $after
     * @return array
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function create(array $model, callable $after = null): array
    {
        return $this->remote(function() use ($model): array
        {
            $data = $this->json('create', $model);

            return $data;

        }, UserDirectoryException::class, $after);
    }

    /**
     * @param int $id
     * @param callable|null $after
     * @return AccountModel
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function read(int $id, callable $after = null): AccountModel
    {
        return $this->remote(function() use ($id)
        {
            $data = $this->json('read', [], [$id]);

            return (new AccountModel($data))->setService($this);

        }, UserDirectoryException::class, $after);
    }

    /**
     * @param int|null $id
     * @param array $data
     * @param callable|null $after
     * @return bool
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function update(int $id = null, array $data, callable $after = null): bool
    {
        return $this->remote(function() use ($id, &$data): bool
        {
            $data = $this->json('update', $data, [$id]);

            return true;

        }, UserDirectoryException::class, $after);
    }

    /**
     * @param int|null $id
     * @return bool
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function delete(int $id = null): bool
    {
        return $this->remote(function() use ($id): bool
        {
            $data = $this->json('delete', [], [$id]);

            return true;

        }, UserDirectoryException::class);
    }

    /**
     * @param int $id
     * @return array
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function getOrganizations(int $id): array
    {
        return $this->remote(function() use ($id): array
        {
            return $this->json('organizations', [], [$id]);

        }, UserDirectoryException::class);
    }

    /**
     * @param int $id
     * @param int $organization_id
     * @return bool
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function joinOrganization(int $id, int $organization_id): bool
    {
        return $this->remote(function() use ($id, $organization_id): bool
        {
            $result = $this->json('join_organization', ['organization_id' => $organization_id], [$id]);

            return true;

        }, UserDirectoryException::class);
    }

    /**
     * @param int $id
     * @param int $organization_id
     * @return bool
     * @throws UserDirectoryException
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     */
    public function leaveOrganization(int $id, int $organization_id): bool
    {
        return $this->remote(function() use ($id, $organization_id): bool
        {
            $result = $this->json('leave_organization', ['organization_id' => $organization_id], [$id]);

            return true;

        }, UserDirectoryException::class);
    }
}