<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Boot diagnostika — explicitně v wp-config.php:
 * define( 'ELEMENTSELL_BOOT_DEBUG', true );
 *
 * Bez wp-config se log zapne automaticky v Elementor kontextu, pokud je
 * ELEMENTSELL_ELEMENTOR_STUB_MODE true (výchozí v plugin.php).
 *
 * Testovací režimy editoru (wp-config.php):
 * define( 'ELEMENTSELL_ELEMENTOR_SAFE_MODE', true );  // žádné elementor.php ani widgety
 * define( 'ELEMENTSELL_ELEMENTOR_NO_WIDGETS', true ); // elementor.php + sync, bez registrace widgetů
 * define( 'ELEMENTSELL_ELEMENTOR_STUB_MODE', false ); // vypne stub (light boot) — plný boot editoru
 * define( 'ELEMENTSELL_ELEMENTOR_PANEL_WIDGETS', true ); // panelové widgety místo plných (záloha paměti)
 * define( 'ELEMENTSELL_ELEMENTOR_DEFERRED_RELOAD', true ); // opt-in: countdown + reload (výchozí false)
 * define( 'ELEMENTSELL_ELEMENTOR_DEFERRED_MS', 5000 ); // prodleva před reloadem (jen s DEFERRED_RELOAD)
 *
 * @return bool
 */
function elementsell_boot_log_always() {
    if ( defined( 'ELEMENTSELL_BOOT_DEBUG' ) && ELEMENTSELL_BOOT_DEBUG ) {
        return true;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_STUB_MODE' ) && ELEMENTSELL_ELEMENTOR_STUB_MODE ) {
        return function_exists( 'elementsell_is_elementor_context' ) && elementsell_is_elementor_context();
    }

    return false;
}

/**
 * @return bool
 */
function elementsell_boot_debug_enabled() {
    return elementsell_boot_log_always();
}

/**
 * @return string
 */
function elementsell_boot_debug_log_path() {
    static $path = null;

    if ( null !== $path ) {
        return $path;
    }

    if ( function_exists( 'wp_upload_dir' ) ) {
        $upload_dir = wp_upload_dir();

        if ( is_array( $upload_dir ) && empty( $upload_dir['error'] ) && ! empty( $upload_dir['basedir'] ) ) {
            $path = trailingslashit( $upload_dir['basedir'] ) . 'elementsell-boot.log';

            return $path;
        }
    }

    $path = '';

    return $path;
}

/**
 * @return float Milisekundy od startu boot logu.
 */
function elementsell_boot_elapsed_ms() {
    if ( ! isset( $GLOBALS['elementsell_boot_start_time'] ) ) {
        $GLOBALS['elementsell_boot_start_time'] = microtime( true );

        return 0.0;
    }

    return round( ( microtime( true ) - $GLOBALS['elementsell_boot_start_time'] ) * 1000, 1 );
}

/**
 * @param string $message
 * @return void
 */
function elementsell_boot_debug_log( $message ) {
    if ( ! elementsell_boot_debug_enabled() ) {
        return;
    }

    $memory = function_exists( 'size_format' ) ? size_format( memory_get_usage( true ) ) : (string) memory_get_usage( true );
    $line   = sprintf(
        '[%s] [+%sms] [mem:%s] %s | %s %s',
        gmdate( 'Y-m-d H:i:s' ),
        elementsell_boot_elapsed_ms(),
        $memory,
        $message,
        isset( $_SERVER['REQUEST_METHOD'] ) ? (string) $_SERVER['REQUEST_METHOD'] : '',
        isset( $_SERVER['REQUEST_URI'] ) ? (string) wp_unslash( $_SERVER['REQUEST_URI'] ) : ''
    );

    error_log( '[ElementSell boot] ' . $line );

    $log_path = elementsell_boot_debug_log_path();

    if ( $log_path !== '' ) {
        $log_dir = dirname( $log_path );

        if ( ! is_dir( $log_dir ) && function_exists( 'wp_mkdir_p' ) ) {
            wp_mkdir_p( $log_dir );
        }

        // Bez LOCK_EX — paralelní Elementor requesty (post.php + ajax + REST) by jinak blokovaly na logu.
        $written = @file_put_contents( $log_path, $line . PHP_EOL, FILE_APPEND );

        if ( false === $written ) {
            error_log( '[ElementSell boot] FAILED to write log file: ' . $log_path );
        }
    }
}

/**
 * @param string $relative_path
 * @return void
 */
function elementsell_boot_debug_require( $relative_path ) {
    $started_at = elementsell_boot_elapsed_ms();
    elementsell_boot_debug_log( 'require start ' . $relative_path );

    /*
     * Bez téhle pojistky shodí celý web chybějící soubor — což se stane vždycky,
     * když je zapnutá volitelná část (např. Emailing) a její složka v pluginu
     * není, protože se do release ZIPu nebalí.
     */
    if ( ! file_exists( PF_PLUGIN_DIR . $relative_path ) ) {
        elementsell_boot_debug_log( 'require SKIPPED (soubor neexistuje) ' . $relative_path );

        return;
    }

    require_once PF_PLUGIN_DIR . $relative_path;

    elementsell_boot_debug_log(
        'require done ' . $relative_path . ' (+' . round( elementsell_boot_elapsed_ms() - $started_at, 1 ) . 'ms)'
    );
}

/**
 * @return string
 */
function elementsell_get_request_uri() {
    return isset( $_SERVER['REQUEST_URI'] ) ? (string) wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
}

/** @var bool|null */
$GLOBALS['elementsell_elementor_context_cache'] = null;

/** @var string */
$GLOBALS['elementsell_elementor_context_reason'] = '';

/**
 * @param bool   $result
 * @param string $reason
 * @return bool
 */
function elementsell_cache_elementor_context( $result, $reason ) {
    $GLOBALS['elementsell_elementor_context_cache'] = (bool) $result;
    $GLOBALS['elementsell_elementor_context_reason'] = (string) $reason;

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log(
            'elementsell_is_elementor_context=' . ( $result ? 'true' : 'false' ) . ' reason=' . $reason
        );
    }

    return (bool) $result;
}

/**
 * @return string
 */
function elementsell_get_elementor_context_reason() {
    return (string) ( $GLOBALS['elementsell_elementor_context_reason'] ?? '' );
}

/**
 * Název WP logged_in cookie — při bootu plugin.php ještě nemusí být LOGGED_IN_COOKIE definováno.
 *
 * @return string
 */
function elementsell_get_logged_in_cookie_name() {
    if ( defined( 'LOGGED_IN_COOKIE' ) && LOGGED_IN_COOKIE ) {
        return (string) LOGGED_IN_COOKIE;
    }

    foreach ( array_keys( $_COOKIE ) as $cookie_name ) {
        if ( strpos( (string) $cookie_name, 'wordpress_logged_in_' ) === 0 ) {
            return (string) $cookie_name;
        }
    }

    return '';
}

/**
 * username|expiration|token|hmac z logged_in cookie — bez wp_validate_auth_cookie (plugin.php boot).
 * user_id není v cookie — odvozuje se z username přes $wpdb nebo wp_parse_auth_cookie.
 *
 * @return array{username:string,user_id:int,token:string,expiration:int}
 */
function elementsell_parse_logged_in_cookie_parts() {
    $empty = [
        'username'   => '',
        'user_id'    => 0,
        'token'      => '',
        'expiration' => 0,
    ];

    $cookie_name = elementsell_get_logged_in_cookie_name();

    if ( $cookie_name === '' || empty( $_COOKIE[ $cookie_name ] ) ) {
        return $empty;
    }

    $raw_value = (string) wp_unslash( $_COOKIE[ $cookie_name ] );
    $decoded   = rawurldecode( $raw_value );
    $parts     = explode( '|', $decoded );

    $username   = isset( $parts[0] ) ? (string) $parts[0] : '';
    $expiration = isset( $parts[1] ) && is_numeric( $parts[1] ) ? (int) $parts[1] : 0;
    $token      = isset( $parts[2] ) ? (string) $parts[2] : '';
    $user_id    = 0;

    if ( $user_id <= 0 && $username !== '' && isset( $GLOBALS['wpdb'] ) && is_object( $GLOBALS['wpdb'] ) ) {
        global $wpdb;

        $found = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT ID FROM {$wpdb->users} WHERE user_login = %s LIMIT 1",
                $username
            )
        );

        if ( $found ) {
            $user_id = (int) $found;
        }
    }

    return [
        'username'   => $username,
        'user_id'    => $user_id,
        'token'      => $token,
        'expiration' => $expiration,
    ];
}

/**
 * User ID z auth cookie — funguje při časném bootu plugin.php (před plnou WP autentizací).
 *
 * @return int
 */
function elementsell_get_boot_user_id_from_auth_cookie() {
    static $resolving = false;

    if ( $resolving ) {
        return 0;
    }

    if ( function_exists( 'wp_parse_auth_cookie' ) ) {
        $resolving = true;
        $parsed    = wp_parse_auth_cookie( '', 'logged_in' );
        $resolving = false;

        if ( is_array( $parsed ) && ! empty( $parsed['user_id'] ) ) {
            return (int) $parsed['user_id'];
        }
    }

    return elementsell_parse_logged_in_cookie_parts()['user_id'];
}

/**
 * @return int
 */
function elementsell_get_boot_user_id() {
    if ( function_exists( 'wp_get_current_user' ) ) {
        $user = wp_get_current_user();

        if ( isset( $user->ID ) && (int) $user->ID > 0 ) {
            return (int) $user->ID;
        }
    }

    return elementsell_get_boot_user_id_from_auth_cookie();
}

/**
 * @return string
 */
function elementsell_editor_session_cookie_name() {
    return 'elementsell_editor_session';
}

/**
 * Cookie je dostupná v $_COOKIE při boot rozhodnutí — dříve než WP auth.
 *
 * @return bool
 */
