<?php
namespace NewsletterBridge\Config;

/**
 * Classe per gestire la configurazione della newsletter
 */
class NewsletterConfig {
    
    /**
     * Ottiene la configurazione completa della newsletter
     * In multisite, dopo switch_to_blog(), legge le opzioni del sito corrente
     * Se non trova opzioni per il sito, prova a leggere le network options come fallback
     * 
     * @param int|null $site_id ID del sito per cui leggere le configurazioni (solo multisite)
     */
    public static function getConfig($site_id = null) {
        // Se viene passato un site_id specifico e siamo in multisite, cambia il contesto
        $switched_blog = false;
        $original_blog_id = null;
        if ($site_id !== null && function_exists('is_multisite') && is_multisite() && function_exists('switch_to_blog')) {
            $current_blog_id = function_exists('get_current_blog_id') ? get_current_blog_id() : 1;
            if ($current_blog_id != $site_id) {
                $original_blog_id = $current_blog_id;
                switch_to_blog($site_id);
                $switched_blog = true;
            }
        }
        
        try {
            // Supporto per WordPress Network (Multisite)
            $is_multisite = function_exists('is_multisite') && is_multisite();
            // Se abbiamo fatto lo switch, passa null così usa il contesto corrente, altrimenti passa $site_id
            $option_site_id = $switched_blog ? null : $site_id;
            $domain = self::get_option_safe('newsletter_domain', '', $is_multisite, $option_site_id);
        
            // Default feeds se il campo è vuoto
            $defaultFeeds = self::getDefaultFeedsConfig();
            $feedsJson = self::get_option_safe('newsletter_feeds', $defaultFeeds, $is_multisite, $option_site_id);
            if (empty($feedsJson) || $feedsJson === '[]') {
                $feedsJson = $defaultFeeds;
            }
            
            // Default dates se il campo è vuoto
            $defaultDates = '[{"date":"XXXX-01-01","description":"Capodanno"},{"date":"XXXX-01-06","description":"Epifania"},{"date":"XXXX-04-25","description":"Festa della liberazione"},{"date":"XXXX-05-01","description":"Festa del lavoro"},{"date":"XXXX-06-02","description":"Festa della Repubblica Italiana"},{"date":"XXXX-08-15","description":"Ferragosto (Assunta)"},{"date":"XXXX-11-01","description":"Festa dei Santi"},{"date":"XXXX-12-08","description":"Immacolata Concezione"},{"date":"XXXX-12-25","description":"Natale"},{"date":"XXXX-12-26","description":"Santo Stefano"}]';
            $datesJson = self::get_option_safe('newsletter_dates', $defaultDates, $is_multisite, $option_site_id);
            if (empty($datesJson) || $datesJson === '[]') {
                $datesJson = $defaultDates;
            }
            
            // Decodifica i feed
            $feeds = json_decode($feedsJson, true) ?: [];
            $feeds = array_map(function($feed) {
                return self::arrayToObject($feed);
            }, $feeds);
            
            // Decodifica le date
            $dates = json_decode($datesJson, true) ?: [];
            $dates = array_map(function($date) {
                return (object) $date;
            }, $dates);
            
            // Configurazione MailUp (se disponibile)
            $mailupConfig = self::getMailupConfig($site_id);
        
            // Titolo newsletter
            // Ora che abbiamo fatto lo switch (se necessario), possiamo usare get_bloginfo() che userà il contesto corrente
            $site_name = get_bloginfo('name');
            $default_title = $site_name . ' - Tutte le news del {{date}}';
            
            // Quando abbiamo fatto lo switch, passiamo null a get_option_safe così usa il contesto corrente
            $newsletter_title = self::get_option_safe('newsletter_title', $default_title, $is_multisite, $option_site_id);
            
            $config = (object) [
                'domain' => $domain,
                'xmlDir' => '/nl-feed/',
                'feeds' => $feeds,
                'datesToExclude' => $dates,
                'mailup' => $mailupConfig,
                'newsletter_title' => $newsletter_title
            ];
            
            return $config;
        } finally {
            // NON ripristinare il contesto qui - lascia che sia gestito dal chiamante
            // Se il contesto è stato cambiato dall'esterno (es. nel comando), non vogliamo ripristinarlo qui
            // perché potrebbe essere ancora necessario per altre operazioni
            // Il ripristino verrà fatto nel comando alla fine
        }
    }
    
    /**
     * Ottiene la configurazione MailUp
     * 
     * @param int|null $site_id ID del sito per cui leggere le configurazioni (solo multisite)
     */
    private static function getMailupConfig($site_id = null) {
        return MailupConfig::getConfig($site_id);
    }
    
