<?php

namespace AuthStack\UserDirectory\Model;

use function AuthStack\UserDirectory\routes;
use AuthStack\UserDirectory\Service\RESTService;
use Buckhill\Support\Traits\DotNotationAccessorTrait;

class Policy extends AbstractModel
{
    use DotNotationAccessorTrait;

    protected $service;

    /**
     * @return Policy
     */
    public function create(): Policy
    {
        return $this->__model($this->getService()->create($this->getModel()));
    }

    /**
     * @param int $id
     * @return Policy
     */
    public function read(int $id): Policy
    {
        return $this->__model($this->getService()->read($id));
    }

    /**
     * @param array $data
     * @return bool
     */
    public function update(array $data = []): bool
    {
        $data = array_merge($this->getModel(), $data);

        $result = $this->getService()->update($this->getID(), $data);

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

        return $result;
    }

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

    /**
     * @param array $options
     * @return array
     */
    public function listing(array $options = []): array
    {
        return $this->getService()->listing($options);
    }

    /**
     * @return int
     */
    public function getID(): int
    {
        return (int)$this->dotNotationFromArray($this->model, 'id', 0);
    }

    /**
     * @param string $title
     * @return Policy
     */
    public function setTitle(string $title): self
    {
        $this->model['title'] = $title;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getTitle()
    {
        return $this->model['title'];
    }

    /**
     * @param int $length
     * @return Policy
     */
    public function setMinLength(int $length): self
    {
        $this->model['min_length'] = $length;

        return $this;
    }

    /**
     * @return array|mixed|null
     */
    public function getMinLength()
    {
        return $this->dotNotationFromArray($this->model, 'min_length');
    }

    /**
     * @param int $str
     * @return Policy
     */
    public function setMinStrength(int $str): self
    {
        $this->model['min_strength'] = $str;

        return $this;
    }

    /**
     * @return array|mixed|null
     */
    public function getMinStrength()
    {
        return $this->dotNotationFromArray($this->model, 'min_strength');
    }

    /**
     * @param int $history
     * @return Policy
     */
    public function setHistory(int $history): self
    {
        $this->model['history'] = $history;

        return $this;
    }

    /**
     * @return array|mixed|null
     */
    public function getHistory()
    {
        return $this->dotNotationFromArray($this->model, 'history');
    }

    /**
     * @param int $lockout
     * @return Policy
     */
    public function setLockout(int $lockout): self
    {
        $this->model['lockout'] = $lockout;

        return $this;
    }

    /**
     * @return array|mixed|null
     */
    public function getLockout()
    {
        return $this->dotNotationFromArray($this->model, 'lockout');
    }

    /**
     * @param int $duration
     * @return Policy
     */
    public function setLockoutDuration(int $duration): self
    {
        $this->model['lockout_duration'] = $duration;

        return $this;
    }

    /**
     * @return array|mixed|null
     */
    public function getLockoutDuration()
    {
        return $this->dotNotationFromArray($this->model, 'lockout_duration');
    }

    /**
     * @param int $age
     * @return Policy
     */
    public function setPasswordAge(int $age): self
    {
        $this->model['max_age'] = $age;

        return $this;
    }

    /**
     * @return array|mixed|null
     */
    public function getPasswordAge()
    {
        return $this->dotNotationFromArray($this->model, 'max_age');
    }

    /**
     * @return \AuthStack\UserDirectory\Service\Policy
     */
    public function getService(): RESTService
    {
        if(!$this->service instanceof \AuthStack\UserDirectory\Service\Policy)
        {
            $baseUrl = $this->baseUrl;
            $authType = $this->auth_type;
            $token = $this->auth_token;

            $routes = routes($baseUrl, $authType, $token);

            $this->service = new \AuthStack\UserDirectory\Service\Policy($baseUrl, $routes['options'], $routes['routes']['policy']);

            if(!is_null($this->tz_offset) && !is_null($this->tz_dst))
            {
                $this->service->setTimeZoneOffset($this->tz_offset);
                $this->service->setTimeZoneDST($this->tz_dst);
            }
        }

        return $this->service;
    }

    /**
     * @param \AuthStack\UserDirectory\Service\Policy $service
     * @return $this
     */
    public function setService(RESTService $service)
    {
        $this->service = $service;

        return $this;
    }

    /**
     * @param Organization $model
     * @return Organization
     */
    protected function __model(Policy $model): Policy
    {
        $this->model = $model->getModel();

        return $model->setService($this->getService());
    }
}