function elementsell_has_editor_session_cookie() {
    $cookie_name = elementsell_editor_session_cookie_name();

    return isset( $_COOKIE[ $cookie_name ] ) && (string) $_COOKIE[ $cookie_name ] === '1';
}

/**
 * @return void
 */
function elementsell_set_editor_session_cookie() {
    if ( headers_sent() ) {
        return;
    }

    $cookie_name = elementsell_editor_session_cookie_name();
    $expires     = time() + ( defined( 'MINUTE_IN_SECONDS' ) ? 5 * MINUTE_IN_SECONDS : 300 );
    $secure      = function_exists( 'is_ssl' ) && is_ssl();

    if ( PHP_VERSION_ID >= 70300 ) {
        setcookie(
            $cookie_name,
            '1',
            [
                'expires'  => $expires,
                'path'     => '/wp-admin/',
                'secure'   => $secure,
                'httponly' => true,
                'samesite' => 'Lax',
            ]
        );
    } else {
        setcookie( $cookie_name, '1', $expires, '/wp-admin/', '', $secure, true );
    }

    $_COOKIE[ $cookie_name ] = '1';
}

/**
 * @return string
 */
function elementsell_elementor_editor_session_transient_key( $user_id = 0 ) {
    $user_id = $user_id > 0 ? (int) $user_id : elementsell_get_boot_user_id();

    if ( $user_id <= 0 ) {
        return '';
    }

    return 'elementsell_elementor_editor_session_' . $user_id;
}

/**
 * @return void
 */
function elementsell_persist_elementor_editor_session_transient() {
    $transient_key = elementsell_elementor_editor_session_transient_key();

    if ( $transient_key !== '' ) {
        set_transient( $transient_key, 1, 5 * MINUTE_IN_SECONDS );
    }
}

/**
 * @return void
 */
function elementsell_schedule_elementor_editor_session_transient() {
    static $scheduled = false;

    if ( $scheduled ) {
        return;
    }

    $scheduled = true;
    add_action( 'shutdown', 'elementsell_persist_elementor_editor_session_transient', 0 );
}

/**
 * @return void
 */
function elementsell_touch_elementor_editor_session() {
    elementsell_set_editor_session_cookie();
    elementsell_schedule_elementor_editor_session_transient();
}

/**
 * @param string   $hook
 * @param callable $callback
 * @param int      $priority
 * @param int      $accepted_args
 * @return void
 */
function elementsell_add_logged_action( $hook, $callback, $priority = 10, $accepted_args = 1 ) {
    if ( ! elementsell_boot_debug_enabled() ) {
        add_action( $hook, $callback, $priority, $accepted_args );

        return;
    }

    $wrapped = static function () use ( $hook, $callback ) {
        elementsell_boot_debug_log( 'hook start: ' . $hook );
        $args   = func_get_args();
        $result = call_user_func_array( $callback, $args );
        elementsell_boot_debug_log( 'hook done: ' . $hook );

        return $result;
    };

    add_action( $hook, $wrapped, $priority, $accepted_args );
}

/**
 * @return void
 */
function elementsell_register_elementor_editor_lifecycle_logs() {
    if ( ! elementsell_boot_debug_enabled() || ! elementsell_is_elementor_context() ) {
        return;
    }

    static $registered = false;

    if ( $registered ) {
        return;
    }

    $registered = true;

    $log = static function ( $label ) {
        elementsell_boot_debug_log( 'editor lifecycle: ' . $label );
    };

    add_action( 'plugins_loaded', static function () use ( $log ) {
        $log( 'plugins_loaded' );
    }, 2 );

    add_action( 'init', static function () use ( $log ) {
        $log( 'init' );
    }, 99999 );

    add_action( 'admin_init', static function () use ( $log ) {
        $log( 'admin_init' );
    }, 99999 );

    add_action( 'admin_action_elementor', static function () use ( $log ) {
        $log( 'after elementor core handler' );
    }, PHP_INT_MAX );

    add_action( 'elementor/loaded', static function () use ( $log ) {
        $log( 'elementor/loaded' );
    }, 0 );

    add_action( 'elementor/widgets/register', static function () use ( $log ) {
        $log( 'elementor/widgets/register (before elementsell callback)' );
    }, 5 );
}

elementsell_register_elementor_editor_lifecycle_logs();

/**
 * @return bool
 */
function elementsell_has_elementor_editor_session() {
    if ( elementsell_has_editor_session_cookie() ) {
        return true;
    }

    $transient_key = elementsell_elementor_editor_session_transient_key();

    return $transient_key !== '' && (bool) get_transient( $transient_key );
}

/**
 * wp_doing_ajax() je při načtení plugin.php ještě false — detekce přes REQUEST_URI.
 *
 * @return bool
 */
function elementsell_is_admin_ajax_request() {
    if ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) {
        return true;
    }

    $uri = elementsell_get_request_uri();

    return strpos( $uri, 'admin-ajax.php' ) !== false;
}

/**
 * @param string $action
 * @return bool
 */
function elementsell_request_action_is_elementor( $action ) {
    $action = sanitize_key( (string) $action );

    if ( $action === '' ) {
        return false;
    }

    if ( 'elementor' === $action || 'elementor_ajax' === $action ) {
        return true;
    }

    if ( 0 === strpos( $action, 'elementor' ) ) {
        return true;
    }

    return strpos( $action, 'elementor' ) !== false;
}

/**
 * Široká detekce Elementor kontextu — pro vypnutí těžkých hooků a lazy load.
 *
 * Důležité: volá se při načtení plugin.php, tedy dříve než WordPress nastaví REST_REQUEST.
 * REST požadavky editoru proto detekujeme přes REQUEST_URI, ne přes konstantu REST_REQUEST.
 *
 * @return bool
 */
function elementsell_is_elementor_context() {
    if ( null !== $GLOBALS['elementsell_elementor_context_cache'] ) {
        return (bool) $GLOBALS['elementsell_elementor_context_cache'];
    }

    if ( defined( 'ELEMENTSELL_EDITOR_MINIMAL_BOOT' ) && ELEMENTSELL_EDITOR_MINIMAL_BOOT ) {
        return elementsell_cache_elementor_context( true, 'constant_minimal_boot' );
    }

    $request_action = isset( $_REQUEST['action'] )
        ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) )
        : '';

    $uri = elementsell_get_request_uri();

    // Záloha: některé proxy/cache nepropíší $_REQUEST['action'], ale URI zůstane.
    if ( $request_action === '' && strpos( $uri, 'action=elementor' ) !== false ) {
        $request_action = 'elementor';
        $_REQUEST['action'] = 'elementor';
    }

    if ( $request_action !== '' && elementsell_request_action_is_elementor( $request_action ) ) {
        elementsell_touch_elementor_editor_session();

        if ( 'elementor' === $request_action ) {
            return elementsell_cache_elementor_context( true, 'request_action_elementor' );
        }

        return elementsell_cache_elementor_context( true, 'ajax_action_elementor' );
    }

    if ( isset( $_GET['page'] ) ) {
        $page = sanitize_key( wp_unslash( (string) $_GET['page'] ) );

        if ( $page === 'elementor' || $page === 'elementor-app' || 0 === strpos( $page, 'elementor_' ) ) {
            elementsell_touch_elementor_editor_session();

            return elementsell_cache_elementor_context( true, 'admin_page_elementor' );
        }
    }

    if ( isset( $_GET['elementor-preview'] ) || isset( $_POST['elementor-preview'] ) ) {
        return elementsell_cache_elementor_context( true, 'elementor_preview' );
    }

    $uri              = elementsell_get_request_uri();
    $is_admin_ajax    = elementsell_is_admin_ajax_request();

    if ( strpos( $uri, '/wp-json/elementor/' ) !== false ) {
        elementsell_touch_elementor_editor_session();

        return elementsell_cache_elementor_context( true, 'rest_uri_elementor_namespace' );
    }

    if ( strpos( $uri, '/wp-json/' ) !== false ) {
        if ( preg_match( '#/wp-json/wp/v2/(pages|posts)(/|\?|$)#', $uri )
            && elementsell_request_referer_is_elementor_editor() ) {
            return elementsell_cache_elementor_context( true, 'rest_uri_wp_v2_referer' );
        }
    }

    if ( $is_admin_ajax ) {
        if ( $request_action === 'heartbeat' && elementsell_heartbeat_is_elementor_request() ) {
            elementsell_touch_elementor_editor_session();

            return elementsell_cache_elementor_context( true, 'ajax_heartbeat_elementor' );
        }

        if ( isset( $_POST['actions'] ) ) {
            $actions = wp_unslash( $_POST['actions'] );

            if ( is_string( $actions ) && strpos( $actions, 'elementor' ) !== false ) {
                elementsell_touch_elementor_editor_session();

                return elementsell_cache_elementor_context( true, 'ajax_post_actions_elementor' );
            }
        }

        if ( $request_action !== 'heartbeat' && elementsell_request_referer_is_elementor_editor() ) {
            elementsell_touch_elementor_editor_session();

            return elementsell_cache_elementor_context( true, 'ajax_referer' );
        }

        $no_match_reason = 'no_match action=' . $request_action;

        return elementsell_cache_elementor_context( false, $no_match_reason );
    }

    if ( elementsell_request_referer_is_elementor_editor() && preg_match( '#/wp-admin/post(-new)?\.php#', $uri ) ) {
        elementsell_touch_elementor_editor_session();

        return elementsell_cache_elementor_context( true, 'admin_post_screen_referer' );
    }

    return elementsell_cache_elementor_context( false, 'no_match' );
}

/**
 * Cookie nastavená JS/AJAX po prodlevě — přepne editor ze stub na plný boot.
 *
 * @return string
 */
function elementsell_editor_deferred_cookie_name() {
    return 'elementsell_editor_deferred';
}

/**
 * Transient podle WP session tokenu — záloha když user_id při bootu ještě není k dispozici.
 *
 * @param string $session_token Volitelný token z AJAX (JS může předat sessionKey z localize).
 * @return string
 */
