<?php

namespace WoWPress\Api;

use WoWPress\Database\Cache;

abstract class Api
{
    protected $api_url;
    private $api_key;
    private $api_id;


    public function __construct($api_id, $api_key)
    {
        $this->api_id = $api_id;
        $this->api_key = $api_key;
    }

    protected function auth()
    {
        return $this->api_key;
    }



    protected function bearer()
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://us.battle.net/oauth/token');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
        curl_setopt($ch, CURLOPT_USERPWD, $this->api_id . ':' . $this->api_key);

        $headers = array();
        $headers[] = 'Content-Type: application/x-www-form-urlencoded';
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $result = json_decode(curl_exec($ch), 1);
        if (curl_errno($ch)) {
            return false;
        }
        curl_close($ch);
        if (!empty($result['error'])) {
            return false;
        }
        $apitoken = $result;
        $bearer = $apitoken['access_token'];

        return $bearer;
    }

    public function put($url, $parameter = [], $headerauth = true)
    {
        $result = "{}";
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $this->api_url . $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $data_json = json_encode($parameter);

        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);

        $headers = array('Content-Type: application/json', 'Content-Length: ' . strlen($data_json));
        $headers[] = 'Accept: application/json';
        if ($headerauth) {
            $headers[] = 'Authorization: ' . $this->api_key;
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);


       

        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            error_log('Error:' . curl_error($ch));
            return false;
        }
        curl_close($ch);
        $out = json_decode($result, true, 512, JSON_INVALID_UTF8_SUBSTITUTE);
        if (json_last_error()) {
            error_log('Error:' . json_last_error_msg());
            return false;
        } else {
            return $out;
        }
    }

    public function post($url, $parameter = [], $headerauth = true)
    {
        $result = "{}";
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $this->api_url . $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $data_json = json_encode($parameter);

        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);

        $headers = array('Content-Type: application/json', 'Content-Length: ' . strlen($data_json));
        $headers[] = 'Accept: application/json';
        if ($headerauth) {
            $headers[] = 'Authorization: ' . $this->api_key;
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);



        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            error_log('Error:' . curl_error($ch));
            return false;
        }
        curl_close($ch);
        $out = json_decode($result, true, 512, JSON_INVALID_UTF8_SUBSTITUTE);
        if (json_last_error()) {
            error_log('Error:' . json_last_error_msg());
            return false;
        } else {
            return $out;
        }
    }

    public function get($url, $parameter = [], $headerauth = true, $expiration = 5)
    {
        $from_cache = true;
        $result = "{}";
        if (!str_contains($url, "https:/")) {
            $url = $this->api_url . $url;
        }else{
            $parts = parse_url($url);
            parse_str($parts['query'], $query);
            $parameter = array_merge($parameter,$query);
            $url = strtok($url, '?');
        }

        $cache_key = Cache::buildKey([
            $url,
            http_build_query($parameter),
            $headerauth ? "true" : "false",
        ]);


        $cache = Cache::where('p_key', $cache_key)->get()->last();


          if(empty($cache->ID) || $cache->isExpired($expiration)){
        $ch = curl_init();
        if (!empty($parameter)) {
            $parameter = http_build_query($parameter);
            curl_setopt($ch, CURLOPT_URL, $url . "?" . $parameter);
        } else {
            curl_setopt($ch, CURLOPT_URL, $url);
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');


        $headers = array();
        $headers[] = 'Accept: application/json';
        if ($headerauth) {
            $headers[] = 'Authorization: ' . $this->api_key;
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($ch);
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($response, 0, $header_size);
        $result = substr($response, $header_size);
        if (curl_errno($ch)) {
            error_log('Error:' . curl_error($ch));
            return false;
        }

        $cache = Cache::upsert($cache_key, $result);
        $from_cache = false;
             }

        if (!is_array($cache->value)) {
            return ['error' => true];
        }

        return array_merge($cache->value, compact('from_cache'));
    }
}