<?php
/**
 * Copyright (C) 2026 Plugixa (https://plugixa.com)
 * License: GNU General Public License v2 or later
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 */

namespace PlugixaRecipe\Integrations\Elementor;

// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber, WordPress.DB.SlowDBQuery, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom-table data layer: table identifiers are built with $wpdb->prefix and are never user input; all request values are bound via $wpdb->prepare(); ORDER BY / LIMIT fragments come out of internal allow-list maps; content reads go through PlugixaRecipe\Cache (the static sniff cannot trace caching through the wrapper); meta_key/meta_value are dedicated plugin columns, not WP_Query.

defined( 'ABSPATH' ) || exit;

use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use PlugixaRecipe\Frontend\Shortcodes;

/**
 * RecipeWidget - Elementor widget for displaying recipes.
 *
 * Allows users to select a saved shortcode configuration or create a custom
 * recipe display configuration directly within the Elementor editor.
 */
class RecipeWidget extends Widget_Base {

    /**
     * Get widget name.
     */
    public function get_name(): string {
        return 'plugixarecipe_recipes';
    }

    /**
     * Get widget title.
     */
    public function get_title(): string {
        return __('Plugixa Recipes', 'plugixarecipe');
    }

    /**
     * Get widget icon.
     */
    public function get_icon(): string {
        return 'eicon-gallery-grid';
    }

    /**
     * Get widget categories.
     */
    public function get_categories(): array {
        return ['plugixarecipe'];
    }

    /**
     * Get widget keywords.
     */
    public function get_keywords(): array {
        return ['recipe', 'food', 'cooking', 'recipes', 'plugixa'];
    }

    /**
     * Register widget controls.
     */
    protected function register_controls(): void {
        // Content section
        $this->start_controls_section('section_content', [
            'label' => __('Recipe Display', 'plugixarecipe'),
            'tab'   => Controls_Manager::TAB_CONTENT,
        ]);

        $this->add_control('source_type', [
            'label'   => __('Source', 'plugixarecipe'),
            'type'    => Controls_Manager::SELECT,
            'default' => 'shortcode',
            'options' => [
                'shortcode' => __('Saved Shortcode', 'plugixarecipe'),
                'custom'    => __('Custom Configuration', 'plugixarecipe'),
            ],
        ]);

        // Saved shortcode selector
        $this->add_control('shortcode_id', [
            'label'     => __('Select Shortcode', 'plugixarecipe'),
            'type'      => Controls_Manager::SELECT,
            'default'   => '',
            'options'   => $this->get_shortcode_options(),
            'condition' => ['source_type' => 'shortcode'],
        ]);

        // Custom configuration controls
        $this->add_control('view_id', [
            'label'     => __('View / Layout', 'plugixarecipe'),
            'type'      => Controls_Manager::SELECT,
            'default'   => '',
            'options'   => $this->get_view_options(),
            'condition' => ['source_type' => 'custom'],
        ]);

        $this->add_control('categories', [
            'label'       => __('Categories', 'plugixarecipe'),
            'type'        => Controls_Manager::TEXT,
            'placeholder' => __('e.g. quick-easy, healthy', 'plugixarecipe'),
            'description' => __('Comma-separated category slugs to filter by.', 'plugixarecipe'),
            'condition'   => ['source_type' => 'custom'],
        ]);

        $this->add_control('cuisines', [
            'label'       => __('Cuisines', 'plugixarecipe'),
            'type'        => Controls_Manager::TEXT,
            'placeholder' => __('e.g. italian, thai', 'plugixarecipe'),
            'description' => __('Comma-separated cuisine slugs to filter by.', 'plugixarecipe'),
            'condition'   => ['source_type' => 'custom'],
        ]);

        $this->add_control('limit', [
            'label'     => __('Number of Recipes', 'plugixarecipe'),
            'type'      => Controls_Manager::NUMBER,
            'default'   => 12,
            'min'       => 1,
            'max'       => 100,
            'condition' => ['source_type' => 'custom'],
        ]);

        $this->add_control('orderby', [
            'label'     => __('Order By', 'plugixarecipe'),
            'type'      => Controls_Manager::SELECT,
            'default'   => 'created_at',
            'options'   => [
                'created_at'     => __('Date Created', 'plugixarecipe'),
                'title'          => __('Title', 'plugixarecipe'),
                'rating_average' => __('Rating', 'plugixarecipe'),
                'prep_time'      => __('Prep Time', 'plugixarecipe'),
                'total_time'     => __('Total Time', 'plugixarecipe'),
                'view_count'     => __('Popularity', 'plugixarecipe'),
            ],
            'condition' => ['source_type' => 'custom'],
        ]);

        $this->add_control('order', [
            'label'     => __('Order', 'plugixarecipe'),
            'type'      => Controls_Manager::SELECT,
            'default'   => 'DESC',
            'options'   => [
                'ASC'  => __('Ascending', 'plugixarecipe'),
                'DESC' => __('Descending', 'plugixarecipe'),
            ],
            'condition' => ['source_type' => 'custom'],
        ]);

        $this->add_control('featured', [
            'label'        => __('Featured Only', 'plugixarecipe'),
            'type'         => Controls_Manager::SWITCHER,
            'default'      => '',
            'label_on'     => __('Yes', 'plugixarecipe'),
            'label_off'    => __('No', 'plugixarecipe'),
            'return_value' => 'true',
            'condition'    => ['source_type' => 'custom'],
        ]);

        $this->add_control('difficulty', [
            'label'     => __('Difficulty', 'plugixarecipe'),
            'type'      => Controls_Manager::SELECT,
            'default'   => '',
            'options'   => [
                ''       => __('All', 'plugixarecipe'),
                'easy'   => __('Easy', 'plugixarecipe'),
                'medium' => __('Medium', 'plugixarecipe'),
                'hard'   => __('Hard', 'plugixarecipe'),
            ],
            'condition' => ['source_type' => 'custom'],
        ]);

        $this->add_control('pagination', [
            'label'        => __('Enable Pagination', 'plugixarecipe'),
            'type'         => Controls_Manager::SWITCHER,
            'default'      => '',
            'label_on'     => __('Yes', 'plugixarecipe'),
            'label_off'    => __('No', 'plugixarecipe'),
            'return_value' => 'true',
            'condition'    => ['source_type' => 'custom'],
        ]);

        $this->add_control('dark_mode', [
            'label'        => __('Dark Mode', 'plugixarecipe'),
            'type'         => Controls_Manager::SWITCHER,
            'default'      => '',
            'label_on'     => __('Yes', 'plugixarecipe'),
            'label_off'    => __('No', 'plugixarecipe'),
            'return_value' => 'true',
        ]);

        $this->end_controls_section();
    }