function elementsell_editor_deferred_session_transient_key( $session_token = '' ) {
    $token = (string) $session_token;

    if ( $token === '' ) {
        $token = elementsell_parse_logged_in_cookie_parts()['token'];
    }

    if ( $token === '' ) {
        return '';
    }

    return 'elementsell_editor_deferred_sess_' . md5( $token );
}

/**
 * Transient jako záloha, když cookie v prohlížeči selže (path/domain, cache proxy).
 *
 * @param int $user_id
 * @return string
 */
function elementsell_editor_deferred_transient_key( $user_id = 0 ) {
    $user_id = $user_id > 0 ? (int) $user_id : elementsell_get_boot_user_id();

    if ( $user_id <= 0 ) {
        return '';
    }

    return 'elementsell_editor_deferred_' . $user_id;
}

/**
 * Cesty pro deferred cookie — shodné s WP admin session (spolehlivější než jen /).
 *
 * @return string[]
 */
function elementsell_editor_deferred_cookie_paths() {
    $paths = [];

    if ( defined( 'ADMIN_COOKIE_PATH' ) && ADMIN_COOKIE_PATH ) {
        $paths[] = ADMIN_COOKIE_PATH;
    }

    $paths[] = '/wp-admin/';
    $paths[] = '/wp-admin';

    if ( defined( 'COOKIEPATH' ) && COOKIEPATH ) {
        $paths[] = COOKIEPATH;
    }

    $paths[] = '/';

    return array_values( array_unique( $paths ) );
}

/**
 * @return bool
 */
function elementsell_has_editor_deferred_transient( $user_id = 0 ) {
    foreach ( elementsell_editor_deferred_transient_keys( $user_id ) as $transient_key ) {
        if ( (bool) get_transient( $transient_key ) ) {
            return true;
        }
    }

    return false;
}

/**
 * @param int    $user_id
 * @param string $session_token
 * @return string[]
 */
function elementsell_editor_deferred_transient_keys( $user_id = 0, $session_token = '' ) {
    $keys = [];

    $user_key = elementsell_editor_deferred_transient_key( $user_id );

    if ( $user_key !== '' ) {
        $keys[] = $user_key;
    }

    $session_key = elementsell_editor_deferred_session_transient_key( $session_token );

    if ( $session_key !== '' && ! in_array( $session_key, $keys, true ) ) {
        $keys[] = $session_key;
    }

    return $keys;
}

/**
 * User meta záloha — nastaví AJAX handler (WP auth už běží).
 *
 * @param int $user_id
 * @return bool
 */
function elementsell_has_editor_deferred_user_meta( $user_id = 0 ) {
    if ( ! function_exists( 'get_user_meta' ) ) {
        return false;
    }

    $user_id = $user_id > 0 ? (int) $user_id : elementsell_get_boot_user_id();

    if ( $user_id <= 0 ) {
        return false;
    }

    $stored = get_user_meta( $user_id, 'elementsell_editor_deferred', true );

    if ( $stored === '' || $stored === false ) {
        return false;
    }

    $ttl = defined( 'MINUTE_IN_SECONDS' ) ? 10 * MINUTE_IN_SECONDS : 600;

    return ( time() - (int) $stored ) < $ttl;
}

/**
 * Cookie nebo transient — obojí signalizuje přechod na plný boot editoru.
 *
 * @return bool
 */
function elementsell_has_editor_deferred_boot() {
    $cookie_name = elementsell_editor_deferred_cookie_name();

    if ( isset( $_COOKIE[ $cookie_name ] ) && (string) $_COOKIE[ $cookie_name ] === '1' ) {
        return true;
    }

    foreach ( elementsell_editor_deferred_transient_keys() as $transient_key ) {
        if ( ! (bool) get_transient( $transient_key ) ) {
            continue;
        }

        // Zrcadlení do $_COOKIE pro zbytek requestu (logika controls/widgetů).
        $_COOKIE[ $cookie_name ] = '1';

        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log(
                'deferred boot: transient hit user_id=' . elementsell_get_boot_user_id()
                . ' key=' . $transient_key
            );
        }

        return true;
    }

    if ( elementsell_has_editor_deferred_user_meta() ) {
        $_COOKIE[ $cookie_name ] = '1';

        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log(
                'deferred boot: user_meta hit user_id=' . elementsell_get_boot_user_id()
            );
        }

        return true;
    }

    return false;
}

/**
 * Alias — připravenost plného bootu editoru (cookie nebo transient).
 *
 * @return bool
 */
function elementsell_has_editor_deferred_ready() {
    return elementsell_has_editor_deferred_boot();
}

/**
 * @return bool
 */
function elementsell_has_editor_deferred_cookie() {
    return elementsell_has_editor_deferred_boot();
}

/**
 * Opt-in reload flow (countdown → AJAX → location.reload). Výchozí vypnuto.
 *
 * @return bool
 */
function elementsell_is_elementor_deferred_reload_enabled() {
    return defined( 'ELEMENTSELL_ELEMENTOR_DEFERRED_RELOAD' ) && ELEMENTSELL_ELEMENTOR_DEFERRED_RELOAD;
}

/**
 * Panelové widgety (widget-panel.php) místo plných — záloha při problémech s pamětí.
 *
 * @return bool
 */
function elementsell_is_elementor_panel_widgets_fallback() {
    return defined( 'ELEMENTSELL_ELEMENTOR_PANEL_WIDGETS' ) && ELEMENTSELL_ELEMENTOR_PANEL_WIDGETS;
}

/**
 * Stub režim s plnými widget controls (výchozí chování).
 *
 * @return bool
 */
function elementsell_is_elementor_stub_full_widgets_mode() {
    return elementsell_is_elementor_stub_mode() && ! elementsell_is_elementor_panel_widgets_fallback();
}

/**
 * Nastaví deferred cookie na jedné cestě.
 *
 * @param string $path
 * @param int    $expires
 * @param bool   $secure
 * @param string $domain
 * @return void
 */
function elementsell_set_editor_deferred_cookie_on_path( $path, $expires, $secure, $domain ) {
    $cookie_name = elementsell_editor_deferred_cookie_name();

    if ( headers_sent() ) {
        return;
    }

    if ( PHP_VERSION_ID >= 70300 ) {
        $options = [
            'expires'  => $expires,
            'path'     => $path,
            'secure'   => $secure,
            'httponly' => false,
            'samesite' => 'Lax',
        ];

        if ( $domain !== '' ) {
            $options['domain'] = $domain;
        }

        setcookie( $cookie_name, '1', $options );
    } else {
        setcookie( $cookie_name, '1', $expires, $path, $domain, $secure, false );
    }
}

/**
 * Nastaví cookie + transient pro přechod ze stub režimu na plný boot editoru.
 * Volá se z AJAX (spolehlivější než čistě document.cookie) nebo jako záloha z JS.
 *
 * @param string $session_token Volitelný session token z AJAX requestu.
 * @return void
 */
function elementsell_set_editor_deferred_cookie( $session_token = '' ) {
    $cookie_name = elementsell_editor_deferred_cookie_name();
    $ttl         = defined( 'MINUTE_IN_SECONDS' ) ? 10 * MINUTE_IN_SECONDS : 600;
    $expires     = time() + $ttl;
    $secure      = function_exists( 'is_ssl' ) && is_ssl();
    $domain      = defined( 'COOKIE_DOMAIN' ) ? (string) COOKIE_DOMAIN : '';
    $paths_set   = [];
    $user_id     = function_exists( 'get_current_user_id' ) ? (int) get_current_user_id() : elementsell_get_boot_user_id();

    if ( $user_id <= 0 ) {
        $user_id = elementsell_get_boot_user_id();
    }

    $transients = elementsell_editor_deferred_transient_keys( $user_id, $session_token );

    foreach ( elementsell_editor_deferred_cookie_paths() as $path ) {
        elementsell_set_editor_deferred_cookie_on_path( $path, $expires, $secure, $domain );
        $paths_set[] = $path;
    }

    $_COOKIE[ $cookie_name ] = '1';

    if ( function_exists( 'set_transient' ) ) {
        foreach ( $transients as $transient_key ) {
            set_transient( $transient_key, 1, $ttl );
        }
    }

    if ( $user_id > 0 && function_exists( 'update_user_meta' ) ) {
        update_user_meta( $user_id, 'elementsell_editor_deferred', time() );
    }

    $log_line = '[ElementSell deferred] cookie+transient set paths=' . implode( ',', $paths_set )
        . ' user_id=' . $user_id
        . ' boot_user_id=' . elementsell_get_boot_user_id()
        . ' transients=' . implode( ',', $transients )
        . ' user_meta=' . ( $user_id > 0 ? 'yes' : 'no' );

    error_log( $log_line );

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log(
            'deferred cookie set server-side paths=' . implode( ',', $paths_set )
            . ' domain=' . ( $domain !== '' ? $domain : '(default)' )
            . ' secure=' . ( $secure ? 'yes' : 'no' )
            . ' user_id=' . $user_id
            . ' boot_user_id=' . elementsell_get_boot_user_id()
            . ' transients=' . implode( ',', $transients )
            . ' user_meta=' . ( $user_id > 0 ? 'yes' : 'no' )
        );
    }
}

/**
 * AJAX — nastaví deferred cookie před reloadem editoru (spolehlivější než jen JS).
 *
 * @return void
 */
function elementsell_ajax_set_editor_deferred_cookie() {
    $user_id = function_exists( 'get_current_user_id' ) ? (int) get_current_user_id() : 0;

    if ( ! current_user_can( 'edit_posts' ) ) {
        error_log(
            '[ElementSell deferred] ajax forbidden user_id=' . $user_id
            . ' boot_user_id=' . elementsell_get_boot_user_id()
        );
        wp_send_json_error( [ 'message' => 'forbidden' ], 403 );
    }

    check_ajax_referer( 'elementsell_deferred_boot', 'nonce' );

    // Token z auth cookie na serveru — JS session_key je jen diagnostika, ne zdroj pravdy.
    $session_token = elementsell_parse_logged_in_cookie_parts()['token'];

    error_log(
        '[ElementSell deferred] ajax handler user_id=' . $user_id
        . ' boot_user_id=' . elementsell_get_boot_user_id()
        . ' session_token=' . ( $session_token !== '' ? 'yes' : 'no' )
    );

    elementsell_set_editor_deferred_cookie( $session_token );

    wp_send_json_success(
        [
            'cookie'  => elementsell_editor_deferred_cookie_name(),
            'user_id' => $user_id,
        ]
    );
}

