<?php

namespace ZohoMailPostSMTP;

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

/**
 * ZohoMailOauth
 */
class ZohoMailOauth {
    
    /**
     * settings
     *
     * @var mixed
     */
    private $settings;
    
    /**
     * __construct
     *
     * @param  mixed $settings
     * @return void
     */
    public function __construct( $settings = array() ) {
        $this->settings = $settings;
    }
    
    /**
     * getZohoMailAuthURL
     *
     * @param  mixed $state
     * @return void
     */
    public function getZohoMailAuthURL( array $options ) {
        $base   = $this->settings['urlAuthorize'];
        $params = $this->getZohoMailAuthParams( $options );
        $query  = $this->getAuthEncodedQuery( $params );

        return $this->attachQuery( $base, $query );
    }
    
    /**
     * getZohoMailAccountDetails
     *
     * @param  mixed $token
     * @param  mixed $url
     * @return void
     */
    public function getZohoMailAccountDetails( $token, $url ) {
        $headers  = array(
            'method' => 'GET',
            'headers' => array(
                'Authorization' => 'Zoho-oauthtoken ' . $token,
                'content-type' => 'application/json'
            )
        );
        $response   = wp_remote_get( $url, $headers );
        $body       = json_decode( wp_remote_retrieve_body( $response ) );
        $data       = (array) reset( $body->data );
        $meta       = (array) reset( $data['sendMailDetails'] );
        $userDetails = array(
            'accountId' => @$data['accountId'],
            'fromAddress' => @$meta['fromAddress'],
        );
        return $userDetails;
    }
    
    /**
     * getZohoMailAuthParams
     *
     * @param  mixed $options
     * @return void
     */
    private function getZohoMailAuthParams( array $options ) {
        if ( empty( $options['scope'] ) ) {
            $options['scope'] = $this->settings['scopes'];
        }

        $options += array( 
            'response_type' => 'code',
            'prompt'        => 'consent',
            'access_type'   => 'offline'
        );

        if ( !isset( $options['redirect_uri'] ) ) {
            $options['redirect_uri'] = $this->settings['redirectUri'];
        }

        $options['client_id'] = $this->settings['clientId'];
       
        return $options;
    }
    
    /**
     * getAuthEncodedQuery
     *
     * @param  mixed $params
     * @return void
     */
    private function getAuthEncodedQuery( array $params ) {
        return $this->GenerateSerializeQuery( $params );
    }
    
    /**
     * GenerateSerializeQuery
     *
     * @param  mixed $params
     * @return void
     */
    private function GenerateSerializeQuery( array $params ) {
        return http_build_query( $params, '', '&', \PHP_QUERY_RFC3986 );
    }
    
    /**
     * attachQuery
     *
     * @param  mixed $url
     * @param  mixed $query
     * @return void
     */
    private function attachQuery( $url, $query ) {
        $query = trim($query, '?&');

        if ($query) {
            $glue = strstr($url, '?') === false ? '?' : '&';
            return $url . $glue . $query;
        }

        return $url;
    }
    
    /**
     * getZohoMailAccessToken
     *
     * @param  mixed $grant
     * @param  mixed $options
     * @return void
     */
    public function getZohoMailAccessToken( $grant, array $options = array() ) {
        $params = array(
            'client_id'     => $this->settings['clientId'],
            'client_secret' => $this->settings['clientSecret'],
            'redirect_uri'  => $this->settings['redirectUri'],
            'grant_type' => $grant,
        );
        $params += $options;
       
        $requestData = $this->zohoMailGetAccessTokenRequest($params);
        $response = wp_remote_request($requestData['url'], $requestData['params']);
        
        if (is_wp_error($response)) {
            throw new \Exception(
                $response->get_error_message()
            );
        }

        $responseBody = wp_remote_retrieve_body($response);

        if (false === is_array( $response ) ) {
            throw new \Exception(
                'Invalid response received from Authorization Server. Expected JSON.'
            );
        }

        if(empty(['access_token'])) {
            throw new \Exception(
                'Invalid response received from Authorization Server.'
            );
        }

        return \json_decode($responseBody, true);
    }
    
    /**
     * zohoMailGetAccessTokenRequest
     *
     * @param  mixed $params
     * @return void
     */
    protected function zohoMailGetAccessTokenRequest( $params ) {
        $method  = "POST";
        $url     = $this->getZohoMailAccessTokenUrl($params);
        $options = $this->GenerateSerializeQuery($params);
        
        return [
            'url' => $url,
            'params' => [
                'method' => $method,
                'body' => $options,
                'headers' => [
                    'content-type' => 'application/x-www-form-urlencoded'
                ]
            ]
        ];
    }
    
    /**
     * getZohoMailAccessTokenUrl
     *
     * @param  mixed $params
     * @return void
     */
    protected function getZohoMailAccessTokenUrl( $params ) {
        $url = $this->settings['urlAccessToken'];
        return $url;
    }
    
    /**
     * disconnect_zoho_account_request
     *
     * @return void
     */
    public function disconnect_zoho_account_request() {
        $url        = $this->settings['urlRevokeRefreshToken'];
        $tokenCache = new ZohoMailTokenCache();
        $tokenCache->revokeZohoMailTokens( $url );
    }
}

