<?php
/**
 * Responsive Portfolio Image Gallery Pro - Shortcode Handler
 *
 * Handles the [rpgal-gallery] shortcode to display portfolio galleries.
 *
 * @package Responsive Portfolio Image Gallery 1.3 - 10 July, 2025
 * @link https://www.realwebcare.com/
 */

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

if (!class_exists('RPGAL_Shortcode')) {
    /**
     * Class RPGAL_Shortcode
     *
     * Manages the portfolio gallery shortcode and frontend rendering.
     */
    class RPGAL_Shortcode
    {
        /**
         * Singleton instance.
         *
         * @var RPGAL_Shortcode|null
         */
        private static $instance;

        /**
         * Instance of RPGAL_Functions.
         *
         * @var RPGAL_Functions
         */
        private $rpgal_functions;

        /**
         * Constructor.
         */
        private function __construct()
        {
            $this->rpgal_functions = RPGAL_Functions::get_instances();

            add_shortcode('rpgal-gallery', [$this, 'rpgal_shortcode_function']);

            // Add inline styles for the plugin.
            add_action('wp_enqueue_scripts', array($this, 'rpgal_add_inline_styles'), 100);
        }

        /**
         * Get singleton instance.
         *
         * @return RPGAL_Shortcode
         */
        public static function get_instances()
        {
            if (self::$instance) {
                return self::$instance;
            }

            self::$instance = new self();

            return self::$instance;
        }

        /**
         * Prevent cloning.
         */
        private function __clone()
        {
            // Do nothing.
        }

        /**
         * Render the [rpgal-gallery] shortcode.
         *
         * @param array $atts Shortcode attributes.
         * @return string HTML output of the gallery.
         */
        public function rpgal_shortcode_function($atts)
        {
            // Define default shortcode attributes.
            $atts = shortcode_atts(
                [
                    'orderby' => 'date', // Default orderby
                    'order' => 'DESC', // Default order
                ],
                $atts,
                'rpgal-gallery'
            );

            // Sanitize shortcode attributes.
            $orderby = sanitize_text_field($atts['orderby']);
            $order = in_array(strtoupper($atts['order']), array('ASC', 'DESC')) ? strtoupper($atts['order']) : 'DESC';

            $portfolio_id = 'main';

            // Start output buffering.
            ob_start();

            $rpgal_enable = sanitize_text_field(rpgal_get_option('rpgal_enable', 'rpgal_general', 'on'));
            $rpgal_porder = sanitize_text_field(rpgal_get_option('rpgal_postorder', 'rpgal_general', $order));
            $rpgal_porder_by = sanitize_text_field(rpgal_get_option('rpgal_postorder_by', 'rpgal_general', $orderby));

            $rpgal_numop = rpgal_get_option('rpgal_postno', 'rpgal_general', -1);
            $rpgal_numop = filter_var($rpgal_numop, FILTER_VALIDATE_INT, ['options' => ['min_range' => -1]]);

            // Include selected categiry form portfolio.
            $portfolio_cats = array_map('intval', rpgal_get_option('rpgal_categories', 'rpgal_general', []));

            $rpgal_taxonomy = 'rpgal-category';

            $args = array(
                'post_type' => 'rpgal',
                'post_status' => 'publish',
                'posts_per_page' => $rpgal_numop,
                'orderby' => $rpgal_porder_by,
                'order' => $rpgal_porder,
                'tax_query' => array(
                    array(
                        'taxonomy' => $rpgal_taxonomy,
                        'terms' => $portfolio_cats,
                        'field' => 'id'
                    )
                )
            );

            $loop = new WP_Query($args);

            if ($loop->have_posts() && $rpgal_enable == 'on') {
                ?>
                <div id="rpgal_<?php echo esc_attr($portfolio_id); ?>" class="rpgal_content">
                    <div id="rpgal_grid_demo" class="rpgal_grid_demo"></div>
                    <?php
                    $image_width = intval(rpgal_get_option('rpgal_img_width', 'rpgal_general', 250));
                    $image_height = intval(rpgal_get_option('rpgal_img_height', 'rpgal_general', 250));
                    $excerpt_length = intval(rpgal_get_option('rpgal_excerpt_ln', 'rpgal_general', 30));
                    $expand_height = intval(rpgal_get_option('rpgal_exp_height', 'rpgal_advanced', 500));
                    $show_plain = sanitize_text_field(rpgal_get_option('rpgal_show_plain', 'rpgal_general', 'on'));
                    $filter_effect = sanitize_text_field(rpgal_get_option('rpgal_filter_effect', 'rpgal_advanced', 'popup'));
                    $hover_direct = sanitize_text_field(rpgal_get_option('rpgal_hover_dir', 'rpgal_advanced', 'on'));
                    $hover_inverse = sanitize_text_field(rpgal_get_option('rpgal_hover_inv', 'rpgal_advanced', 'off'));
                    $hover_effect = sanitize_text_field(rpgal_get_option('rpgal_hover_effect', 'rpgal_advanced', 'none'));
                    $hide_excerpt = sanitize_text_field(rpgal_get_option('rpgal_hide_excerpt', 'rpgal_advanced', 'off'));
                    $show_wrapper = sanitize_text_field(rpgal_get_option('rpgal_show_wrap', 'rpgal_advanced', 'on'));

                    // Prepare data for inline script.
                    $data = [
                        'loop' => $loop,
                        'postid' => get_the_ID(),
                        'id' => $portfolio_id,
                        'effect' => $filter_effect,
                        'hvdir' => $hover_direct,
                        'plain' => $show_plain,
                        'hvinv' => $hover_inverse,
                        'exhgt' => $expand_height,
                        'pcats' => $portfolio_cats,
                        'imgwd' => $image_width,
                        'imght' => $image_height,
                        'excln' => $excerpt_length,
                    ];

                    $custom_css = '';

                    $custom_css .= '#rpgal_' . $portfolio_id . ' .og-fullimg img{height:' . $expand_height . 'px;}' . PHP_EOL;

                    if ($hover_effect === 'zoompan') {
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid li{width:' . $image_width . 'px;height:' . $image_height . 'px;}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li>a img{-webkit-transition:all 0.2s linear;-moz-transition:all 0.2s linear;-o-transition:all 0.2s linear;-ms-transition:all 0.2s linear;transition:all 0.2s linear;}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li:hover>a img{-webkit-transform:scale(1.1,1.1);-moz-transform:scale(1.1,1.1);-o-transform:scale(1.1,1.1);-ms-transform:scale(1.1,1.1);transform:scale(1.1,1.1);}' . PHP_EOL;
                    } elseif ($hover_effect === 'zoomhide') {
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid li{width:' . $image_width . 'px;height:' . $image_height . 'px;}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li>a img{-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-o-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1);-webkit-transition:all 0.7s ease-in-out;-moz-transition:all 0.7s ease-in-out;-o-transition:all 0.7s ease-in-out;-ms-transition:all 0.7s ease-in-out;transition:all 0.7s ease-in-out;}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li:hover>a img{-webkit-transform:scale(10);-moz-transform:scale(10);-o-transform:scale(10);-ms-transform:scale(10);transform:scale(10);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);opacity:0;}' . PHP_EOL;
                    } elseif ($hover_effect === 'shrink') {
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid li{width:' . $image_width . 'px;height:' . $image_height . 'px;}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li>a img{-webkit-transition:opacity 0.35s,-webkit-transform 0.35s;transition:opacity 0.35s,transform 0.35s;-webkit-transform:scale(1.15);transform:scale(1.15);}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li:hover>a img{opacity:0.5;-webkit-transform:scale(1);transform:scale(1);}' . PHP_EOL;
                    } elseif ($hover_effect === 'slideout') {
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid li{width:' . $image_width . 'px;height:' . $image_height . 'px;}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li>a img{-webkit-transition:all 0.3s ease-in-out;-moz-transition:all 0.3s ease-in-out;-o-transition:all 0.3s ease-in-out;-ms-transition:all 0.3s ease-in-out;transition:all 0.3s ease-in-out;}' . PHP_EOL;
                        $custom_css .= '#rpgal_' . $portfolio_id . ' ul.og-grid>li:hover>a img{-webkit-transform:translateX(300px);-moz-transform:translateX(300px);-o-transform:translateX(300px);-ms-transform:translateX(300px);transform:translateX(300px);}' . PHP_EOL;
                    }

                    // Hide wrapper if needed
                    if ($show_wrapper === 'hide') {
                        $custom_css .= '#rpgal_' . $portfolio_id . ' .rpgalslide-wrapper,#rpgal_' . $portfolio_id . ' .og-details .infosep{display:none;}' . PHP_EOL;
                    }

                    // Hide excerpt if needed
                    if ($hide_excerpt === 'hide') {
                        $custom_css .= '#rpgal_' . $portfolio_id . ' .og-expander p{display:none;}' . PHP_EOL;
                    }

                    if (get_option('rpgal_custom_css') !== $custom_css) {
                        update_option('rpgal_custom_css', $custom_css);
                    }

                    $script = $this->rpgal_functions->get_inline_portfolio_script($data);

                    if (wp_script_is('rpgal-grid', 'enqueued')) {
                        wp_add_inline_script('rpgal-grid', $script);
                    } else {
                        wp_register_script('rpgal-init', false, array(), '1.3', array('in_footer' => true));
                        wp_enqueue_script('rpgal-init');
                        wp_add_inline_script('rpgal-init', $script);
                    }
                    echo '</div>';
            } else {
                esc_html_e('No portfolio found. Make sure that the display portfolio is enabled in portfolio settings.', 'responsive-portfolio-image-gallery');
            }
            wp_reset_postdata();
            return ob_get_clean();
        }

        /**
         * Adds custom inline styles to the front-end for the Responsive Portfolio Gallery.
         *
         * This method retrieves the stored custom CSS from the plugin options
         * and appends it as an inline style using WordPress's enqueue system.
         * It only executes if valid custom CSS exists to prevent unnecessary style injection.
         *
         * @return void
         */
        public function rpgal_add_inline_styles()
        {
            // Retrieve stored custom CSS from the database option.
            $custom_css = get_option('rpgal_custom_css', '');
            $user_css = rpgal_get_option('rpgal_custom_css', 'rpgal_style', '');

            // Exit if there is no custom CSS to add.
            if (empty($custom_css)) {
                return;
            }

            // Check if user has entered any CSS or not
            if (!empty($user_css)) {
                $custom_css .= sanitize_textarea_field($user_css);
            }

            // Register a dummy stylesheet handle for inline styles.
            wp_register_style('rpgal-custom', false, [], '1.3');

            // Enqueue the dummy stylesheet to allow inline style attachment.
            wp_enqueue_style('rpgal-custom');

            // Add the stored custom CSS as inline style to the dummy handle.
            wp_add_inline_style('rpgal-custom', $custom_css); // Keep CSS syntax safe
        }
    }

    // Initialize the shortcode class.
    RPGAL_Shortcode::get_instances();
}