add_action( 'wp_ajax_elementsell_deferred_editor_boot', 'elementsell_ajax_set_editor_deferred_cookie' );
add_action( 'wp_ajax_elementsell_set_editor_deferred', 'elementsell_ajax_set_editor_deferred_cookie' );

/**
 * Izolační test editoru — light boot bez database/sync.
 * Výchozí: plné widget.php + controls v jednom requestu (bez reloadu).
 * Panel fallback: ELEMENTSELL_ELEMENTOR_PANEL_WIDGETS + volitelně DEFERRED_RELOAD.
 *
 * @return bool
 */
function elementsell_is_elementor_stub_mode() {
    if ( ! elementsell_is_elementor_context() ) {
        return false;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_STUB_MODE' ) && ! ELEMENTSELL_ELEMENTOR_STUB_MODE ) {
        return false;
    }

    // Preview iframe musí vykreslit skutečný formulář (render()), ne panelovou ikonu.
    if ( isset( $_GET['elementor-preview'] ) || isset( $_POST['elementor-preview'] ) ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'stub skipped: elementor-preview iframe needs full widget render' );
        }

        return false;
    }

    if (
        elementsell_is_elementor_deferred_reload_enabled()
        && elementsell_has_editor_deferred_cookie()
    ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'deferred reload: stub skipped, full mode enabled (cookie or transient)' );
        }

        return false;
    }

    return true;
}

/**
 * Má paralelní request během editoru smět načíst automation, demo, billing, …?
 * Heartbeat bez Elementor payloadu při aktivní editor cookie jinak spustí plný boot
 * souběžně s post.php?action=elementor a vyčerpá PHP-FPM pool.
 *
 * @return bool
 */
function elementsell_is_heavy_full_boot_allowed() {
    if ( ! elementsell_has_editor_session_cookie() ) {
        return true;
    }

    $request_action = isset( $_REQUEST['action'] )
        ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) )
        : '';

    if ( $request_action === 'heartbeat' && elementsell_is_admin_ajax_request() ) {
        if ( ! elementsell_heartbeat_is_elementor_request() ) {
            if ( elementsell_boot_debug_enabled() ) {
                elementsell_boot_debug_log(
                    'heavy full boot blocked: editor cookie + heartbeat without elementor POST'
                );
            }

            return false;
        }
    }

    return true;
}

/**
 * Elementor kontext bez elementor.php — pouze compat + database (těžké hooky vypnuté).
 *
 * @return bool
 */
function elementsell_is_elementor_ultra_minimal_boot() {
    if ( ! elementsell_is_elementor_context() ) {
        return false;
    }

    if ( elementsell_is_elementor_stub_mode() ) {
        return true;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_SAFE_MODE' ) && ELEMENTSELL_ELEMENTOR_SAFE_MODE ) {
        return true;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_NO_WIDGETS' ) && ELEMENTSELL_ELEMENTOR_NO_WIDGETS ) {
        return false;
    }

    return ! elementsell_elementor_boot_needs_sync();
}

/**
 * Těžký boot (elementor-sync) — jen hlavní otevření editoru post.php?action=elementor.
 * Paralelní requesty (REST, heartbeat, elementor_ajax) zůstávají ultra_minimal.
 *
 * @return bool
 */
function elementsell_elementor_boot_needs_sync() {
    if ( elementsell_is_elementor_stub_mode() ) {
        return false;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_SAFE_MODE' ) && ELEMENTSELL_ELEMENTOR_SAFE_MODE ) {
        return false;
    }

    $uri = elementsell_get_request_uri();

    $request_action = isset( $_REQUEST['action'] )
        ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) )
        : '';

    if ( 'elementor' === $request_action ) {
        return true;
    }

    if ( strpos( $uri, 'action=elementor' ) !== false && preg_match( '#/wp-admin/post(-new)?\.php#', $uri ) ) {
        return true;
    }

    return false;
}

/**
 * Lite widgety v panelu editoru — post.php, elementor_ajax, elementor-app.
 * Neřídí načtení sync (viz elementsell_elementor_boot_needs_sync).
 *
 * @return bool
 */
function elementsell_elementor_boot_needs_widgets() {
    if ( elementsell_is_elementor_stub_mode() ) {
        return true;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_SAFE_MODE' ) && ELEMENTSELL_ELEMENTOR_SAFE_MODE ) {
        return false;
    }

    if ( elementsell_elementor_boot_needs_sync() ) {
        return true;
    }

    $request_action = isset( $_REQUEST['action'] )
        ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) )
        : '';

    if ( 'elementor_ajax' === $request_action ) {
        return true;
    }

    if ( isset( $_GET['page'] ) ) {
        $page = sanitize_key( wp_unslash( (string) $_GET['page'] ) );

        if ( $page === 'elementor-app' ) {
            return true;
        }
    }

    return false;
}

/**
 * Má se po načtení includes/elementor.php připojit registrace widgetů?
 * Boot (ultra_minimal) už rozhodl, zda se elementor.php načte — tady jen test režimy.
 *
 * @return bool
 */
function elementsell_should_register_elementor_widgets() {
    if ( elementsell_is_elementor_stub_mode() && elementsell_is_elementor_panel_widgets_fallback() ) {
        return false;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_SAFE_MODE' ) && ELEMENTSELL_ELEMENTOR_SAFE_MODE ) {
        return false;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_NO_WIDGETS' ) && ELEMENTSELL_ELEMENTOR_NO_WIDGETS ) {
        return false;
    }

    return true;
}

/**
 * @return bool
 */
function elementsell_request_referer_is_elementor_editor() {
    if ( empty( $_SERVER['HTTP_REFERER'] ) ) {
        return false;
    }

    $referer = (string) wp_unslash( $_SERVER['HTTP_REFERER'] );

    return strpos( $referer, 'action=elementor' ) !== false
        || strpos( $referer, 'elementor-preview' ) !== false
        || strpos( $referer, 'page=elementor' ) !== false
        || strpos( $referer, 'page=elementor-app' ) !== false
        || strpos( $referer, '/elementor-app/' ) !== false;
}

/**
 * @return bool
 */
function elementsell_heartbeat_is_elementor_request() {
    if ( ! isset( $_POST['data'] ) ) {
        return false;
    }

    $data = wp_unslash( $_POST['data'] );

    if ( is_string( $data ) ) {
        $decoded = json_decode( $data, true );
        $data    = is_array( $decoded ) ? $decoded : [];
    }

    if ( ! is_array( $data ) ) {
        return false;
    }

    foreach ( [ 'elementor_post_lock', 'elementor_save_builder', 'elementor_refresh_editor' ] as $key ) {
        if ( isset( $data[ $key ] ) ) {
            return true;
        }
    }

    return false;
}

/**
 * @deprecated Použijte elementsell_is_elementor_context().
 * @return bool
 */
function elementsell_is_builder_request() {
    return elementsell_is_elementor_context();
}

/**
 * Render widgetu v Elementor editoru / náhledu (ne na živém webu).
 *
 * @return bool
 */
function elementsell_is_elementor_editor_render() {
    if ( elementsell_is_elementor_context() ) {
        return true;
    }

    if ( ! did_action( 'elementor/loaded' ) || ! class_exists( '\Elementor\Plugin' ) ) {
        return false;
    }

    $plugin = \Elementor\Plugin::instance();

    if ( isset( $plugin->preview ) && $plugin->preview->is_preview_mode() ) {
        return true;
    }

    if ( isset( $plugin->editor ) && $plugin->editor->is_edit_mode() ) {
        return true;
    }

    return false;
}

/**
 * @return int
 */
function elementsell_get_elementor_editor_post_id() {
    foreach ( [ 'post', 'post_id', 'editor_post_id' ] as $request_key ) {
        if ( isset( $_REQUEST[ $request_key ] ) ) {
            $post_id = (int) wp_unslash( $_REQUEST[ $request_key ] );

            if ( $post_id > 0 ) {
                return $post_id;
            }
        }
    }

    if ( elementsell_is_admin_ajax_request() && isset( $_POST['actions'] ) ) {
        $actions_raw = wp_unslash( $_POST['actions'] );
        $actions     = is_string( $actions_raw ) ? json_decode( $actions_raw, true ) : $actions_raw;

        if ( is_array( $actions ) ) {
            foreach ( $actions as $action ) {
                if ( ! is_array( $action ) || empty( $action['data'] ) || ! is_array( $action['data'] ) ) {
                    continue;
                }

                if ( ! empty( $action['data']['post_id'] ) ) {
                    $post_id = (int) $action['data']['post_id'];

                    if ( $post_id > 0 ) {
                        return $post_id;
                    }
                }

                if ( ! empty( $action['data']['editor_post_id'] ) ) {
                    $post_id = (int) $action['data']['editor_post_id'];

                    if ( $post_id > 0 ) {
                        return $post_id;
                    }
                }
            }
        }
    }

    if ( class_exists( '\Elementor\Plugin' ) && did_action( 'elementor/loaded' ) ) {
        $plugin = \Elementor\Plugin::instance();

        if ( isset( $plugin->editor ) && method_exists( $plugin->editor, 'get_post_id' ) ) {
            $post_id = (int) $plugin->editor->get_post_id();

            if ( $post_id > 0 ) {
                return $post_id;
            }
        }
    }

    return 0;
}

/**
 * @param array       $elements
 * @param string|null $widget_type
 * @return bool
 */
