<?php

namespace App\Services\Integrations\SoftwareLicense;

use Exception;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class SlackIntegration
{
    protected $name;
    protected $baseUrl;
    protected $apiVersion;
    protected $itemsPerpageSize = 3;

    /**
     * Constructor for DropboxIntegration
     * 
     */
    public function __construct()
    {
        $this->name = 'Slack';
        $this->baseUrl = config('services.slack.base_url');
        $this->apiVersion = config('services.slack.api_version');
    }

    /**
     * It sends a POST request to the API endpoint with the data provided and returns the response in JSON format
     * 
     * @param name The name of the API you are calling.
     * @param url The url of the API endpoint you want to call.
     * @param data The data to be sent to the API.
     * 
     * @return mixed response from the API call.
     */
    public function getApiResponse($accessToken, $name, $url, $data='')
    {
        $apiURL =  $this->baseUrl . $url;
        
        try {
            $response =  Http::withToken($accessToken)            
            ->get($apiURL)
            ->json();      

            return $response;
        } catch   (Exception $e) {
            Log::channel('daily')->info($name." fetch error ---- " . $e->getMessage());
            
            return false;
        }
    }

    /**
     * It generates the access token using authorization code received from softeware aseet api authentication
     *
     * @param string $code The authorization code you received from the previous step.
     * @param string $redirectURL callback URL for oauth2 flow
     * @param string $key client key
     * @param string $password client secret
     * 
     * @return mixed response is a JSON object containing the access token, the token type, and the number of seconds until the token expires and refresh token.
     */
    public function generateAccessToken($code, $redirectURL, $key,  $password)
    {
        try {
            $data = [
                'grant_type' => 'authorization_code',
                'code' => $code,
                'redirect_uri' => $redirectURL
            ];
            $response = Http::asForm()
            ->withBasicAuth($key,  $password)
            ->post($this->baseUrl . '/oauth.v2.access', $data)->throw()->json();

            return $response;
        } catch (Exception $e) {
            Log::channel('daily')->info($this->name . " Error :- " . $e->getMessage());

            return false;
        }
    }
    
    /**
     * It refreshes the token.
     * 
     * @param mixed $tokenData
     * @param string $key client key
     * @param string $password client secret
     * 
     * @return mixed response is a JSON object with the following fields:
     */
    public function refreshToken($tokenData, $key, $password)
    {
        if (empty($tokenData)) {
            return false;
        }

        try {
            $data = [
                'grant_type' => 'refresh_token',
                'refresh_token' => $tokenData['refresh_token']
            ];
            $response = Http::asForm()
            ->withBasicAuth($key,  $password)
            ->post($this->baseUrl . '/oauth.v2.access', $data)->throw()->json();

            return $response;
        } catch (Exception $e) {
            Log::channel('daily')->info($this->name . " Error :- " . $e->getMessage());

            return false;
        }
    }
    
    /**
     * It check software asset API connection status
     * 
     * @param string $accessToken
     * @return int
     */
    public function checkConnection($accessToken)
    {
        $response = $this->getApiResponse($accessToken, $this->name . ' info', '/auth.teams.list');

        return  isset($response['ok'])  ? $response['ok'] : false;
    }
   
    /**
     * This function updates the number of licenses purchased for a Dsoftware asset
     * 
     * @param string $accessToken
     * 
     * @return bool 
     */
    public function updateLicencePurchasedCount($accessToken)
    {
        $response  =  $this->getApiResponse($accessToken, $this->name . ' info','/team.billableInfo');
        
        return '';
    }

    /**
     * It fetches team members of software asset from API
     * 
     * @param string $accessToken
     * @param mixed $nextPageToken
     * 
     * @return mixed
     */
    public function getSoftwareAssetMemberList($accessToken, $nextPageToken)
    {
        $url  = '/users.list?limit=' . $this->itemsPerpageSize;

        if ($nextPageToken) {
            $url  =  '/users.list?limit=' . $this->itemsPerpageSize . '&cursor=' . $nextPageToken;
        }

        return $this->getApiResponse($accessToken, $this->name . ' member list', $url);  
    }
}
