<?php

/**
 * Register all actions and filters for the plugin.
 * @package    Servicebestkoppeling
* @subpackage Servicebestkoppeling/includes
 * @author     Trinco Ingels <info@trincoingels.nl>
 */
class LinkNetwerk_API{

    private $admin;
    private $linknetwerkApiEndpoint = "http://linknetwerk/api/order-created.php";

    /**
     * Initialize the class and set its properties.
     *
     * @since    1.0.0
     */
    public function __construct() {

        $lk = new Linknetwerk();
        $this->admin = new LinkNetwerk_Admin($lk::get_plugin_name(), $lk::get_version());
    }

    private function getParams($request){

        $body = $request->get_body();
        $params = null;
        if(!empty($body)){
            $params = json_decode($body, true);
        }
        if(!$params){
            $params = $request->get_params();
        }
        return $params;
    }

    private function checkAuthentication($params){
        if(!$params)
            return "Authentication error";

        $siteUrl = get_site_url();

        $anchor = url_decode($params['link']);

        $hash = sanitize_text_field($params['hash']);

        if(!$hash || empty($hash) || !preg_match('/^[a-z0-9]+$/', $hash) || is_null($hash))
			return "Param: hash missing";


        $ourhash = hash_hmac('sha256', $anchor.$siteUrl, get_option("lupsOnlineLinkNetwerkApiKey"));
        if($ourhash !== $hash) return "Authentication error";

		return true;
    }

    private function checkBlogAuthentication($params){
        if(!$params)
            return new WP_Error(400, "Authentication error");

        $siteUrl = get_site_url();

        $title = preg_replace("/[^a-zA-Z]+/", "", $params['title']);

        $hash = sanitize_text_field($params['hash']);

        if(!$hash || empty($hash) || !preg_match('/^[a-z0-9]+$/', $hash)) return new WP_Error(400, "Param 'hash' missing");
        $ourhash = hash_hmac('sha256', $title.$siteUrl, get_option("lupsOnlineLinkNetwerkApiKey"));

        if($ourhash !== $hash) return new WP_Error(401, "Authentication error");
    }

    private function checkCategoryAuthentication($params){
        if(!$params)
            return new WP_Error(400, "Authentication error");

        $siteUrl = get_site_url();

        $category = $params['category'];

        $hash = sanitize_text_field($params['hash']);

        if(!$hash || empty($hash) || !preg_match('/^[a-z0-9]+$/', $hash)) return new WP_Error(400, "Param 'hash' missing");
        $ourhash = hash_hmac('sha256', $category.$siteUrl, get_option("lupsOnlineLinkNetwerkApiKey"));

        if($ourhash !== $hash) return new WP_Error(401, "Authentication error");
    }


    public function getLink($request){
        $params = $this->getParams($request);

        if(!$params["pageid"] || !preg_match('/^\d+$/',$params["pageid"])) return new WP_Error(400,"Param pageid missing");

        if(!filter_var(($authenticationError = $this->checkAuthentication($params) ), FILTER_VALIDATE_BOOLEAN)) return new WP_Error(401, $authenticationError);

        return $this->admin->getLink(
            isset($params['id']) ? $params['id'] : null,
            isset($params['pageid']) ? $params['pageid'] : null,
            isset($params['TypeLinkId']) ? $params['TypeLinkId'] : null
        );
    }

    /*
     * Add link to database
     */
    public function addLink($request) {
        $params = $this->getParams($request);
        if(!$params["pageid"] || !preg_match('/^\d+$/',$params["pageid"])) return new WP_Error(400,"Param pageid' missing");

        if($params['linkOrder']) $this->admin->addSetting('linkOrder', $params['linkOrder']);

        $this->checkAuthentication($params);
        return $this->admin->saveLink($params);
    }

    public function changeLink($request) {
        $params = $this->getParams($request);

        if(!$params["pageid"] || !preg_match('/^\d+$/',$params["pageid"])) return new WP_Error(400,"Param 'pageid' missing");

        if($params['linkOrder']) $this->admin->addSetting('linkOrder', $params['linkOrder']);

        $this->checkAuthentication($params);

        return $this->admin->updateLink($params);
    }