function elementsell_elementor_elements_contain_widget( $elements, $widget_type = null ) {
    if ( ! is_array( $elements ) ) {
        return false;
    }

    foreach ( $elements as $element ) {
        if ( ! is_array( $element ) ) {
            continue;
        }

        if ( $widget_type === null ) {
            $type = (string) ( $element['widgetType'] ?? '' );

            if (
                $type === 'elementsell_payment_form'
                || $type === 'elementsell_course_image'
                || $type === 'elementsell_thank_you'
            ) {
                return true;
            }
        } elseif ( ! empty( $element['widgetType'] ) && $element['widgetType'] === $widget_type ) {
            return true;
        }

        if ( ! empty( $element['elements'] ) && elementsell_elementor_elements_contain_widget( $element['elements'], $widget_type ) ) {
            return true;
        }
    }

    return false;
}

/**
 * @param int $post_id
 * @return bool
 */
function elementsell_post_contains_elementsell_widgets( $post_id ) {
    $post_id = (int) $post_id;

    if ( $post_id <= 0 ) {
        return false;
    }

    $raw = get_post_meta( $post_id, '_elementor_data', true );

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log(
            'post_contains_widgets: post_id=' . $post_id
            . ' meta_len=' . ( is_string( $raw ) ? strlen( $raw ) : 0 )
        );
    }

    if ( ! is_string( $raw ) || $raw === '' || $raw === '[]' ) {
        return false;
    }

    if (
        strpos( $raw, 'elementsell_payment_form' ) === false
        && strpos( $raw, 'elementsell_course_image' ) === false
        && strpos( $raw, 'elementsell_thank_you' ) === false
    ) {
        return false;
    }

    $elements = json_decode( $raw, true );

    if ( JSON_ERROR_NONE !== json_last_error() || ! is_array( $elements ) || empty( $elements ) ) {
        return false;
    }

    return elementsell_elementor_elements_contain_widget( $elements );
}

/**
 * Plný widget (render + controls) vs lite varianta jen pro panel editoru.
 *
 * @return bool
 */
function elementsell_should_register_full_elementor_widget_controls() {
    // Veřejný frontend — vždy plný widget (platby musí fungovat).
    if ( function_exists( 'is_admin' ) && ! is_admin() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'widget controls: full (public frontend)' );
        }

        return true;
    }

    // Elementor preview iframe na frontendu.
    if ( isset( $_GET['elementor-preview'] ) || isset( $_POST['elementor-preview'] ) ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'widget controls: full (elementor preview)' );
        }

        return true;
    }

    // Mimo Elementor kontext (běžný admin, frontend) — plný widget.
    if ( ! elementsell_is_elementor_context() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'widget controls: full (non-elementor request)' );
        }

        return true;
    }

    // Stub režim s plnými widgety — všechny controls hned v jednom requestu (bez reloadu).
    if ( elementsell_is_elementor_stub_full_widgets_mode() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'widget controls: full (stub light boot, no reload)' );
        }

        return true;
    }

    // Opt-in deferred reload — plné controls po cookie + reload.
    if ( elementsell_is_elementor_deferred_reload_enabled() && elementsell_has_editor_deferred_cookie() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'widget controls: full (deferred reload, editor)' );
        }

        return true;
    }

    // Panel fallback nebo starý minimal boot — jen ikona v panelu.
    if ( elementsell_elementor_boot_needs_widgets() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'widget controls: panel-only (editor library)' );
        }

        return false;
    }

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log( 'widget controls: lite (admin elementor auxiliary)' );
    }

    return false;
}

/**
 * @return void
 */
function elementsell_skip_heavy_hooks_in_elementor() {
    $in_elementor_context = elementsell_is_elementor_context();
    $in_editor_action     = elementsell_elementor_boot_needs_sync();

    if ( ! $in_elementor_context && ! $in_editor_action ) {
        return;
    }

    remove_action( 'init', 'elementsell_ensure_thank_you_page', 12 );
    remove_action( 'init', 'elementsell_ensure_privacy_page', 12 );
    remove_action( 'init', 'elementsell_ensure_unsubscribe_page', 12 );
    remove_action( 'init', 'elementsell_register_thank_you_shortcode' );
    remove_action( 'init', 'elementsell_register_course_role_shortcodes' );
    remove_action( 'init', 'elementsell_register_page_access_meta' );
    remove_action( 'init', 'elementsell_automation_register_offer_query_var' );
    remove_action( 'add_meta_boxes', 'elementsell_register_page_access_meta_box' );
    remove_action( 'save_post_page', 'elementsell_save_page_access_meta_box', 10 );
    remove_filter( 'manage_pages_columns', 'elementsell_add_page_access_column' );
    remove_action( 'manage_pages_custom_column', 'elementsell_render_page_access_column', 10 );
    remove_action( 'init', 'elementsell_demo_register_guitar_roles', 9 );
    remove_action( 'init', 'elementsell_maybe_sync_publish_endpoint_to_webroot', 1 );
    remove_action( 'admin_init', 'elementsell_maybe_refresh_server_public_ip', 99 );
    remove_action( 'admin_init', 'elementsell_telemetry_maybe_register_existing_site' );
    remove_action( 'admin_init', 'elementsell_automation_register_settings' );
    remove_action( 'admin_init', 'elementsell_handle_delete_order' );
    remove_action( 'admin_init', 'elementsell_restrict_wp_admin_access' );
    remove_action( 'admin_init', 'elementsell_handle_invoice_export_request' );
    remove_action( 'admin_init', 'elementsell_register_invoice_settings' );
}

add_action( 'plugins_loaded', 'elementsell_skip_heavy_hooks_in_elementor', 1 );
add_action( 'admin_init', 'elementsell_skip_heavy_hooks_in_elementor', 0 );
add_action( 'admin_action_elementor', 'elementsell_skip_heavy_hooks_in_elementor', 0 );

/**
 * ID Elementor dokumentu, ve kterém je widget uložen (pro validaci platby).
 *
 * @param object|null $widget Instance Elementor widgetu.
 * @return int
 */
function elementsell_get_payment_widget_document_post_id( $widget = null ) {
    if ( is_object( $widget ) && method_exists( $widget, 'get_post_id' ) ) {
        $post_id = (int) $widget->get_post_id();

        if ( $post_id > 0 ) {
            return $post_id;
        }
    }

    if ( class_exists( '\Elementor\Plugin' ) && did_action( 'elementor/loaded' ) ) {
        $plugin = \Elementor\Plugin::instance();

        if ( isset( $plugin->editor ) && $plugin->editor->is_edit_mode() && method_exists( $plugin->editor, 'get_post_id' ) ) {
            $post_id = (int) $plugin->editor->get_post_id();

            if ( $post_id > 0 ) {
                return $post_id;
            }
        }
    }

    if ( is_singular() ) {
        return (int) get_queried_object_id();
    }

    $post_id = (int) get_the_ID();

    return $post_id > 0 ? $post_id : 0;
}

/**
 * @return void
 */
function elementsell_log_shutdown_fatal() {
    if ( elementsell_boot_debug_enabled() ) {
        $peak = function_exists( 'size_format' ) ? size_format( memory_get_peak_usage( true ) ) : (string) memory_get_peak_usage( true );
        elementsell_boot_debug_log(
            'shutdown peak_memory=' . $peak
            . ' elementor_context=' . ( elementsell_is_elementor_context() ? 'true' : 'false' )
            . ' reason=' . elementsell_get_elementor_context_reason()
        );
    }

    if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
        return;
    }

    $error = error_get_last();

    if ( ! $error || ! in_array( $error['type'], [ E_ERROR, E_PARSE, E_COMPILE_ERROR, E_CORE_ERROR ], true ) ) {
        return;
    }

    error_log(
        '[ElementSell fatal] ' . $error['message'] . ' in ' . $error['file'] . ':' . $error['line']
    );
}

register_shutdown_function( 'elementsell_log_shutdown_fatal' );

/**
 * Lehká registrace widgetů — vždy z compat.php, bez includes/elementor.php.
 *
 * @param \Elementor\Widgets_Manager|null $widgets_manager
 * @return void
 */
