<?php

/**
 * Plugin Name: Orange Addons for Elementor
 * Description: Enhance your Elementor page building experience with Orange Addons. This plugin provides a collection of highly customizable and creative widgets designed to extend Elementor's capabilities, allowing you to build stunning and unique websites faster and easier.
 * Plugin URI:  https://orange-addons.com/
 * Version:     1.0.0
 * Author:      Orange Addons
 * Author URI:  https://orange-addons.com
 * Text Domain: orange-addons-for-elementor
 * License: GNU General Public License v3.0 or later
 * License URI: https://www.gnu.org/licenses/gpl-3.0.html
 *
 * Requires Plugins: elementor
 * Elementor tested up to: 3.21.0
 * Elementor Pro tested up to: 3.21.0
 */
if ( !function_exists( 'oradel_fs' ) ) {
    // Create a helper function for easy SDK access.
    function oradel_fs() {
        global $oradel_fs;
        if ( !isset( $oradel_fs ) ) {
            // Include Freemius SDK.
            require_once dirname( __FILE__ ) . '/vendor/freemius/start.php';
            $oradel_fs = fs_dynamic_init( array(
                'id'               => '18095',
                'slug'             => 'orange-addons-for-elementor',
                'type'             => 'plugin',
                'public_key'       => 'pk_6508157c704fdda259bb20e165432',
                'is_premium'       => false,
                'premium_suffix'   => 'Premium',
                'has_addons'       => false,
                'has_paid_plans'   => true,
                'is_org_compliant' => true,
                'trial'            => array(
                    'days'               => 7,
                    'is_require_payment' => true,
                ),
                'menu'             => array(
                    'slug' => 'oradel-settings',
                ),
                'is_live'          => true,
            ) );
        }
        return $oradel_fs;
    }

    // Init Freemius.
    oradel_fs();
    // Signal that SDK was initiated.
    do_action( 'oradel_fs_loaded' );
}
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
define( 'ORADEL__FILE__', __FILE__ );
define( 'ORADEL_PLUGIN_BASE', plugin_basename( ORADEL__FILE__ ) );
define( 'ORADEL_PATH', plugin_dir_path( ORADEL__FILE__ ) );
define( 'ORADEL_MODULES_PATH', ORADEL_PATH . 'modules/' );
define( 'ORADEL_URL', plugins_url( '/', ORADEL__FILE__ ) );
define( 'ORADEL_ASSETS_URL', ORADEL_URL . 'assets/' );
define( 'ORADEL_MODULES_URL', ORADEL_URL . 'modules/' );
if ( !defined( 'ORADEL_TEMPLATES' ) ) {
    define( 'ORADEL_TEMPLATES', ORADEL_PATH . 'includes/template-parts/' );
}
function oradel_plugin() {
    require_once __DIR__ . '/includes/plugin.php';
    \Oradel_Plugin\Oradel_Plugin::instance();
}