    /**
     * Helper per gestire le opzioni in ambiente multisite
     * Se viene passato un site_id, usa get_blog_option() per leggere direttamente le opzioni di quel sito
     * Altrimenti, prova prima get_option() (opzioni del sito corrente)
     * Se non trova nulla, prova get_site_option() (opzioni di rete) come fallback
     * 
     * @param string $option_name Nome dell'opzione
     * @param mixed $default Valore di default
     * @param bool $is_multisite Se siamo in multisite
     * @param int|null $site_id ID del sito per cui leggere l'opzione (solo multisite)
     */
    private static function get_option_safe($option_name, $default = false, $is_multisite = false, $site_id = null) {
        if ($is_multisite) {
            $sentinel = [];
            
            // Se è specificato un site_id, leggi direttamente le opzioni di quel sito
            // Ma se il contesto è già stato cambiato (switch_to_blog fatto in getConfig), usa get_option() invece
            if ($site_id !== null && function_exists('get_blog_option')) {
                // Se il contesto corrente corrisponde al site_id, usa get_option() che legge dal contesto corrente
                $current_blog_id = function_exists('get_current_blog_id') ? get_current_blog_id() : null;
                if ($current_blog_id === $site_id) {
                    // Il contesto è già stato cambiato, usa get_option() che legge dal contesto corrente
                    $site_value = get_option($option_name, $sentinel);
                } else {
                    // Il contesto non è stato cambiato, usa get_blog_option() per leggere direttamente
                    $site_value = get_blog_option($site_id, $option_name, $sentinel);
                }
                
                if ($site_value !== $sentinel) {
                    return $site_value;
                }
                
                // Se non trova nulla per il sito specificato, prova le network options
                if (function_exists('get_site_option')) {
                    $network_value = get_site_option($option_name, $sentinel);
                    if ($network_value !== $sentinel) {
                        return $network_value;
                    }
                }
                
                // Se non trova nulla, restituisce il default
                return $default;
            }
            
            // Altrimenti, usa il comportamento standard (sito corrente)
            $site_value = get_option($option_name, $sentinel);
            
            // Se esiste un valore per il sito corrente (diverso dal sentinella), usalo
            if ($site_value !== $sentinel) {
                return $site_value;
            }
            
            // Altrimenti, prova a leggere le network options come fallback
            if (function_exists('get_site_option')) {
                $network_value = get_site_option($option_name, $sentinel);
                if ($network_value !== $sentinel) {
                    return $network_value;
                }
            }
            
            // Se non trova nulla, restituisce il default
            return $default;
        }
        
        // Non multisite: usa semplicemente get_option
        return get_option($option_name, $default);
    }
    
    /**
     * Salva la configurazione
     * In multisite, salva sempre come site options (specifiche per sito)
     * per permettere configurazioni diverse per ogni sito
     */
    public static function saveConfig($domain, $feeds, $dates, $newsletter_title = null) {
        $is_multisite = function_exists('is_multisite') && is_multisite();
        $is_network_admin = function_exists('is_network_admin') && is_network_admin();
        $is_network = $is_multisite && $is_network_admin;
        
        // Se siamo in multisite ma NON nel network admin, forza il salvataggio come site options
        // Questo permette a ogni sito di avere le sue configurazioni
        if ($is_multisite && !$is_network_admin) {
            $is_network = false;
        }
        
        self::update_option_safe('newsletter_domain', sanitize_text_field($domain), $is_network);
        self::update_option_safe('newsletter_feeds', sanitize_textarea_field($feeds), $is_network);
        self::update_option_safe('newsletter_dates', sanitize_textarea_field($dates), $is_network);
        
        if ($newsletter_title !== null) {
            self::update_option_safe('newsletter_title', sanitize_text_field($newsletter_title), $is_network);
        }
    }
    
    /**
     * Helper per salvare le opzioni in ambiente multisite
     */
    private static function update_option_safe($option_name, $value, $is_network = false) {
        if ($is_network && function_exists('update_site_option')) {
            return update_site_option($option_name, $value);
        }
        return update_option($option_name, $value);
    }
    
    /**
     * Configurazione di default per i feed
     */
    private static function getDefaultFeedsConfig() {
        return json_encode([
            [
                'name' => 'featured',
                'file' => 'featured.xml',
                'title' => 'Articolo in Evidenza',
                'fixed' => true,
                'query_params' => [
                    'posts_per_page' => 1,
                    'exclude_tags' => ['blind-sponsored', 'offerte'],
                    'meta_query' => [
                        ['key' => 'in_evidenza_newsletter', 'value' => 1]
                    ]
                ]
            ],
            [
                'name' => 'newsfeed',
                'file' => 'newsfeed.xml',
                'title' => 'Feed Principale',
                'fixed' => true,
                'query_params' => [
                    'posts_per_page' => 20,
                    'exclude_tags' => ['blind-sponsored', 'offerte'],
                    'exclude_featured' => true
                ]
            ],
            [
                'name' => 'offersfeed',
                'file' => 'offers.xml',
                'title' => 'Feed Offerte',
                'fixed' => false,
                'query_params' => [
                    'posts_per_page' => 10,
                    'include_tags' => ['offerte'],
                    'exclude_tags' => ['blind-sponsored'],
                    'post_types' => ['post']
                ]
            ],
            [
                'name' => 'sponsored',
                'file' => 'sponsored.xml',
                'title' => 'Contenuti Sponsorizzati',
                'fixed' => false,
                'query_params' => [
                    'posts_per_page' => 5,
                    'include_tags' => ['sponsored'],
                    'post_types' => ['post']
                ]
            ],
            [
                'name' => 'nlsponsored',
                'file' => 'nlsponsored.xml',
                'title' => 'Newsletter Sponsorizzati',
                'fixed' => false,
                'query_params' => [
                    'posts_per_page' => 3,
                    'include_tags' => ['nl_sponsored'],
                    'post_types' => ['post']
                ]
            ]
        ]);
    }
    
    /**
     * Converte ricorsivamente un array in un oggetto
     */
    private static function arrayToObject($array) {
        if (!is_array($array)) {
            return $array;
        }
        
        $object = new \stdClass();
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $object->$key = self::arrayToObject($value);
            } else {
                $object->$key = $value;
            }
        }
        
        return $object;
    }
}