function elementsell_register_elementor_widgets( $widgets_manager = null ) {
    static $registered = false;

    if ( function_exists( 'elementsell_boot_debug_log' ) ) {
        $request_action = isset( $_REQUEST['action'] )
            ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) )
            : '';
        elementsell_boot_debug_log(
            'elementor/widgets/register callback entered'
            . ' uri=' . elementsell_get_request_uri()
            . ' action=' . $request_action
            . ' pf_version=' . ( defined( 'PF_VERSION' ) ? PF_VERSION : 'unknown' )
            . ' already_registered=' . ( $registered ? 'yes' : 'no' )
        );
    }

    if ( $registered ) {
        if ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'elementor/widgets/register skipped: already registered this request' );
        }

        return;
    }

    if ( null === $widgets_manager && class_exists( '\Elementor\Plugin' ) ) {
        $widgets_manager = \Elementor\Plugin::instance()->widgets_manager;
    }

    if ( ! is_object( $widgets_manager ) ) {
        if ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'elementor/widgets/register skipped: widgets_manager missing' );
        }

        return;
    }

    if ( ! class_exists( '\Elementor\Widget_Base' ) ) {
        if ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'elementor/widgets/register skipped: Widget_Base missing' );
        }

        return;
    }

    if ( function_exists( 'elementsell_boot_debug_log' ) ) {
        elementsell_boot_debug_log( 'elementor/widgets/register start Widget_Base=yes' );
    }

    $use_full_widgets = ! function_exists( 'elementsell_should_register_full_elementor_widget_controls' )
        || elementsell_should_register_full_elementor_widget_controls();

    if ( function_exists( 'elementsell_boot_debug_log' ) ) {
        elementsell_boot_debug_log( 'elementor/widgets/register mode=' . ( $use_full_widgets ? 'full' : 'panel' ) );

        if ( elementsell_has_editor_deferred_cookie() && $use_full_widgets ) {
            elementsell_boot_debug_log( 'deferred boot: full widgets + full controls enabled' );
        }
    }

    if ( $use_full_widgets ) {
        if ( ! class_exists( 'ElementSell_Widget', false ) ) {
            elementsell_boot_debug_require( 'widget.php' );
        } elseif ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'widget.php skipped: ElementSell_Widget class already defined' );
        }

        if ( ! class_exists( 'ElementSell_Course_Image_Widget', false ) ) {
            elementsell_boot_debug_require( 'widget-course-image.php' );
        } elseif ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'widget-course-image.php skipped: class already defined' );
        }
    } else {
        if ( ! class_exists( 'ElementSell_Widget', false ) ) {
            elementsell_boot_debug_require( 'widget-panel.php' );
        } elseif ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log(
                'widget-panel.php skipped: ElementSell_Widget already defined (full variant loaded earlier — class conflict)'
            );
        }

        if ( ! class_exists( 'ElementSell_Course_Image_Widget', false ) ) {
            elementsell_boot_debug_require( 'widget-course-image-panel.php' );
        } elseif ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'widget-course-image-panel.php skipped: class already defined' );
        }
    }

    if (
        ! class_exists( 'ElementSell_Widget', false )
        || ! class_exists( 'ElementSell_Course_Image_Widget', false )
    ) {
        if ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'elementor/widgets/register aborted: widget class missing after require' );
        }

        return;
    }

    $payment_widget      = new \ElementSell_Widget();
    $course_image_widget = new \ElementSell_Course_Image_Widget();

    if ( function_exists( 'elementsell_boot_debug_log' ) ) {
        elementsell_boot_debug_log(
            'elementor/widgets/register widget names: '
            . $payment_widget->get_name()
            . ', '
            . $course_image_widget->get_name()
        );
    }

    $did_register = false;

    if ( method_exists( $widgets_manager, 'register' ) ) {
        $widgets_manager->register( $payment_widget );
        $widgets_manager->register( $course_image_widget );
        $did_register = true;

        if ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'elementor/widgets/register register() called=yes method=register' );
        }
    } elseif ( method_exists( $widgets_manager, 'register_widget_type' ) ) {
        $widgets_manager->register_widget_type( $payment_widget );
        $widgets_manager->register_widget_type( $course_image_widget );
        $did_register = true;

        if ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'elementor/widgets/register register() called=yes method=register_widget_type' );
        }
    }

    if ( ! $did_register ) {
        if ( function_exists( 'elementsell_boot_debug_log' ) ) {
            elementsell_boot_debug_log( 'elementor/widgets/register skipped: widgets_manager has no register method' );
        }

        return;
    }

    $registered = true;

    if ( function_exists( 'elementsell_boot_debug_log' ) ) {
        elementsell_boot_debug_log( 'elementor/widgets/register done' );
    }
}

/**
 * Připojí elementor/widgets/register z compat — bez lazy require elementor.php.
 *
 * @return void
 */
function elementsell_attach_elementor_widget_registration_hooks() {
    static $attached = false;

    if ( $attached ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'attach: elementor/widgets/register hook already attached' );
        }

        return;
    }

    $attached = true;

    if ( elementsell_is_elementor_stub_mode() && elementsell_is_elementor_panel_widgets_fallback() ) {
        elementsell_boot_debug_require( 'includes/elementor-stub.php' );
        elementsell_attach_elementor_stub_registration();

        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log(
                'attach: panel fallback mode (ELEMENTSELL_ELEMENTOR_PANEL_WIDGETS)'
            );
        }

        return;
    }

    if ( elementsell_is_elementor_stub_full_widgets_mode() && elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log(
            'attach: stub light boot + full widgets (elementsell_register_elementor_widgets)'
        );
    }

    if ( ! elementsell_should_register_elementor_widgets() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'attach: elementor/widgets/register attached=no (test mode)' );
        }

        return;
    }

    add_action( 'elementor/widgets/register', 'elementsell_register_elementor_widgets', 10 );
    add_action( 'elementor/widgets/widgets_registered', 'elementsell_register_elementor_widgets', 10 );
    add_action( 'elementor/init', 'elementsell_register_elementor_widgets_on_elementor_init', 20 );

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log( 'attach: elementor/widgets/register hook attached priority=10 yes' );
        elementsell_boot_debug_log( 'attach: elementor/init register fallback hook attached priority=20 yes' );
    }

    if ( did_action( 'elementor/widgets/register' ) || did_action( 'elementor/widgets/widgets_registered' ) ) {
        if ( class_exists( '\Elementor\Plugin' ) ) {
            if ( elementsell_boot_debug_enabled() ) {
                elementsell_boot_debug_log( 'attach: hook already fired, registering immediately' );
            }

            elementsell_register_elementor_widgets( \Elementor\Plugin::instance()->widgets_manager );
        } elseif ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'attach: hook already fired but Elementor Plugin missing' );
        }
    }
}

/**
 * Fallback registrace po elementor/init — widgets_manager už existuje (na rozdíl od elementor/loaded).
 * Statický guard v elementsell_register_elementor_widgets() brání dvojí registraci.
 *
 * @return void
 */
function elementsell_register_elementor_widgets_on_elementor_init() {
    if ( ! elementsell_should_register_elementor_widgets() ) {
        return;
    }

    if ( ! elementsell_elementor_boot_needs_widgets() && ! elementsell_elementor_boot_needs_sync() ) {
        return;
    }

    if ( did_action( 'elementor/widgets/register' ) || did_action( 'elementor/widgets/widgets_registered' ) ) {
        return;
    }

    if ( ! class_exists( '\Elementor\Plugin' ) ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'elementor/init widget register fallback skipped: Plugin missing' );
        }

        return;
    }

    $widgets_manager = \Elementor\Plugin::instance()->widgets_manager;

    if ( ! is_object( $widgets_manager ) ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'elementor/init widget register fallback skipped: widgets_manager missing' );
        }

        return;
    }

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log( 'elementor/init widget register fallback attempt' );
    }

    elementsell_register_elementor_widgets( $widgets_manager );
}

elementsell_attach_elementor_widget_registration_hooks();

/**
 * Ikona widgetu Obrázek kurzu v panelu Elementoru — nativní eicon (spolehlivé zobrazení).
 * Vizuální odznak obrázku přidává editor-only CSS (course-image-panel-icon.css).
 *
 * @return string
 */
function elementsell_get_course_image_widget_icon() {
    return 'eicon-eye';
}

/**
 * Načte editor-only CSS pro odznak obrázku u widgetu Obrázek kurzu v panelu.
 *
 * @return void
 */
function elementsell_enqueue_elementor_course_image_panel_icon_styles() {
    static $enqueued = false;

    if ( $enqueued || ! defined( 'PF_PLUGIN_URL' ) || ! function_exists( 'wp_enqueue_style' ) ) {
        return;
    }

    $enqueued = true;

    wp_enqueue_style(
        'elementsell-course-image-panel-icon',
        PF_PLUGIN_URL . 'assets/icons/course-image-panel-icon.css',
        [],
        defined( 'PF_VERSION' ) ? PF_VERSION : '1.0.0'
    );
}

/**
 * Záložní enqueue panelové ikony přes admin_enqueue_scripts (některé verze Elementoru).
 *
 * @param string $hook
 * @return void
 */
function elementsell_enqueue_elementor_course_image_panel_icon_styles_admin( $hook ) {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    elementsell_enqueue_elementor_course_image_panel_icon_styles();
}

add_action( 'elementor/editor/before_enqueue_styles', 'elementsell_enqueue_elementor_course_image_panel_icon_styles', 5 );
add_action( 'elementor/editor/after_enqueue_styles', 'elementsell_enqueue_elementor_course_image_panel_icon_styles', 5 );
add_action( 'admin_enqueue_scripts', 'elementsell_enqueue_elementor_course_image_panel_icon_styles_admin', 5 );

/**
 * Je aktuální request hlavní Elementor editor (post.php?action=elementor)?
 *
 * @return bool
 */
function elementsell_is_elementor_editor_screen_request() {
    $uri = elementsell_get_request_uri();

    if ( preg_match( '#/wp-admin/post(-new)?\.php#', $uri ) ) {
        $request_action = isset( $_REQUEST['action'] )
            ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) )
            : '';

        if ( 'elementor' === $request_action || strpos( $uri, 'action=elementor' ) !== false ) {
            return true;
        }
    }

    if ( isset( $_GET['page'] ) ) {
        $page = sanitize_key( wp_unslash( (string) $_GET['page'] ) );

        if ( $page === 'elementor' ) {
            return true;
        }
    }

    if ( function_exists( 'get_current_screen' ) ) {
        $screen = get_current_screen();

        if ( is_object( $screen ) && isset( $screen->action ) && $screen->action === 'elementor' ) {
            return true;
        }
    }

    return false;
}

/**
 * Konfigurace pro deferred boot JS (enqueue i inline fallback).
 *
 * @return array<string,mixed>
 */
function elementsell_get_deferred_boot_script_config() {
    $delay_ms = defined( 'ELEMENTSELL_ELEMENTOR_DEFERRED_MS' )
        ? max( 1000, (int) ELEMENTSELL_ELEMENTOR_DEFERRED_MS )
        : 5000;

    $cookie_ttl    = defined( 'MINUTE_IN_SECONDS' ) ? 10 * MINUTE_IN_SECONDS : 600;
    $cookie_paths  = elementsell_editor_deferred_cookie_paths();
    $session_token = elementsell_parse_logged_in_cookie_parts()['token'];
    $session_key   = $session_token !== '' ? md5( $session_token ) : '';

    return [
        'reloadEnabled' => elementsell_is_elementor_deferred_reload_enabled(),
        'delayMs'       => $delay_ms,
        'cookieMaxAge'  => $cookie_ttl,
        'cookieName'    => elementsell_editor_deferred_cookie_name(),
        'cookiePaths'   => $cookie_paths,
        'ajaxUrl'       => function_exists( 'admin_url' ) ? admin_url( 'admin-ajax.php' ) : '',
        'nonce'         => function_exists( 'wp_create_nonce' ) ? wp_create_nonce( 'elementsell_deferred_boot' ) : '',
        'sessionKey'    => $session_key,
        'debug'         => true,
        'messages'      => [
            'waiting'   => 'ElementSell: plná nastavení formuláře za %d s (stránka se pak sama obnoví)',
            'countdown' => 'ElementSell: plná nastavení za %d s',
            'active'    => 'ElementSell: načítám plná nastavení formuláře…',
            'failed'    => 'Plná nastavení se po obnovení nenačetla. Klikněte na tlačítko níže nebo obnovte stránku (F5).',
            'manual'    => 'Načíst plné nastavení formuláře',
            'retry'     => 'Zkusit znovu',
        ],
    ];
}