add_action( 'plugins_loaded', 'oradel_plugin' );
function oradel_load_more_posts() {
    check_ajax_referer( 'load_more_posts_nonce', 'security' );
    $page = ( isset( $_POST['page'] ) ? intval( wp_unslash( $_POST['page'] ) ) : 1 );
    $posts_per_page = ( isset( $_POST['posts_per_page'] ) ? intval( wp_unslash( $_POST['posts_per_page'] ) ) : 5 );
    $category_position = ( isset( $_POST['category_position'] ) ? sanitize_text_field( wp_unslash( $_POST['category_position'] ) ) : 'bottom' );
    $categories_count = ( isset( $_POST['categories_count'] ) ? intval( wp_unslash( $_POST['categories_count'] ) ) : 1 );
    $post_skin = ( isset( $_POST['post_skin'] ) ? sanitize_text_field( wp_unslash( $_POST['post_skin'] ) ) : 'classic' );
    $show_image = ( isset( $_POST['show_image'] ) ? sanitize_text_field( wp_unslash( $_POST['show_image'] ) ) : 'yes' );
    $image_size = ( isset( $_POST['image_size'] ) ? sanitize_text_field( wp_unslash( $_POST['image_size'] ) ) : 'full' );
    $order_by = ( isset( $_POST['order_by'] ) ? sanitize_text_field( wp_unslash( $_POST['order_by'] ) ) : 'date' );
    $order = ( isset( $_POST['order'] ) ? sanitize_text_field( wp_unslash( $_POST['order'] ) ) : 'DESC' );
    $exclude_posts = [];
    if ( isset( $_POST['exclude_posts'] ) && is_array( $_POST['exclude_posts'] ) ) {
        $exclude_posts = array_map( 'intval', wp_unslash( $_POST['exclude_posts'] ) );
    }
    $exclude_no_image = isset( $_POST['exclude_no_image'] ) && sanitize_text_field( wp_unslash( $_POST['exclude_no_image'] ) ) === 'true';
    $ignore_sticky_posts = isset( $_POST['ignore_sticky_posts'] ) && sanitize_text_field( wp_unslash( $_POST['ignore_sticky_posts'] ) ) === 'true';
    $post_elements_order_raw = ( isset( $_POST['post_elements_order'] ) ? sanitize_text_field( wp_unslash( $_POST['post_elements_order'] ) ) : '' );
    $post_elements_order = [];
    if ( !empty( $post_elements_order_raw ) ) {
        $decoded = json_decode( $post_elements_order_raw, true );
        if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) {
            $post_elements_order = map_deep( $decoded, 'sanitize_text_field' );
        }
    }
    $open_in_new_tab = ( isset( $_POST['open_in_new_tab'] ) ? sanitize_text_field( wp_unslash( $_POST['open_in_new_tab'] ) ) : 'yes' );
    $lazy_loading = ( isset( $_POST['lazy_loading'] ) ? sanitize_text_field( wp_unslash( $_POST['lazy_loading'] ) ) : 'yes' );
    $no_posts_text = ( isset( $_POST['no_posts_text'] ) ? sanitize_text_field( wp_unslash( $_POST['no_posts_text'] ) ) : __( 'No posts found', 'orange-addons-for-elementor' ) );
    $taxonomy_type = ( isset( $_POST['taxonomy_type'] ) ? sanitize_text_field( wp_unslash( $_POST['taxonomy_type'] ) ) : 'category' );
    $term_id = ( isset( $_POST['term_id'] ) ? sanitize_text_field( wp_unslash( $_POST['term_id'] ) ) : 'all' );
    $tax_query_raw = ( isset( $_POST['tax_query'] ) ? sanitize_text_field( wp_unslash( $_POST['tax_query'] ) ) : '' );
    $settings_tax_query = [];
    if ( !empty( $tax_query_raw ) ) {
        $decoded = json_decode( $tax_query_raw, true );
        if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) {
            $settings_tax_query = map_deep( $decoded, 'sanitize_text_field' );
        }
    }
    $args = [
        'post_type'           => 'post',
        'posts_per_page'      => $posts_per_page,
        'paged'               => $page,
        'orderby'             => $order_by,
        'order'               => $order,
        'ignore_sticky_posts' => $ignore_sticky_posts,
    ];
    if ( !empty( $exclude_posts ) ) {
        // Limit the number of excluded posts for performance reasons
        // WordPress VIP recommends avoiding large post__not_in arrays
        $exclude_posts = array_slice( $exclude_posts, 0, 100 );
        $args['post__not_in'] = $exclude_posts;
        // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- Limited to 100 posts for performance
    }
    if ( $exclude_no_image ) {
        // meta_query is necessary here to filter posts with featured images
        // This is a simple EXISTS query on _thumbnail_id which is indexed
        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
        $args['meta_query'] = [[
            'key'     => '_thumbnail_id',
            'compare' => 'EXISTS',
        ]];
    }
    if ( $term_id !== 'all' || !empty( $settings_tax_query ) ) {
        // tax_query is necessary for filtering posts by taxonomy terms
        // Using term_id field which is indexed for optimal performance
        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
        $tax_query = [
            'relation' => 'AND',
        ];
        if ( !empty( $settings_tax_query ) ) {
            $tax_query[] = $settings_tax_query;
        }
        if ( $term_id !== 'all' ) {
            $tax_query[] = [
                'taxonomy' => $taxonomy_type,
                'field'    => 'term_id',
                'terms'    => [$term_id],
            ];
        }
        // Note: tax_query can be slow on large databases with complex taxonomy relationships
        // Consider limiting the number of taxonomy terms and using proper database indexes
        $args['tax_query'] = $tax_query;
        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Necessary for category filtering, limited terms recommended
    }
    $query = new WP_Query($args);
    if ( $query->have_posts() ) {
        ob_start();
        while ( $query->have_posts() ) {
            $query->the_post();
            $args = [
                'post_elements_order' => $post_elements_order,
                'category_position'   => $category_position,
                'categories_count'    => $categories_count,
                'show_image'          => $show_image,
                'image_size'          => $image_size,
                'open_in_new_tab'     => $open_in_new_tab,
                'lazy_loading'        => $lazy_loading,
            ];
            if ( $post_skin === 'cards' ) {
                include ORADEL_TEMPLATES . 'posts-grid-cards.php';
            } else {
                if ( $post_skin === 'classic' ) {
                    include ORADEL_TEMPLATES . 'posts-grid-classic.php';
                } else {
                    if ( $post_skin === 'list' ) {
                        include ORADEL_TEMPLATES . 'posts-grid-list.php';
                    }
                }
            }
        }
        wp_reset_postdata();
        $html = ob_get_clean();
        $is_last_page = $page >= $query->max_num_pages;
        wp_send_json_success( [
            'html'         => $html,
            'is_last_page' => $is_last_page,
            'total_pages'  => $query->max_num_pages,
        ] );
    } else {
        ob_start();
        echo '<div class="oea-no-posts-found">' . esc_html( $no_posts_text ) . '</div>';
        $html = ob_get_clean();
        wp_send_json_success( [
            'html'         => $html,
            'is_last_page' => true,
        ] );
    }
    wp_die();
}

