<?php

namespace AuthStack\UserDirectoryAPI\Model;

use AuthStack\UserDirectoryAPI\Service\RESTService;

class Account extends Model
{
    protected $cfg = 'account';
    protected $provider = \AuthStack\UserDirectoryAPI\Service\Account::class;

    const S_ACTIVE = 1;
    const S_PENDING = 2;
    const S_RESETTING_PASSWORD = 3;
    const S_PASSWORD_EXPIRED = 4;
    const S_DEACTIVATED = 5;
    const S_SUSPENDED = 6;
    const S_LOCKED_OUT = 7;
    const S_EXPIRED = 8;

    /**
     * @param string $username
     * @param string $password
     * @param callable|null $after
     * @return Account
     * @throws \AuthStack\UserDirectoryAPI\Exception\TransferException
     * @throws \AuthStack\UserDirectoryAPI\Exception\UserDirectoryException
     */
    public function authenticate(string $username, string $password, callable $after = null): self
    {
        /** @var  $service \AuthStack\UserDirectoryAPI\Service\Account */
        $service = $this->getService();

        $model = $service->authenticate($username, $password, $after);

        $this->model = array_merge($this->model, $model);

        return $this;
    }

    /**
     * @return bool
     */
    public function activate(): bool
    {
        if(!$this->isActive())
        {
            $this->getService()->activate($this->id);

            $this->setStatusID(self::S_ACTIVE);
        }

        return $this->isActive();
    }

    /**
     * @return bool
     */
    public function delete(): bool
    {
        return $this->getService()->delete($this->id);
    }

    /**
     * @return bool
     */
    public function isActive(): bool
    {
        return (int)$this->status_id === self::S_ACTIVE;
    }

    /**
     * @return bool
     */
    public function isCreated(): bool
    {
        return isset($this->model['id']) && !empty($this->model['id']);
    }

    /**
     * @param array $model
     * @param callable|null $after
     * @return Account
     */
    public function save(array $model = [], callable $after = null): self
    {
        $model = array_merge($this->getModel(), $model);

        if(!$this->isCreated())
        {
            $model = array_merge($model, $this->getService()->create($model, $after));
        }
        else
        {
            $this->getService()->update($this->id, $model, $after);
        }

        $this->model = $model;

        return $this;
    }

    /**
     * @return array
     */
    public function getOrganizations(): array
    {
        return $this->getService()->getOrganizations((int)$this->id);
    }

    /**
     * @param int $organization_id
     * @return bool
     */
    public function joinOrganization(int $organization_id): bool
    {
        return $this->getService()->joinOrganization((int)$this->id, $organization_id);
    }

    /**
     * @param int $organization_id
     * @return bool
     */
    public function leaveOrganization(int $organization_id): bool
    {
        return $this->getService()->leaveOrganization((int)$this->id, $organization_id);
    }

    /**
     * @param int $id
     * @return Account
     */
    public function setPasswordPolicy(int $id): self
    {
        $this->model['policy_id'] = $id;

        return $this;
    }

    /**
     * @param string $name
     * @return $this|Model
     */
    public function setFirstName(string $name)
    {
        return $this->setProperty('first_name', $name);
    }

    /**
     * @param string $lname
     * @return $this|Model
     */
    public function setLastName(string $lname)
    {
        return $this->setProperty('last_name', $lname);
    }

    /**
     * @param string $username
     * @return $this|Model
     */
    public function setUsername(string $username)
    {
        return $this->setProperty('username', $username);
    }

    /**
     * @param string $email
     * @return $this|Model
     */
    public function setEmail(string $email)
    {
        return $this->setProperty('email', $email);
    }

    /**
     * @param string $password
     * @return $this|Model
     */
    public function setPassword(string $password)
    {
        return $this->setProperty('password', $password);
    }

    /**
     * @param int $id
     * @return $this|Model
     */
    public function setPasswordPolicyID(int $id)
    {
        return $this->setProperty('policy_id', $id);
    }

    /**
     * @param string $expires_at
     * @return $this|Model
     */
    public function setExpiresAt(string $expires_at)
    {
        return $this->setProperty('expries_at', $expires_at);
    }

    /**
     * @param int $status_id
     * @return $this|Model
     */
    public function setStatusID(int $status_id)
    {
        return $this->setProperty('status_id', $status_id);
    }

    /**
     * @return $this|Model
     */
    public function setActive()
    {
        return $this->setProperty('status_id', self::S_ACTIVE);
    }

    /**
     * @return $this|Model
     */
    public function setPending()
    {
        return $this->setProperty('status_id', self::S_PENDING);
    }

    /**
     * @return $this|Model
     */
    public function setDeactivated()
    {
        return $this->setProperty('status_id', self::S_DEACTIVATED);
    }

    /**
     * @return $this|Model
     */
    public function setSuspended()
    {
        return $this->setProperty('status_id', self::S_SUSPENDED);
    }
}