/**
 * @return string
 */
function elementsell_get_deferred_enqueue_skip_reason() {
    if ( ! elementsell_is_elementor_deferred_reload_enabled() ) {
        return 'deferred_reload_disabled';
    }

    if ( ! defined( 'PF_PLUGIN_URL' ) ) {
        return 'pf_plugin_url_missing';
    }

    if ( ! elementsell_is_elementor_context() && ! elementsell_is_elementor_editor_screen_request() ) {
        return 'not_elementor_context';
    }

    if ( elementsell_has_editor_deferred_boot() ) {
        return 'deferred_already_ready';
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_STUB_MODE' ) && ! ELEMENTSELL_ELEMENTOR_STUB_MODE ) {
        return 'stub_mode_disabled';
    }

    if ( ! elementsell_is_elementor_stub_mode() ) {
        return 'stub_mode_false';
    }

    return '';
}

/**
 * Odložený boot editoru — lehký JS jen při aktivním stub režimu.
 *
 * @param string $source Volající hook pro diagnostiku.
 * @return void
 */
function elementsell_enqueue_elementor_deferred_boot_script( $source = '' ) {
    static $enqueued = false;

    if ( $enqueued ) {
        return;
    }

    $skip_reason = elementsell_get_deferred_enqueue_skip_reason();

    if ( $skip_reason !== '' ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log(
                'deferred script enqueue: skipped reason=' . $skip_reason
                . ' source=' . ( $source !== '' ? $source : 'unknown' )
                . ' uri=' . elementsell_get_request_uri()
                . ' editor_screen=' . ( elementsell_is_elementor_editor_screen_request() ? 'yes' : 'no' )
            );
        }

        return;
    }

    if ( ! function_exists( 'wp_enqueue_script' ) ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log(
                'deferred script enqueue: skipped reason=wp_enqueue_script_missing source=' . $source
            );
        }

        return;
    }

    $config   = elementsell_get_deferred_boot_script_config();
    $delay_ms = (int) $config['delayMs'];

    wp_enqueue_script(
        'elementsell-elementor-deferred',
        PF_PLUGIN_URL . 'assets/elementor-deferred.js',
        [ 'jquery' ],
        defined( 'PF_VERSION' ) ? PF_VERSION : '1.0.0',
        true
    );

    wp_localize_script(
        'elementsell-elementor-deferred',
        'elementsellDeferredBoot',
        $config
    );

    $enqueued = true;

    error_log(
        '[ElementSell deferred] enqueued elementor-deferred.js delay_ms=' . $delay_ms
        . ' source=' . ( $source !== '' ? $source : 'unknown' )
        . ' uri=' . elementsell_get_request_uri()
    );

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log(
            'deferred script enqueue: enqueued delay_ms=' . $delay_ms
            . ' source=' . ( $source !== '' ? $source : 'unknown' )
            . ' session_key=' . ( ! empty( $config['sessionKey'] ) ? 'yes' : 'no' )
        );
    }
}

/**
 * Záložní enqueue — některé verze Elementoru nespolehlivě volají elementor/editor/after_enqueue_scripts.
 *
 * @param string $hook
 * @return void
 */
function elementsell_enqueue_elementor_deferred_boot_script_admin( $hook ) {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        if ( 'post.php' === $hook || 'post-new.php' === $hook ) {
            if ( elementsell_boot_debug_enabled() && elementsell_is_elementor_context() ) {
                elementsell_boot_debug_log(
                    'deferred script enqueue: skipped reason=not_editor_screen hook=' . $hook
                );
            }
        }

        return;
    }

    elementsell_enqueue_elementor_deferred_boot_script( 'admin_enqueue_scripts:' . $hook );
}

/**
 * @return void
 */
function elementsell_enqueue_elementor_deferred_boot_script_editor_hook() {
    elementsell_enqueue_elementor_deferred_boot_script( 'elementor/editor_enqueue_scripts' );
}

/**
 * @return void
 */
function elementsell_enqueue_elementor_deferred_boot_script_admin_action() {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    elementsell_enqueue_elementor_deferred_boot_script( 'admin_action_elementor' );
}

/**
 * @param \WP_Screen|null $screen
 * @return void
 */
function elementsell_enqueue_elementor_deferred_boot_script_current_screen( $screen ) {
    if ( ! is_object( $screen ) || ! isset( $screen->action ) || $screen->action !== 'elementor' ) {
        return;
    }

    elementsell_enqueue_elementor_deferred_boot_script( 'current_screen' );
}

/**
 * Inline fallback — countdown + AJAX + reload přímo ve footer editoru (nezávislé na wp_enqueue).
 *
 * @return void
 */
function elementsell_print_elementor_deferred_boot_inline_fallback() {
    static $printed = false;

    if ( $printed ) {
        return;
    }

    if ( ! elementsell_is_elementor_deferred_reload_enabled() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'deferred inline footer: skipped reason=deferred_reload_disabled' );
        }

        return;
    }

    if ( elementsell_has_editor_deferred_boot() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'deferred inline footer: skipped reason=deferred_already_ready' );
        }

        return;
    }

    if ( defined( 'ELEMENTSELL_ELEMENTOR_STUB_MODE' ) && ! ELEMENTSELL_ELEMENTOR_STUB_MODE ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'deferred inline footer: skipped reason=stub_mode_disabled' );
        }

        return;
    }

    if ( ! elementsell_is_elementor_stub_mode() ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'deferred inline footer: skipped reason=stub_mode_false' );
        }

        return;
    }

    if ( function_exists( 'wp_script_is' )
        && ( wp_script_is( 'elementsell-elementor-deferred', 'enqueued' ) || wp_script_is( 'elementsell-elementor-deferred', 'done' ) ) ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'deferred inline footer: skipped reason=script_already_enqueued' );
        }

        return;
    }

    $script_path = defined( 'PF_PLUGIN_DIR' ) ? PF_PLUGIN_DIR . 'assets/elementor-deferred.js' : '';

    if ( $script_path === '' || ! is_readable( $script_path ) ) {
        if ( elementsell_boot_debug_enabled() ) {
            elementsell_boot_debug_log( 'deferred inline footer: skipped reason=script_file_missing' );
        }

        return;
    }

    $printed = true;
    $config  = elementsell_get_deferred_boot_script_config();

    if ( elementsell_boot_debug_enabled() ) {
        elementsell_boot_debug_log(
            'deferred inline footer: printing inline boot script delay_ms=' . (int) $config['delayMs']
            . ' uri=' . elementsell_get_request_uri()
        );
    }

    error_log(
        '[ElementSell deferred] inline footer fallback delay_ms=' . (int) $config['delayMs']
        . ' uri=' . elementsell_get_request_uri()
    );

    $config_json = function_exists( 'wp_json_encode' )
        ? wp_json_encode( $config )
        : json_encode( $config );

    echo '<script id="elementsell-deferred-boot-config">window.elementsellDeferredBoot=' . $config_json . ';</script>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    echo '<script id="elementsell-deferred-boot-inline">'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted plugin asset
    readfile( $script_path );
    echo '</script>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}

/**
 * Poslední pokus o enqueue ve footer editoru, pak inline fallback.
 *
 * @return void
 */
function elementsell_elementor_deferred_boot_footer() {
    elementsell_enqueue_elementor_deferred_boot_script( 'elementor/editor/footer' );
    elementsell_print_elementor_deferred_boot_inline_fallback();
}

add_action( 'elementor/editor/after_enqueue_scripts', 'elementsell_enqueue_elementor_deferred_boot_script_editor_hook' );
add_action( 'elementor/editor/before_enqueue_scripts', 'elementsell_enqueue_elementor_deferred_boot_script_editor_hook', 1 );
add_action( 'admin_enqueue_scripts', 'elementsell_enqueue_elementor_deferred_boot_script_admin', 5 );
add_action( 'admin_action_elementor', 'elementsell_enqueue_elementor_deferred_boot_script_admin_action', 1 );
add_action( 'current_screen', 'elementsell_enqueue_elementor_deferred_boot_script_current_screen', 999 );
add_action( 'elementor/editor/footer', 'elementsell_elementor_deferred_boot_footer', 999 );

/**
 * Editor panel: styly globálního přepínače „Zobrazit vlastní pole“.
 *
 * @return void
 */
function elementsell_enqueue_elementor_custom_fields_global_toggle_styles() {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    if ( ! function_exists( 'wp_enqueue_style' ) ) {
        return;
    }

    wp_enqueue_style(
        'elementsell-elementor-custom-fields-global-toggle',
        PF_PLUGIN_URL . 'assets/elementor-custom-fields-global-toggle.css',
        [],
        defined( 'PF_VERSION' ) ? PF_VERSION : '1.0.0'
    );
}

add_action( 'elementor/editor/after_enqueue_styles', 'elementsell_enqueue_elementor_custom_fields_global_toggle_styles' );

/**
 * Editor panel: styly selectu „Aktivní režim“ (ThePay demo = modrá, ostrý = červená)
 * a barevné sekce platebních credentials (Fio/ThePay).
 *
 * @return void
 */