add_action( 'wp_ajax_oradel_load_more_posts', 'oradel_load_more_posts' );
add_action( 'wp_ajax_nopriv_oradel_load_more_posts', 'oradel_load_more_posts' );
add_action( 'admin_menu', 'oradel_plugin_menu' );
function oradel_plugin_menu() {
    add_menu_page(
        'Orange Addons for Elementor Settings',
        'Orange Addons',
        'manage_options',
        'oradel-settings',
        'oradel_settings_page',
        'dashicons-admin-tools',
        80
    );
}

function oradel_settings_page() {
    ?>
    <div class="wrap">
        <h1>Orange Addons for Elementor Settings</h1>
        <div class="oea-tabs">
            <ul class="oea-tab-nav">
                <li><a href="#general" class="oea-tab-link active" data-tab="general">General</a></li>
                <li><a href="#widgets" class="oea-tab-link" data-tab="widgets">Widgets</a></li>
            </ul>
            <div class="oea-tab-content" id="oea-tab-content">
            </div>
        </div>
    </div>
    <?php 
}

add_action( 'admin_init', 'oradel_register_settings' );
function oradel_sanitize_widgets_status(  $input  ) {
    if ( !is_array( $input ) ) {
        return array();
    }
    $sanitized = array();
    foreach ( $input as $key => $value ) {
        $sanitized_key = sanitize_key( $key );
        $sanitized_value = ( in_array( $value, array('0', '1'), true ) ? $value : '0' );
        $sanitized[$sanitized_key] = $sanitized_value;
    }
    return $sanitized;
}

function oradel_register_settings() {
    register_setting( 'oradel_settings_group', 'oradel_elementor_widgets_status', array(
        'sanitize_callback' => 'oradel_sanitize_widgets_status',
    ) );
    add_settings_section(
        'oradel_widgets_section',
        __( 'Widgets', 'orange-addons-for-elementor' ),
        'oradel_widgets_section_callback',
        'oradel-settings'
    );
    if ( !class_exists( '\\Oradel_Plugin\\Oradel_Plugin' ) ) {
        require_once plugin_dir_path( __FILE__ ) . 'includes/plugin.php';
    }
    $widgets = \Oradel_Plugin\Oradel_Plugin::instance()->get_widgets();
    foreach ( $widgets as $name => $widget ) {
        add_settings_field(
            'oradel_widget_' . $name,
            $widget['title'],
            'oradel_widget_field_callback',
            'oradel-settings',
            'oradel_widgets_section',
            [
                'name' => $name,
            ]
        );
    }
}

