<?php

namespace Blazemedia\Affiliation\Rendering\DirectLink;

use Blazemedia\Affiliation\Utils\HttpRequest;

/**
 * Sono i parametri per i link diretti 
 * ( tipicamente Amazon/eBay )
 */
class ImpactAttributes extends Attributes {

    protected function setDirectLinkAttributes() {


        $this->label = 'Impact';
        $this->code  = 'impt';

        $program = $this->getProgramData();

        $this->program        = $program->name;
        $this->program_suffix = $program->suffix;
        $this->subject        = $program->subject;
        $this->subject_code   = $program->subject_code;
        $this->theme_label    = $program->theme_label;
        $this->theme_code     = $program->theme_code;
        $this->built_url      = $program->built_url;
    }


    protected function getProgramData() {
        $impactDomains = $this->getCachedDomains();

        usort($impactDomains, function ($a, $b) {
            return (strlen($a) > strlen($b)) ? -1 : 1;
        });

        $programDomain = array_filter($impactDomains, fn ($impactDomain) => str_contains(strtolower($this->url), $impactDomain));
        $programDomain = !empty($programDomain) ? array_shift($programDomain) : '';

        $program = $this->getCachedProgram($programDomain);

        // Se l'api non trova un programma, ritorna vuoto e stampa un errore
        if (empty($program)) {
            $this->printError($this->url, $programDomain);
            return $this->getEmptyProgram();
        }
        return $this->dataAdapt($program);
    }


    protected function dataAdapt($program) {
        $deepLink     = $program->impact->deeplink_domain;
        $publisher_id = '2643607';
        $ads_id       = $program->impact->ads_id;
        $program_id   = $program->impact->program_id;

        if (substr($deepLink, -1) !== '/') {
            $deepLink .= '/';
        }

        $deepLinkDomain = $deepLink . "c/" . $publisher_id . "/" . $ads_id . "/" . $program_id;
        $queryStringArr = [
            'subId1' => 'booBLZTRKood',
            'u'      => $this->url
        ];
        $urlBuilder = $deepLinkDomain . '?' . http_build_query($queryStringArr);

        return (object) [

            'name'         => $program->name,
            'suffix'       => $program->program_suffix,
            'subject'      => $program->related_subject,
            'subject_code' => $program->related_subject_code,
            'theme_label'  => $program->related_theme,
            'theme_code'   => $program->related_theme_code,
            'built_url'    => $urlBuilder,
        ];
    }


    protected function printError($link, $domainError) {

        if (!is_user_logged_in()) return;

        $awinError = <<<HTML
        <div class      = "awinerror">
                <h2>ERRORE Mapping Impact </h2>                    
                Il link: {{ link }}<br>
                Presenta l'id programma {{ program_id }} non mappato
                Classe: {{ class }}
            </div>
            <style>.awinerror{ background: red; color: white }</style>
        HTML;

        echo str_replace(
            ['{{ link }}', '{{ program_id }}', '{{ class }}'],
            [$link,        $domainError, __CLASS__],
            $awinError
        );
    }


    /**
     * Ottiene i domini dall'API e li memorizza in un transient per 1 ora.
     *
     * @return array Impact Domains
     */
    private function getCachedDomains() {

        $transientKey = 'impact_api_domain';

        $cachedData = get_transient($transientKey);

        if (false === $cachedData) {
            $apiData = $this->fetchDataFromApi();

            set_transient($transientKey, $apiData, 3600);

            $cachedData = $apiData;
        }

        return $cachedData;
    }

    /**
     * Ottiene i Programmi per un dominio e li mantiene in cache per un giorno.
     *
     * @return array Impact Domains
     */
    private function getCachedProgram($identifier) {

        $transientKey = 'impact_program_' . $identifier;

        $cachedData = get_transient($transientKey);

        if (false === $cachedData) {
            $apiData = $this->fetchProgramData($identifier);

            set_transient($transientKey, $apiData, 3600);

            $cachedData = $apiData;
        }

        return $cachedData;
    }

    protected function fetchProgramData($identifier) {
        $apicall = BLZ_API_RENDERING_MANAGER . 'programby/impact/' . $identifier;

        $maxRetries = 3;
        $currentRetry = 0;

        while ($currentRetry < $maxRetries) {
            $response = json_decode(HttpRequest::getContent($apicall));
            if ($this->isApiResponseValid($response)) {
                return $response;
            }

            $currentRetry++;
        }

        return null;
    }


    /**
     * @return array
     */
    private function fetchDataFromApi() {
        $apicall = BLZ_API_RENDERING_MANAGER . 'programby/impact_domains/';
        return json_decode(HttpRequest::getContent($apicall), true);
    }


    private function isApiResponseValid($response) {
        return (
            $response !== null &&
            count((array)$response) > 0 &&
            !(
                isset($response->status) &&
                in_array($response->status, ['error', 404])
            )
        );
    }


    private function getEmptyProgram() {
        return (object) [
            'name'         => '',
            'suffix'       => '',
            'subject'      => '',
            'subject_code' => '',
            'theme_label'  => '',
            'theme_code'   => '',
            'built_url'    => ''
        ];
    }
}
