<?php

class Pixel
{
    static $strapiHost = 'http://172.26.14.5:1337';
    static $funnel;
    static $cacheFile = __DIR__ . '/pixels.json';
    static $cacheDuration = 300;
    static $authToken = 'db1f67b4088fe06e48198cf453aad4247cb4ba82a294a25cafb08f1aa1c98ca8debd94bd67d668cc7efff2f8dae29cb7f5cb85ae6f63524ddcc228e2953845d7452f4819cd3ba64d05fbde95e80b91984d205fccaeb5e6a3a9a018548fb145cd96d21fb2f1a7672d1788d8b99b461801800bbedf66c4045a672191e3584bd0b8';

    public static function render($funnel, $event)
    {
        try {
            self::$funnel = $funnel;
            $response = self::fetchWithCache();
            $responseParsed = json_decode($response, true);
            foreach ($responseParsed['data'] as $key => $value) {
                if (!empty($value['attributes']['event']) && in_array($value['attributes']['event'], $event)) {

                    // Check for should_match condition
                    $shouldMatch = true;
                    if (!empty($value['attributes']['only_if_matches'])) {
                        $shouldMatch = self::checkShouldMatch($value['attributes']['only_if_matches']);
                    }

                    // Proceed only if shouldMatch is true
                    if ($shouldMatch) {
                        // If the affiliate_id is empty, then render the pixel code for all affiliates
                        if (empty($value['attributes']['affiliate_id'])) {
                            echo self::replacePlaceholders($value) . "\n";
                        }

                        if (!empty($value['attributes']['affiliate_id']) && !empty($_SESSION['kk_affid']) && $value['attributes']['affiliate_id'] == $_SESSION['kk_affid']) {
                            echo self::replacePlaceholders($value) . "\n";
                        }
                    }
                }
            }
        } catch (Exception $e) {
            echo "<!-- Pixel render exception -->\n";
            if (isset($_GET['__debug'])) {
                echo $e->getMessage(), "\n";
                echo $e->getTraceAsString(), "\n";
            }
        }
    }

    public static function replacePlaceholders($pixel)
    {
        $pixelId = $pixel['id'];

        if (
            $pixel['attributes']['event'] !== 'pageview'
            && !empty($_SESSION['pixel_render_logs'])
            && in_array($pixelId, $_SESSION['pixel_render_logs'])
        ) {
            return sprintf('<!-- Pixel render exception(id:%d): skipping duplicate render -->', $pixelId);
        }

        // Match {{session|key}} and {{get|key}} patterns
        $dataURI = preg_replace_callback('/{{(SESSION|GET)\|([^}]+)}}/', function ($matches) {
            $type = $matches[1];
            $key = $matches[2];

            if ($type == 'SESSION' && isset($_SESSION[$key])) {
                return $_SESSION[$key];
            } elseif ($type == 'GET' && isset($_GET[$key])) {
                return $_GET[$key];
            } else {
                return ''; // Return empty string if the key is not found
            }
        }, $pixel['attributes']['code']);

        if (preg_match('/\[POSTBACK\](.*?)\[\/POSTBACK\]/', $dataURI, $matches)) {
            $postbackUrl = $matches[1];

            $curl = curl_init();

            curl_setopt_array($curl, [
                CURLOPT_URL => $postbackUrl,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => "GET",
            ]);

            $response = curl_exec($curl);
            $curlError = curl_error($curl);
            if ($curlError) {
                return '<!-- Postback error: ' . $postbackUrl . ':' . $curlError .  ' -->';
            } else {
                $_SESSION['pixel_render_logs'][] = $pixelId;
                return '<!-- Postback success: ' . $postbackUrl . ':' . $response .  ' -->';
            }
        } else {
            $_SESSION['pixel_render_logs'][] = $pixelId;
            return $dataURI;
        }
    }

    public static function fetch()
    {
        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_URL => self::$strapiHost . "/api/pixels?filters%5Bfunnel%5D%5B%24eq%5D=" . self::$funnel,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_POSTFIELDS => "",
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer " . self::$authToken,
                "Content-Type: application/json",
                "User-Agent: insomnia/9.2.0"
            ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
            throw new Exception("cURL Error #:" . $err);
        }

        return $response;
    }

    public static function fetchWithCache()
    {
        // Check if cache burst parameter is set
        if (isset($_GET['__cache_burst'])) {
            $data = self::fetch();
            file_put_contents(self::$cacheFile, $data);
            return $data;
        }

        // Check if cache file exists and is not older than the cache duration
        if (file_exists(self::$cacheFile)) {
            $fileModifiedTime = filemtime(self::$cacheFile);
            if (time() - $fileModifiedTime < self::$cacheDuration) {
                return file_get_contents(self::$cacheFile);
            }
        }

        // Fetch fresh data and cache it
        $data = self::fetch();
        file_put_contents(self::$cacheFile, $data);
        return $data;
    }

    public static function checkShouldMatch($shouldMatch)
    {
        foreach ($shouldMatch as $type => $key) {
            $negate = false;
            if (strpos($key, '!') === 0) {
                $negate = true;
                $key = substr($key, 1);
            }

            if ($type == 'GET') {
                if (($negate && isset($_GET[$key])) || (!$negate && !isset($_GET[$key]))) {
                    return false;
                }
            } elseif ($type == 'SESSION') {
                if (($negate && isset($_SESSION[$key])) || (!$negate && !isset($_SESSION[$key]))) {
                    return false;
                }
            }
        }
        return true;
    }
}