    /*
     * Delete link
     * param: Id <int>
     */
    public function deleteLink($request) {
        $params = $this->getParams($request);
        if(!$params["pageid"] || !preg_match('/^\d+$/',$params["pageid"])) return new WP_Error(400,"Param 'pageid' missing");

        $this->checkAuthentication($params);

        return $this->admin->deleteLink($params);
    }


//    public function getBlog($request) {
//        $this->checkAuthentication($request);
//
//        $this->admin->saveBlog($request);
//    }

    public function addBlog($request) {
        $params = $this->getParams($request);
        if(!$params["title"]) return new WP_Error(400,"Param 'title' missing");

        $this->checkBlogAuthentication($params);

        return $this->admin->saveBlog($params);
    }

    public function changeBlog($request) {
        $params = $this->getParams($request);
        if(!$params["title"]) return new WP_Error(400,"Param 'title' missing");

        $this->checkBlogAuthentication($params);

        return $this->admin->updateBlog($params);
    }

    /*
     * Delete blog
     * param: Id <int>
     */
    public function deleteBlog($request) {
        $params = $this->getParams($request);

        if(!$params["pageid"] || !preg_match('/^\d+$/',$params["pageid"])) return new WP_Error(400,"Param 'pageid' missing");

        $this->checkBlogAuthentication($params);

        $this->admin->deleteBlog($params["pageid"]);
    }

    public function getCategories(){
        $categories = get_categories(array('hide_empty'=>false));
        echo json_encode($categories, true);
    }

    public function addCategory($request){
        $params = $this->getParams($request);

        if(!$params["category"]) return new WP_Error(400,"Param 'category' missing");

        $this->checkCategoryAuthentication($params);

        $this->admin->addCategory($params["category"]);

        return json_encode("Ok");
    }

    public function apiCall($data, $method){
        $error_msg = false;
		$curl = curl_init();

        curl_setopt( $curl, CURLOPT_URL, $this->linknetwerkApiEndpoint );
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );

        if($method == "POST"){
            curl_setopt( $curl, CURLOPT_POST, 1 );
            curl_setopt( $curl, CURLOPT_POSTFIELDS, json_encode($data, true) );
        }

	date_default_timezone_set('UTC');
	date_default_timezone_set('Europe/Amsterdam');
	$xTimestamp = (new Datetime)->format('Y-m-d\TH:i:s');
	$xHash = hash_hmac('sha256', json_encode($data, true).$xTimestamp, get_option("lupsOnlineLinkNetwerkWebshopLicenseKey"));

        $headers = array(
            'Content-Type: application/json'
            , sprintf('x-timestamp: %s', $xTimestamp)
            , sprintf('x-referer: %s', get_site_url())
            , sprintf('x-hash: %s', $xHash)
        );

        curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers); // Inject the token into the header
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, 1);
        $result = curl_exec($curl);
        $http_status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if (curl_errno($curl)) {
            $error_msg = curl_error($curl);
        }

        curl_close($curl);

        if(!($http_status_code >= 200 && $http_status_code <= 300) && !$error_msg){
            $error_msg = json_decode($result,true);
            $error_msg = $error_msg['message'];
        }
        if($error_msg){
            // Requests and response logging.
            error_log(print_r("\nDatum: ".date('Y-m-d H:i:s')."\nPath: ".$path."\nMethod:".$method."\nRequest: ".json_encode($data), true), 3, plugin_dir_path( dirname( __FILE__ ) )."api_transaction.log");
            error_log(print_r("\nResponse: ".$http_status_code. ":".$result, true), 3, plugin_dir_path( dirname( __FILE__ ) )."api_transaction.log");
            error_log(print_r("\nError: ".$http_status_code. ":".$error_msg, true), 3, plugin_dir_path( dirname( __FILE__ ) )."api_transaction.log");
            throw new Exception($error_msg, $http_status_code);
        }

        return json_decode($result, true);
    }
}