function elementsell_enqueue_elementor_thepay_environment_mode_styles() {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    if ( ! function_exists( 'wp_enqueue_style' ) ) {
        return;
    }

    wp_enqueue_style(
        'elementsell-elementor-thepay-environment-mode',
        PF_PLUGIN_URL . 'assets/elementor-thepay-environment-mode.css',
        [],
        defined( 'PF_VERSION' ) ? PF_VERSION : '1.0.0'
    );
}

/**
 * Editor panel: JS pro přepínání CSS tříd podle hodnoty selectu „Aktivní režim“.
 *
 * @return void
 */
function elementsell_enqueue_elementor_thepay_environment_mode_script() {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    if ( ! function_exists( 'wp_enqueue_script' ) ) {
        return;
    }

    wp_enqueue_script(
        'elementsell-elementor-thepay-environment-mode',
        PF_PLUGIN_URL . 'assets/elementor-thepay-environment-mode.js',
        [ 'jquery' ],
        defined( 'PF_VERSION' ) ? PF_VERSION : '1.0.0',
        true
    );
}

/**
 * Záložní enqueue ThePay režimových stylů/skriptu přes admin_enqueue_scripts.
 *
 * @param string $hook
 * @return void
 */
function elementsell_enqueue_elementor_thepay_environment_mode_admin( $hook ) {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    elementsell_enqueue_elementor_thepay_environment_mode_styles();
    elementsell_enqueue_elementor_thepay_environment_mode_script();
}

/**
 * Záložní enqueue ThePay režimových stylů/skriptu přes admin_action_elementor.
 *
 * @return void
 */
function elementsell_enqueue_elementor_thepay_environment_mode_admin_action() {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    elementsell_enqueue_elementor_thepay_environment_mode_styles();
    elementsell_enqueue_elementor_thepay_environment_mode_script();
}

/**
 * @param \WP_Screen|null $screen
 * @return void
 */
function elementsell_enqueue_elementor_thepay_environment_mode_current_screen( $screen ) {
    if ( ! is_object( $screen ) || ! isset( $screen->action ) || $screen->action !== 'elementor' ) {
        return;
    }

    elementsell_enqueue_elementor_thepay_environment_mode_styles();
    elementsell_enqueue_elementor_thepay_environment_mode_script();
}

/**
 * Inline fallback — CSS + JS přímo ve footer editoru (nezávislé na wp_enqueue).
 *
 * @return void
 */
function elementsell_print_elementor_thepay_environment_mode_inline_fallback() {
    static $printed = false;

    if ( $printed || ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    $style_enqueued = function_exists( 'wp_style_is' )
        && wp_style_is( 'elementsell-elementor-thepay-environment-mode', 'enqueued' );
    $script_enqueued = function_exists( 'wp_script_is' )
        && wp_script_is( 'elementsell-elementor-thepay-environment-mode', 'enqueued' );

    if ( $style_enqueued && $script_enqueued ) {
        return;
    }

    $printed = true;

    $css_path = PF_PLUGIN_DIR . 'assets/elementor-thepay-environment-mode.css';
    $js_path  = PF_PLUGIN_DIR . 'assets/elementor-thepay-environment-mode.js';

    if ( ! $style_enqueued && is_readable( $css_path ) ) {
        echo '<style id="elementsell-thepay-environment-mode-inline">'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted plugin asset
        readfile( $css_path );
        echo '</style>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    if ( ! $script_enqueued && is_readable( $js_path ) ) {
        echo '<script id="elementsell-thepay-environment-mode-inline">'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted plugin asset
        readfile( $js_path );
        echo '</script>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
}

add_action( 'elementor/editor/before_enqueue_styles', 'elementsell_enqueue_elementor_thepay_environment_mode_styles', 5 );
add_action( 'elementor/editor/after_enqueue_styles', 'elementsell_enqueue_elementor_thepay_environment_mode_styles' );
add_action( 'elementor/editor/before_enqueue_scripts', 'elementsell_enqueue_elementor_thepay_environment_mode_script', 1 );
add_action( 'elementor/editor/after_enqueue_scripts', 'elementsell_enqueue_elementor_thepay_environment_mode_script' );
add_action( 'admin_enqueue_scripts', 'elementsell_enqueue_elementor_thepay_environment_mode_admin', 5 );
add_action( 'admin_action_elementor', 'elementsell_enqueue_elementor_thepay_environment_mode_admin_action', 1 );
add_action( 'current_screen', 'elementsell_enqueue_elementor_thepay_environment_mode_current_screen', 999 );
add_action( 'elementor/editor/footer', 'elementsell_print_elementor_thepay_environment_mode_inline_fallback', 999 );

/**
 * Editor: legacy email_from_name → faktury_jmeno (PHP filtry + JS záloha v panelu).
 *
 * @return void
 */
function elementsell_ensure_email_from_name_editor_hooks() {
    if ( ! function_exists( 'elementsell_register_elementor_email_from_name_editor_hooks' ) ) {
        require_once PF_PLUGIN_DIR . 'includes/payments/payment-widget-credentials.php';
    }

    if ( function_exists( 'elementsell_register_elementor_email_from_name_editor_hooks' ) ) {
        elementsell_register_elementor_email_from_name_editor_hooks();
    }
}

add_action( 'plugins_loaded', 'elementsell_ensure_email_from_name_editor_hooks', 1 );

/**
 * Editor panel: JS záloha pro pole Jméno odesílatele.
 *
 * @return void
 */
function elementsell_enqueue_elementor_email_from_name_script() {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    if ( ! function_exists( 'wp_enqueue_script' ) || ! defined( 'PF_PLUGIN_URL' ) ) {
        return;
    }

    wp_enqueue_script(
        'elementsell-elementor-email-from-name',
        PF_PLUGIN_URL . 'assets/elementor-email-from-name.js',
        [ 'jquery' ],
        defined( 'PF_VERSION' ) ? PF_VERSION : '1.0.0',
        true
    );
}

/**
 * @param string $hook
 * @return void
 */
function elementsell_enqueue_elementor_email_from_name_script_admin( $hook ) {
    if ( ! elementsell_is_elementor_editor_screen_request() ) {
        return;
    }

    elementsell_enqueue_elementor_email_from_name_script();
}

add_action( 'elementor/editor/before_enqueue_scripts', 'elementsell_enqueue_elementor_email_from_name_script', 1 );
add_action( 'elementor/editor/after_enqueue_scripts', 'elementsell_enqueue_elementor_email_from_name_script' );
add_action( 'admin_enqueue_scripts', 'elementsell_enqueue_elementor_email_from_name_script_admin', 5 );

/**
 * Zajistí načtení helperů pro legacy jméno odesílatele platebního widgetu.
 *
 * @return void
 */
function elementsell_ensure_payment_widget_sender_name_helpers_loaded() {
    if (
        function_exists( 'elementsell_get_widget_email_from_name_default' )
        && function_exists( 'elementsell_is_legacy_widget_sender_name' )
    ) {
        return;
    }

    if ( ! defined( 'PF_PLUGIN_DIR' ) ) {
        return;
    }

    $path = PF_PLUGIN_DIR . 'includes/payments/payment-widget-credentials.php';

    if ( is_readable( $path ) ) {
        require_once $path;
    }
}

/**
 * Rekurzivně nahradí legacy email_from_name u widgetu elementsell_payment_form.
 *
 * @param array<int, array<string, mixed>> $elements
 * @return array<int, array<string, mixed>>
 */
function elementsell_patch_payment_widget_legacy_sender_names_in_elements( $elements ) {
    if ( ! is_array( $elements ) || empty( $elements ) ) {
        return is_array( $elements ) ? $elements : [];
    }

    elementsell_ensure_payment_widget_sender_name_helpers_loaded();

    if (
        ! function_exists( 'elementsell_is_legacy_widget_sender_name' )
        || ! function_exists( 'elementsell_get_widget_email_from_name_default' )
    ) {
        return $elements;
    }

    $default_name = elementsell_get_widget_email_from_name_default();

    foreach ( $elements as $index => $element ) {
        if ( ! is_array( $element ) ) {
            continue;
        }

        if (
            ! empty( $element['widgetType'] )
            && $element['widgetType'] === 'elementsell_payment_form'
            && isset( $element['settings']['email_from_name'] )
            && elementsell_is_legacy_widget_sender_name( $element['settings']['email_from_name'] )
            && $default_name !== ''
        ) {
            $elements[ $index ]['settings']['email_from_name'] = $default_name;
        }

        if ( ! empty( $element['elements'] ) && is_array( $element['elements'] ) ) {
            $elements[ $index ]['elements'] = elementsell_patch_payment_widget_legacy_sender_names_in_elements( $element['elements'] );
        }
    }

    return $elements;
}

/**
 * Při načtení dokumentu v Elementor editoru nahradí legacy „Platební formulář“ hodnotou z faktury_jmeno.
 *
 * @param array                         $data
 * @param \Elementor\Core\Base\Document $document
 * @return array
 */
function elementsell_filter_elementor_document_load_payment_widget_sender_name( $data, $document ) {
    unset( $document );

    return elementsell_patch_payment_widget_legacy_sender_names_in_elements( $data );
}

/**
 * Při uložení dokumentu zapíše opravené jméno odesílatele do _elementor_data.
 *
 * @param array                         $data
 * @param \Elementor\Core\Base\Document $document
 * @return array
 */
function elementsell_filter_elementor_document_save_payment_widget_sender_name( $data, $document ) {
    unset( $document );

    if ( ! is_array( $data ) || empty( $data['elements'] ) || ! is_array( $data['elements'] ) ) {
        return $data;
    }

    $data['elements'] = elementsell_patch_payment_widget_legacy_sender_names_in_elements( $data['elements'] );

    return $data;
}

add_filter( 'elementor/document/load/data', 'elementsell_filter_elementor_document_load_payment_widget_sender_name', 10, 2 );
add_filter( 'elementor/document/save/data', 'elementsell_filter_elementor_document_save_payment_widget_sender_name', 10, 2 );
