<?php
/**
 * Migration des réglages depuis une installation manuelle du thème.
 *
 * Le ZIP distribué historiquement par chalet-montagne.com s'installait dans le
 * dossier « chalet-montagne-com-theme », alors que la version WordPress.org
 * s'installe dans « chalet-montagne ». WordPress stockant les réglages du
 * personnalisateur dans l'option theme_mods_{dossier}, ceux-ci deviennent
 * invisibles après la bascule. On les recopie une seule fois.
 *
 * @package ChaletMontagne
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Anciens noms de dossier connus du thème.
 *
 * @return array
 */
function chaletmontagne_get_legacy_stylesheets() {
    return array('chalet-montagne-com-theme', 'chaletmontagne');
}

/**
 * Indique si un tableau de theme_mods contient des réglages propres au thème.
 *
 * WordPress écrit lui-même certaines clés dans les theme_mods du nouveau
 * thème au moment de la bascule (nav_menu_locations, sidebars_widgets,
 * l'entrée 0) : elles ne prouvent pas que l'utilisateur a configuré le
 * thème. Seules les clés « chaletmontagne_* » (hors drapeau de migration)
 * comptent.
 *
 * @param array $mods Theme mods.
 * @return bool
 */
function chaletmontagne_has_theme_settings($mods) {
    if (!is_array($mods)) {
        return false;
    }
    foreach ($mods as $key => $value) {
        if (!is_string($key) || 'chaletmontagne_migrated_from' === $key || 'chaletmontagne_menu_locations_synced' === $key) {
            continue;
        }
        if (0 === strpos($key, 'chaletmontagne_')) {
            return true;
        }
    }
    return false;
}

/**
 * Recopie la table des menus par langue de Polylang.
 *
 * Polylang n'utilise pas theme_mods sur le site public : il lit sa propre
 * option polylang['nav_menus'][<dossier du thème>][<emplacement>][<langue>],
 * indexée par le nom du dossier, et ne gère pas les changements de thème. Sans
 * cette copie, les menus disparaissent dans toutes les langues après la bascule.
 *
 * @param string $legacy  Ancien dossier.
 * @param string $current Dossier courant.
 * @return void
 */
function chaletmontagne_migrate_polylang_nav_menus($legacy, $current) {
    $options = get_option('polylang');
    if (!is_array($options) || empty($options['nav_menus'][$legacy]) || !is_array($options['nav_menus'][$legacy])) {
        return;
    }
    if (empty($options['nav_menus'][$current])) {
        $options['nav_menus'][$current] = $options['nav_menus'][$legacy];
        update_option('polylang', $options);
    }
}

/**
 * Réaligne theme_mods['nav_menu_locations'] sur la table Polylang.
 *
 * Lors d'une bascule de thème, wp_map_nav_menu_locations() (WordPress) fait
 * un mappage « flou » par famille de noms : l'ancien emplacement Polylang
 * primary___en contient « primary » et vient donc écraser primary avec le
 * menu anglais. Le site reste correct (Polylang lit sa table), mais au
 * prochain « Publier » du Customizer Polylang re-dérive la langue par défaut
 * depuis cette clé nue : le site français affiche alors le menu anglais.
 *
 * La table Polylang étant la source de vérité, on reconstruit les emplacements
 * à partir d'elle : clé nue = langue par défaut, <emplacement>___<langue>
 * pour les autres langues.
 *
 * @param string $current Dossier courant.
 * @return bool True si une synchronisation a été faite.
 */
function chaletmontagne_sync_menu_locations_from_polylang($current) {
    $options = get_option('polylang');
    if (!is_array($options) || empty($options['default_lang']) || empty($options['nav_menus'][$current]) || !is_array($options['nav_menus'][$current])) {
        return false;
    }
    $default = $options['default_lang'];
    $mods    = get_option('theme_mods_' . $current);
    $mods    = is_array($mods) ? $mods : array();
    $locations = (isset($mods['nav_menu_locations']) && is_array($mods['nav_menu_locations'])) ? $mods['nav_menu_locations'] : array();

    foreach ($options['nav_menus'][$current] as $location => $by_lang) {
        if (!is_array($by_lang)) {
            continue;
        }
        foreach ($by_lang as $lang => $menu_id) {
            $menu_id = (int) $menu_id;
            if ($menu_id <= 0) {
                continue;
            }
            $key = ($lang === $default) ? $location : $location . '___' . $lang;
            $locations[$key] = $menu_id;
        }
    }

    $mods['nav_menu_locations'] = $locations;
    update_option('theme_mods_' . $current, $mods);
    return true;
}