function oradel_widgets_section_callback() {
    echo '<p>' . esc_html__( 'Enable or disable individual widgets.', 'orange-addons-for-elementor' ) . '</p>';
}

function oradel_widget_field_callback(  $args  ) {
    $name = $args['name'];
    if ( !class_exists( '\\Oradel_Plugin\\Oradel_Plugin' ) ) {
        require_once plugin_dir_path( __FILE__ ) . 'includes/plugin.php';
    }
    $widgets_status = \Oradel_Plugin\Oradel_Plugin::instance()->get_widget_statuses();
    $checked = isset( $widgets_status[$name] ) && $widgets_status[$name] == '1';
    echo '<div class="oea-toggle-switch">';
    echo '<input type="hidden" name="oradel_elementor_widgets_status[' . esc_attr( $name ) . ']" value="0" />';
    echo '<input type="checkbox" id="oradel_widget_' . esc_attr( $name ) . '" name="oradel_elementor_widgets_status[' . esc_attr( $name ) . ']" value="1" ' . checked( 1, ( $checked ? 1 : 0 ), false ) . ' />';
    echo '<label for="oradel_widget_' . esc_attr( $name ) . '"></label>';
    echo '</div>';
}

add_action( 'admin_enqueue_scripts', 'oradel_admin_styles' );
function oradel_admin_styles(  $hook  ) {
    if ( $hook !== 'toplevel_page_oradel-settings' ) {
        return;
    }
    wp_enqueue_style(
        'oradel-admin-style',
        ORADEL_ASSETS_URL . 'css/admin-style.min.css',
        [],
        '1.0.0'
    );
    wp_enqueue_style( 'dashicons' );
    wp_enqueue_script(
        'oradel-admin-script',
        ORADEL_ASSETS_URL . 'js/admin-script.min.js',
        ['jquery'],
        '1.0.3',
        true
    );
    wp_localize_script( 'oradel-admin-script', 'oradelAjax', [
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
        'nonce'   => wp_create_nonce( 'oradel_settings_nonce' ),
    ] );
}

add_action( 'wp_ajax_oradel_load_tab_content', 'oradel_load_tab_content' );
function oradel_load_tab_content() {
    check_ajax_referer( 'oradel_settings_nonce', 'nonce' );
    $tab = ( isset( $_POST['tab'] ) ? sanitize_text_field( wp_unslash( $_POST['tab'] ) ) : 'general' );
    ob_start();
    if ( $tab === 'general' ) {
        ?>
        <div class="oea-tab-pane">
            <h2>General Settings</h2>
            <p>Welcome to Orange Addons for Elementor!</p>
            <table class="form-table">
                <tr>
                    <th>Plugin Version</th>
                    <td><?php 
        echo '1.0.0';
        ?></td>
                </tr>
                <tr>
                    <th>Author</th>
                    <td>Orange Addons</td>
                </tr>
                <tr>
                    <th>Website</th>
                    <td><a href="https://orange-addons.com" target="_blank">orange-addons.com</a></td>
                </tr>
            </table>
        </div>
        <?php 
    } elseif ( $tab === 'widgets' ) {
        if ( !class_exists( '\\Oradel_Plugin\\Oradel_Plugin' ) ) {
            require_once plugin_dir_path( __FILE__ ) . 'includes/plugin.php';
        }
        $widgets = \Oradel_Plugin\Oradel_Plugin::instance()->get_widgets();
        $widgets_status = \Oradel_Plugin\Oradel_Plugin::instance()->get_widget_statuses();
        ?>
        <div class="oea-tab-pane">
            <h2>Widgets Settings</h2>
            <p><?php 
        echo esc_html__( 'Enable or disable individual widgets.', 'orange-addons-for-elementor' );
        ?></p>
            <form id="oea-widgets-form" method="post">
                <table class="form-table">
                    <?php 
        foreach ( $widgets as $name => $widget ) {
            ?>
                        <tr>
                            <th scope="row"><?php 
            echo esc_html( $widget['title'] );
            ?></th>
                            <td>
                                <div class="oea-toggle-switch">
                                    <input type="hidden" name="oradel_elementor_widgets_status[<?php 
            echo esc_attr( $name );
            ?>]"
                                        value="0" />
                                    <input type="checkbox" id="oradel_widget_<?php 
            echo esc_attr( $name );
            ?>"
                                        name="oradel_elementor_widgets_status[<?php 
            echo esc_attr( $name );
            ?>]" value="1" <?php 
            checked( 1, ( isset( $widgets_status[$name] ) && $widgets_status[$name] == '1' ? 1 : 0 ) );
            ?> />
                                    <label for="oradel_widget_<?php 
            echo esc_attr( $name );
            ?>"></label>
                                </div>
                            </td>
                        </tr>
                    <?php 
        }
        ?>
                </table>
                <p class="submit">
                    <button type="submit" id="submit"
                        class="button button-primary"><?php 
        echo esc_html__( 'Save Changes', 'orange-addons-for-elementor' );
        ?></button>
                </p>
            </form>
        </div>
        <?php 
    }
    $html = ob_get_clean();
    wp_send_json_success( [
        'html' => $html,
    ] );
    wp_die();
}