    /**
     * Render widget output on the frontend.
     */
    protected function render(): void {
        $settings = $this->get_settings_for_display();

        $shortcode_atts = [];

        if ($settings['source_type'] === 'shortcode' && !empty($settings['shortcode_id'])) {
            $shortcode_atts['id'] = (int) $settings['shortcode_id'];
        } else {
            if (!empty($settings['view_id'])) {
                $shortcode_atts['view'] = $settings['view_id'];
            }
            if (!empty($settings['categories'])) {
                $shortcode_atts['categories'] = $settings['categories'];
            }
            if (!empty($settings['cuisines'])) {
                $shortcode_atts['cuisines'] = $settings['cuisines'];
            }
            if (!empty($settings['limit'])) {
                $shortcode_atts['limit'] = (int) $settings['limit'];
            }
            if (!empty($settings['orderby'])) {
                $shortcode_atts['orderby'] = $settings['orderby'];
            }
            if (!empty($settings['order'])) {
                $shortcode_atts['order'] = $settings['order'];
            }
            if (!empty($settings['featured'])) {
                $shortcode_atts['featured'] = $settings['featured'];
            }
            if (!empty($settings['difficulty'])) {
                $shortcode_atts['difficulty'] = $settings['difficulty'];
            }
            if (!empty($settings['pagination'])) {
                $shortcode_atts['pagination'] = $settings['pagination'];
            }
        }

        if (!empty($settings['dark_mode'])) {
            $shortcode_atts['dark_mode'] = $settings['dark_mode'];
        }

        $shortcodes = new Shortcodes();
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- render_recipes() returns a fully-rendered template fragment (the same string the Gutenberg block returns for WP to print); every dynamic value inside it is escaped at its own output site in Shortcodes::render_recipes() and templates/*.php. Escaping here would destroy the plugin's own layout markup.
        echo $shortcodes->render_recipes($shortcode_atts);
    }

    /**
     * Get saved shortcodes for the dropdown.
     */
    private function get_shortcode_options(): array {
        global $wpdb;
        $table = $wpdb->prefix . 'plugixarecipe_shortcodes';

        $results = $wpdb->get_results("SELECT id, name FROM {$table} ORDER BY name ASC", ARRAY_A);

        $options = ['' => __('-- Select a Shortcode --', 'plugixarecipe')];
        foreach ($results ?: [] as $row) {
            $options[(string) $row['id']] = $row['name'];
        }

        return $options;
    }

    /**
     * Get available views for the dropdown.
     */
    private function get_view_options(): array {
        global $wpdb;
        $table = $wpdb->prefix . 'plugixarecipe_views';

        $results = $wpdb->get_results("SELECT id, name FROM {$table} ORDER BY name ASC", ARRAY_A);

        $options = ['' => __('-- Default View --', 'plugixarecipe')];
        foreach ($results ?: [] as $row) {
            $options[(string) $row['id']] = $row['name'];
        }

        return $options;
    }
}