/**
 * Réparation unique des sites déjà basculés (1.4.5 à 1.4.8) dont la clé nue
 * pointe sur le menu d'une autre langue. Sans effet sans Polylang.
 *
 * @return void
 */
function chaletmontagne_repair_polylang_menu_locations() {
    $current = get_stylesheet();
    $mods    = get_option('theme_mods_' . $current);
    if (is_array($mods) && !empty($mods['chaletmontagne_menu_locations_synced'])) {
        return;
    }
    if (chaletmontagne_sync_menu_locations_from_polylang($current)) {
        set_theme_mod('chaletmontagne_menu_locations_synced', 1);
    }
}
add_action('admin_init', 'chaletmontagne_repair_polylang_menu_locations', 20);

/**
 * Recopie les theme_mods de l'ancien dossier vers le dossier courant. *
 * N'écrase jamais des réglages existants et ne s'exécute qu'une seule fois :
 * le drapeau est stocké dans les theme_mods eux-mêmes (aucune option
 * supplémentaire n'est créée en base).
 *
 * Valeurs du drapeau chaletmontagne_migrated_from :
 * - ancien dossier : réglages repris depuis ce dossier ;
 * - 'none'         : aucun ancien réglage trouvé, ne plus chercher ;
 * - ''             : drapeau posé par les versions 1.4.5/1.4.6, dont la
 *                    migration échouait dès qu'un menu était assigné (WordPress
 *                    recopie nav_menu_locations avant after_switch_theme). Un
 *                    site sans réglage propre avec ce drapeau est re-migré.
 *
 * @return void
 */
function chaletmontagne_migrate_legacy_theme_mods() {
    $current = get_stylesheet();
    $legacy  = chaletmontagne_get_legacy_stylesheets();

    // Le thème tourne encore depuis un ancien dossier : rien à migrer.
    if (in_array($current, $legacy, true)) {
        return;
    }

    $mods = get_option('theme_mods_' . $current);
    $mods = is_array($mods) ? $mods : array();

    // Migration déjà effectuée, ou installation qui possède ses propres réglages.
    if (!empty($mods['chaletmontagne_migrated_from']) || chaletmontagne_has_theme_settings($mods)) {
        return;
    }

    foreach ($legacy as $slug) {
        $old = get_option('theme_mods_' . $slug);
        if (!is_array($old)) {
            continue;
        }
        unset($old[0]);
        if (empty($old)) {
            continue;
        }

        // Ce que WordPress a déjà écrit à la bascule (emplacements de menus
        // remappés, widgets) prime sur l'ancienne valeur.
        unset($mods[0], $mods['chaletmontagne_migrated_from']);
        $merged = array_merge($old, $mods);

        // Emplacements de menus : WordPress ne remappe que ceux qu'il a pu faire
        // correspondre (si le site est passé par un thème intermédiaire sans
        // emplacement « footer », celui-ci est perdu). Les slugs étant identiques
        // entre les deux dossiers, on complète depuis l'ancien thème.
        $new_locations = isset($mods['nav_menu_locations']) ? array_filter((array) $mods['nav_menu_locations']) : array();
        $old_locations = isset($old['nav_menu_locations']) ? array_filter((array) $old['nav_menu_locations']) : array();
        if (!empty($old_locations)) {
            $merged['nav_menu_locations'] = $new_locations + $old_locations;
        }

        $merged['chaletmontagne_migrated_from'] = $slug;
        update_option('theme_mods_' . $current, $merged);

        chaletmontagne_migrate_polylang_nav_menus($slug, $current);
        if (chaletmontagne_sync_menu_locations_from_polylang($current)) {
            set_theme_mod('chaletmontagne_menu_locations_synced', 1);
        }

        // Le CSS additionnel est un post « custom_css » nommé d'après le dossier.
        if (!empty($merged['custom_css_post_id'])) {
            $css_post = get_post((int) $merged['custom_css_post_id']);
            if ($css_post && 'custom_css' === $css_post->post_type && $current !== $css_post->post_name) {
                wp_update_post(
                    array(
                        'ID'        => $css_post->ID,
                        'post_name' => $current,
                    )
                );
            }
        }

        return;
    }

    // Aucun ancien réglage trouvé : on marque quand même pour ne pas rechercher.
    set_theme_mod('chaletmontagne_migrated_from', 'none');
}
add_action('after_switch_theme', 'chaletmontagne_migrate_legacy_theme_mods');
// Filet de sécurité pour les sites déjà basculés avant cette version.
add_action('admin_init', 'chaletmontagne_migrate_legacy_theme_mods');
