<?php

declare(strict_types=1);

/*
 * This file is part of dacore bundle for Contao.
 *
 * (c) Benjamin Roth
 *
 * @license commercial
 */

namespace vossmedien\DacoreBundle\API;

use Contao\System;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use vossmedien\DacoreBundle\Model\KatalogModel;
use vossmedien\DacoreBundle\Model\StelleModel;
use vossmedien\DacoreBundle\Model\StellenModel;

class Softgarden
{
    /**
     * @var SerializerInterface
     */
    protected $serializer;

    /**
     * @var HttpClientInterface
     */
    protected $httpClient;

    protected $clientId;

    protected $apiDomain;

    public function __construct(SerializerInterface $serializer, HttpClientInterface $httpClient)
    {
        $this->serializer = $serializer;
        $this->httpClient = $httpClient;

        $this->clientId = System::getContainer()->getParameter('vossmedien_dacore.softgarden.client_id');
        $this->apiDomain = System::getContainer()->getParameter('vossmedien_dacore.softgarden.api_domain');
    }

    protected function getClientId()
    {
        return $this->clientId;
    }

    protected function getApiDomain()
    {
        return rtrim($this->apiDomain,'/');
    }

    protected function getBasicAuthorization()
    {
        return [$this->getClientId(),''];
    }

    protected function sendRequest(string $relEndpoint, array $options, string $method = 'GET',bool $blnFQDNEndpoint=false)
    {
        if ($blnFQDNEndpoint)
        {
            return $this->httpClient->request($method,$relEndpoint,$options);
        }

        $relEndpoint = '/' . ltrim($relEndpoint,'/');

        return $this->httpClient->request($method,$this->getApiDomain().$relEndpoint,$options);
    }

    public function testApiRequest()
    {
        // bewerber@dacore.api / Aebekai2ail4coum
        $options = [
            'auth_basic' => $this->getBasicAuthorization(),
            'headers' => ['Content-Type: application/json']
        ];

        $response = $this->sendRequest('jobslist/102581_extern',$options);

        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            return json_decode($content);
        }

        return null;
    }

    public function hasApplied(int $jobId, $token_type, $access_token)
    {
        // bewerber@dacore.api / Aebekai2ail4coum
        $options = [
            'headers' => [
                'Authorization: ' . $token_type . ' ' . $access_token
            ]
        ];

        $response = $this->sendRequest('jobs/' . $jobId . '/applied',$options);

        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            return $content == 'true';
        }

        return false;
    }

    public function getApplicationId(int $jobId, $token_type, $access_token)
    {
        // bewerber@dacore.api / Aebekai2ail4coum
        $options = [
            'headers' => [
                'Authorization: ' . $token_type . ' ' . $access_token,
                'Content-Type: application/json'
            ]
        ];

        $response = $this->sendRequest('jobs/' . $jobId . '/application',$options);

        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            return $content;
        }

        return null;
    }

    public function startApplication(int $jobId, $token_type, $access_token)
    {
        // bewerber@dacore.api / Aebekai2ail4coum
        $options = [
            'headers' => [
                'Authorization: ' . $token_type . ' ' . $access_token,
                'Content-Type: application/json'
            ]
        ];

        $response = $this->sendRequest('applications?jobId='.$jobId,$options, 'POST');

        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            return $content;
        }

        return null;
    }

    public function getApplication(string $applicationId, $token_type, $access_token)
    {
        // bewerber@dacore.api / Aebekai2ail4coum
        $options = [
            'headers' => [
                'Authorization: ' . $token_type . ' ' . $access_token,
                'Content-Type: application/json'
            ]
        ];

        $response = $this->sendRequest('applications/' . $applicationId . '?fields=*',$options);

        if ($response->getStatusCode() == 200)
        {
            $content = json_decode($response->getContent());

            return $content;
        }

        return null;
    }

    public function deleteApplication(string $applicationId, $token_type, $access_token)
    {
        // bewerber@dacore.api / Aebekai2ail4coum
        $options = [
            'headers' => [
                'Authorization: ' . $token_type . ' ' . $access_token,
                'Content-Type: application/json'
            ]
        ];

        $response = $this->sendRequest('applications/' . $applicationId,$options,'DELETE');

        if ($response->getStatusCode() == 204)
        {
            return true;
        }

        return false;
    }

    public function createApplicantUser(string $username,string $password,?string $email=null)
    {
        if ($email === null)
        {
            $email = $username;
        }

        $options = [
            'auth_basic' => $this->getBasicAuthorization(),
            'headers' => [
                'Content-Type: application/json'
            ],
            'body' => json_encode([
                'salutation' => 0,
                'firstname' => 'Dacore',
                'lastname' => 'Bewerber',
                'username' => $username,
                'password' => $password,
                'email' => $email,
                'locale' => 'de',
                'dataPrivacyAccepted' => true
            ])
        ];

        $response = $this->sendRequest('applicants',$options,'POST');

        if ($response->getStatusCode() == 204)
        {
            return true;
        }

        return false;
    }

    public function getUserAccessToken($username, $password)
    {
        // bewerber@dacore.api / Aebekai2ail4coum
        $options = [
            'auth_basic' => $this->getBasicAuthorization(),
            'body' => [
                'grant_type' => 'password',
                'username' => $username,
                'password' => $password
            ]
        ];

        $response = $this->sendRequest('https://api.softgarden.io/api/rest/oauth/frontend/token',$options,'POST',true);

        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            return json_decode($content);
        }

        return null;
    }

    public function getStellenFiltered(array $params=[]): ?StellenModel
    {
        $options = [
            'headers' => $this->getAuthorizeRequestHeader()
        ];

        if (count($params))
        {
            $options['query'] = $params;
        }

        $response = $this->sendRequest('Stelle/GetStellenFiltered',$options);



        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            /** @var StellenModel $collection */
            $collection = $this->serializer->deserialize($content,StellenModel::class,'json');

            return $collection;
        }

        return null;
    }

    public function getStelleById(string $uuid, array $params=[]): ?StelleModel
    {
        $options = [
            'headers' => $this->getAuthorizeRequestHeader(),
            'query' => [
                'stelleUuid' => $uuid
            ]
        ];

        if (count($params))
        {
            $options['query'] = array_merge($options['query'],$params);
        }

        $response = $this->sendRequest('Stelle/GetStelleById',$options);



        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            /** @var StelleModel $model */
            $model = $this->serializer->deserialize($content,StelleModel::class,'json');

            return $model;
        }

        return null;
    }

    public function getKatalogByRelationName(string $entityName, string $relationName): ?KatalogModel
    {
        $options = [
            'headers' => $this->getAuthorizeRequestHeader(),
            'query' => [
                'entityName' => $entityName,
                'relationName' => $relationName
            ]
        ];

        $response = $this->sendRequest('Katalog/GetByRelationName',$options);



        if ($response->getStatusCode() == 200)
        {
            $content = $response->getContent();

            /** @var KatalogModel $collection */
            $collection = $this->serializer->deserialize($content,KatalogModel::class,'json');

            return $collection;
        }

        return null;
    }

}