add_action( 'wp_ajax_oradel_save_widgets_settings', 'oradel_save_widgets_settings' );
function oradel_save_widgets_settings() {
    if ( !isset( $_POST['nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'oradel_settings_nonce' ) ) {
        wp_send_json_error( [
            'message' => 'Invalid nonce',
        ] );
        wp_die();
    }
    if ( !current_user_can( 'manage_options' ) ) {
        wp_send_json_error( [
            'message' => 'Insufficient permissions',
        ] );
        wp_die();
    }
    if ( !isset( $_POST['form_data'] ) ) {
        wp_send_json_error( [
            'message' => 'No form data received',
        ] );
        wp_die();
    }
    // Parse the serialized form data string into an array
    // Validate and sanitize the raw form data string before parsing
    // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Data is sanitized after parsing using oradel_sanitize_widgets_status()
    $raw_form_data = wp_unslash( $_POST['form_data'] );
    // Validate that we have a non-empty string
    if ( empty( $raw_form_data ) || !is_string( $raw_form_data ) ) {
        wp_send_json_error( [
            'message' => 'Invalid form data format',
        ] );
        wp_die();
    }
    // Additional validation: ensure the string contains valid form data structure
    if ( strlen( $raw_form_data ) > 10000 ) {
        wp_send_json_error( [
            'message' => 'Form data too large',
        ] );
        wp_die();
    }
    $form_data = [];
    parse_str( $raw_form_data, $form_data );
    if ( isset( $form_data['oradel_elementor_widgets_status'] ) ) {
        // Sanitize all values using the registered sanitization callback
        $new_settings = oradel_sanitize_widgets_status( $form_data['oradel_elementor_widgets_status'] );
        update_option( 'oradel_elementor_widgets_status', $new_settings );
        wp_send_json_success( [
            'message' => 'Settings saved',
        ] );
    } else {
        wp_send_json_error( [
            'message' => 'No settings data received',
        ] );
    }
    wp_die();
}

function force_elementor_font_awesome() {
    if ( did_action( 'elementor/loaded' ) ) {
        wp_enqueue_style(
            'font-awesome-5',
            plugins_url( '/elementor/assets/lib/font-awesome/css/all.min.css', 'elementor' ),
            array(),
            ( defined( 'ELEMENTOR_VERSION' ) ? ELEMENTOR_VERSION : '5.15.4' )
        );
    }
}

add_action( 'wp_enqueue_scripts', 'force_elementor_font_awesome', 100 );
oradel_fs()->add_filter( 'pricing_url', function ( $url ) {
    return 'https://orange-addons.com/?ref=oradel-admin-settings#pricing-plans';
} );