<?php

namespace onespace\tools\activeApi\components\clients;

use app\models\User;
use bizley\jwt\Jwt;
use Yii;
use yii\base\Component;
use yii\helpers\ArrayHelper;

class OneSpaceIdClient extends Component {
    public $serverUrl = null;
    public $defaultHeaders = [];

    public const NOTIFY_METHOD_PUSH_NOTIFICATION = 'push';
    public const NOTIFY_METHOD_SMS = 'sms';
    public const NOTIFY_METHOD_EMAIL = 'email';
    public const NOTIFY_METHOD_BLANK_EMAIL = 'email_blank';
    public const NOTIFY_METHOD_BLANK_EMAIL_AND_PUSH = 'email_blank_and_push';

    public const NOTIFY_ACTION_SHOW_MESSAGES = 'showmessages';
    public const NOTIFY_ACTION_ENROL_ACCEPTED = 'showaccepted';
    public const NOTIFY_ACTION_ENROL_REJECTED = 'showrejected';
    public const NOTIFY_ACTION_ENROLMENTS = 'showenrolments';
    public const NOTIFY_ACTION_ACCESS_DEVICES = 'showdevices';

    public function init() {
        if ($this->serverUrl == null) {
            $this->serverUrl = Yii::$app->params['serviceUrls']['userApi'];
        }
        if (isset(Yii::$app->request) && Yii::$app->request instanceof yii\web\Request) {
            $this->defaultHeaders['X-Forwarded-For'] = Yii::$app->request->getUserIP();
        }
    }

    /**
     * @return User|string|null
     */
    public function login($payload = [], $headers = []) {
        /** @var OneSpaceServiceClient $client */
        $client = Yii::$app->onespaceServiceClient;

        $url = $this->serverUrl . 'login';

        $response = $client->post($url, ['data' => $payload], ArrayHelper::merge($this->defaultHeaders, $headers))->send();

        if ($response->isOk) {
            if (ArrayHelper::getValue($response->data, 'data.success', false)) {
                // user has logged in
                // need to get the user ID out of the token
                $user = User::findIdentityByAccessToken(ArrayHelper::getValue($response->data, 'data.token'), Jwt::class);
                $user->authToken = ArrayHelper::getValue($response->data, 'data.token');
                $user->refreshToken = ArrayHelper::getValue($response->data, 'data.refresh');
                return $user;
            } else {
                $errors = [];
                // there may be multiple error objects
                foreach (ArrayHelper::getColumn(ArrayHelper::getValue($response->data, 'errors', []), 'meta', []) as $error => $fieldErrors) {
                    // each error object may have multiple errors per field
                    foreach ($fieldErrors as $field => $messages) {
                        $errors = ArrayHelper::merge($errors, $messages);
                    }
                }
                // we have reduced the errors down to a single list that can be imploded
                return implode(', ', $errors);
            }
        }
        return null;
    }

    /**
     * @return User|string|null
     */
    public function validatePassword($userGuid, $password) {
        /** @var OneSpaceServiceClient $client */
        $client = Yii::$app->onespaceServiceClient;

        $url = $this->serverUrl . 'validate-password';

        $response = $client->post($url, ['data' => ['userId' => $userGuid, 'password' => $password]])->send();

        if ($response->isOk) {
            return ArrayHelper::getValue($response->data, 'data.success', false);
        }
        return null;
    }

    public function expandToken($token, $newClaims = [], $headers = []) {
        /** @var OneSpaceServiceClient $client */
        $client = Yii::$app->onespaceServiceClient;

        $url = $this->serverUrl . 'expand-token';

        $response = $client->post($url, ['data' => ['token' => $token, 'additionalClaims' => $newClaims]], ArrayHelper::merge($this->defaultHeaders, $headers))->send();

        if ($response->isOk) {
            return ArrayHelper::getValue($response->data, 'data.token', false);
        }
        return false;
    }

    public function getAllowedUsers() {
        /** @var OneSpaceServiceClient $client */
        $client = Yii::$app->onespaceServiceClient;

        $url = Yii::$app->params['serviceUrls']['userUi'] . 'licence-service/allowed-users';

        $response = $client->post($url)->send();


        if (!$response->isOk) {
            print_r($response->content) and die;
            // return false;
        }

        return $response->data;
    }

    /**
     * Sends request to 1iD for notification.
     * @param array $payload Notification payload.
     * @see \app\models\auth\Notification
     * @return bool
     */
    public function notifyUser(array $payload): bool {

        /** @var OneSpaceServiceClient $client */
        $client = Yii::$app->onespaceServiceClient;

        $url = $this->serverUrl . 'notify';
        $response = $client->post($url, ['data' => $payload])->send();

        if (!$response->isOk || ArrayHelper::getValue($response->data, 'data.success', false) === false) {
            Yii::error("Error sending notification: " . json_encode($response->getData()));
            return false;
        }

        return true;
    }
}
