<?php

namespace AuthStack\UserDirectoryAPI\Model;

use function AuthStack\UserDirectoryAPI\routes;
use AuthStack\UserDirectoryAPI\Service\RESTService;

abstract class Model
{
    protected $model;
    protected $tz_offset;
    protected $tz_dst;
    protected $baseUrl;
    protected $token;
    protected $cfg;
    protected $provider;

    /**
     * @var RESTService
     */
    protected $service;

    public function __construct(array $model = [])
    {
        $this->model = $model;
    }

    /**
     * @param $prop
     * @return mixed|null
     */
    public function __get($prop)
    {
        return isset($this->model[$prop]) ? $this->model[$prop] : null;
    }

    /**
     * Returns a string key that represents routes entry in routes.php
     *
     * @return mixed
     */
    protected function getConfigSection()
    {
        return $this->cfg;
    }

    /**
     * Returns class name (in Service namespace) that handles REST operations for this model
     *
     * @return mixed
     */
    protected function getRESTServiceProvider()
    {
        return $this->provider;
    }

    /**
     * @return RESTService
     */
    public function getService(): RESTService
    {
        if(empty($this->service))
        {
            $routes = routes($this->baseUrl, $this->token);

            $service = $this->getRESTServiceProvider();

            $this->service = new $service($this->baseUrl, $routes['options'], $routes['routes'][$this->getConfigSection()]);

            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 RESTService $service
     * @return $this
     */
    public function setService(RESTService $service): self
    {
        $this->service = $service;

        return $this;
    }

    /**
     * @param string $url
     * @return Model
     */
    public function setBaseUrl(string $url): self
    {
        $this->baseUrl = $url;

        return $this;
    }

    /**
     * @param string $token
     * @return Model
     */
    public function setBearerToken(string $token): self
    {
        $this->token = $token;

        return $this;
    }

    /**
     * @param string $offset
     * @return Model
     */
    public function setTimeZoneOffset(string $offset): self
    {
        $this->tz_offset = $offset;

        return $this;
    }

    /**
     * @param string $dst
     * @return Model
     */
    public function setTimeZoneDST(string $dst): self
    {
        $this->tz_dst = $dst;

        return $this;
    }

    /**
     * @return array
     */
    public function getModel(): array
    {
        return $this->model;
    }

    /**
     * @param string $name
     * @param $value
     * @return $this
     */
    protected function setProperty(string $name, $value): self
    {
        $this->model[$name] = $value;

        return $this;
    }
}