<?php

defined( 'ABSPATH' ) || exit;

final class W2PShopSettings {

	/**
	 * Unified allowed HTML array for wp_kses() sanitization across all form generation methods
	 */
	private const ALLOWED_HTML = array(
		// Table elements
		'tr' => array(),
		'th' => array(
			'scope' => true,
			'class' => true,
		),
		'td' => array(
			'class' => true,
		),
		
		// Paragraph elements
		'p' => array(
			'class' => true,
			'id'    => true,
		),
		
		// Form elements
		'label' => array(
			'for' => true,
		),
		'input' => array(
			'type'     => true,
			'name'     => true,
			'id'       => true,
			'value'    => true,
			'class'    => true,
			'style'    => true,
			'readonly' => true,
			'checked'  => true,
			'size'     => true,
			'step'     => true,
			'min'      => true,
			'max'      => true,
		),
		'select' => array(
			'name'       => true,
			'id'         => true,
			'class'      => true,
			'style'      => true,
			'data-input' => true,
			'multiple'   => true,
		),
		'option' => array(
			'value'          => true,
			'selected'       => true,
			'class'          => true,
			'data-parent-id' => true,
		),
		'textarea' => array(
			'class' => true,
			'rows'  => true,
			'name'  => true,
			'id'    => true,
		),
		'fieldset' => array(),
		'legend' => array(
			'class' => true,
		),
		
		// Text elements
		'span' => array(
			'class' => true,
			'style' => true,
		),
		'a' => array(
			'href'   => true,
			'target' => true,
		),
		
		// Line break
		'br' => array(),
	);

	public static function get_settings() {
		// Get current saved settings.
		if ( is_multisite() ) {
			$settings = get_blog_option( get_current_blog_id(), 'w2pshop_settings' );
		} else {
			$settings = get_option( 'w2pshop_settings' );
		}

		// In case there are no saved settings, return an empty array.
		$settings = ( ! $settings ) ? array() : $settings;

		// Define any default settings.
		$default_settings = array();
		$default_settings = apply_filters( 'w2pshop_default_settings', $default_settings );

		// Apply any default settings to the main settings array if they are not set.
		foreach ( $default_settings as $key => $value ) {
			if ( ! isset( $settings[ $key ] ) ) {
				$settings[ $key ] = $value;
			}
		}

		// Store settings in database.
		if ( is_multisite() ) {
			update_blog_option( get_current_blog_id(), 'w2pshop_settings', $settings );
		} else {
			update_option( 'w2pshop_settings', $settings );
		}

		return $settings;
	}

	public static function get_setting( $name, $without_sanitization = false ) {
		$settings = self::get_settings();
		$value    = '';
		if ( array_key_exists( $name, $settings ) ) {
			if ( $without_sanitization ) {
				$value = $settings[ $name ];
			} else {
				$value = W2PShopUtil::sanitize_variable( $settings[ $name ] );
			}
		}
		return $value;
	}

	public static function get_setting_with_default( $name, $default_value, $without_sanitization = false ) {
		$value = self::get_setting( $name, $without_sanitization );
		// Check if $value is an array or  empty, return default value
		if ( ! is_string( $value ) || strlen( $value ) == 0 ) {
			return $default_value;
		} else {
			return $value;
		}
	}

	public static function get_product_option( $post_id, $name, $default_value = null ) {
		$product_options = get_post_meta( $post_id, '_w2pshop_product', true );

		if ( ! is_array( $product_options ) ) {
			return $default_value;
		}
		if ( ! array_key_exists( $name, $product_options ) ) {
			return $default_value;
		}

		return $product_options[ $name ];
	}

	public static function get_product_data_value( $product_data, $name, $default_value = null ) {
		if ( ! is_array( $product_data ) ) {
			return $default_value;
		}

		$filtered_data = array_values(
			array_filter(
				$product_data,
				function ( $data ) use ( $name ) {
					// Support both array and object shapes for product data entries
					if ( is_array( $data ) ) {
						return ( $data['key'] ?? null ) === $name;
					}
					if ( is_object( $data ) ) {
						return ( $data->key ?? null ) === $name;
					}
					return false;
				}
			)
		);

		if ( count( $filtered_data ) > 0 ) {
			$first = $filtered_data[0];
			if ( is_array( $first ) ) {
				return array_key_exists( 'value', $first ) ? $first['value'] : $default_value;
			}
			if ( is_object( $first ) ) {
				return $first->value ?? $default_value;
			}
		}
		return $default_value;
	}

	public static function get_product_item_data_array_by_order_item( $order_id, $item_id ) : array|null {
		// Check if order ID and item ID are valid
		if ( empty( $order_id ) || empty( $item_id ) ) {
			return null;
		}

		// Get the order object
		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			return null;
		}

		// Get the item object
		$item = $order->get_item( $item_id );
		if ( ! $item ) {
			return null;
		}

		// Get the product data
		$w2pshop_product_item_data = $item->get_meta( '_w2pshop_product' );
		if ( ! empty( $w2pshop_product_item_data ) && is_array( $w2pshop_product_item_data ) ) {
			return $w2pshop_product_item_data;
		}

		return null;
	}

	public static function is_w2pshop_product( $post_id ) {
		return self::get_product_option( $post_id, 'is_enabled', false );
	}

	public static function update_setting( $name, $value ): void {
		$settings          = self::get_settings();
		$settings[ $name ] = $value;

		self::update_settings( $settings );
	}

	public static function update_settings( $settings ): void {
		if ( is_multisite() ) {
			update_blog_option( get_current_blog_id(), 'w2pshop_settings', $settings );
			restore_current_blog();
		} else {
			update_option( 'w2pshop_settings', $settings );
		}
	}

	public static function handle_settings_save( $settings_tab = '' ): array {
        $settings = self::get_settings();
        if ( ! isset( $_REQUEST['w2pshop_settings_nonce'] ) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['w2pshop_settings_nonce'])), 'save_w2pshop_settings' ) ) {
            return $settings;
        }
		if ( isset( $_REQUEST['save_w2pshop_settings'] ) ) {
			if ( empty( $settings_tab ) ) {
				$settings_tab = ( isset( $_REQUEST['tab'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['tab'] )) : '';
			}
			$settings = apply_filters( 'w2pshop_settings_save', $settings, $settings_tab );

			self::update_settings( $settings );
		}

		return $settings;
	}

	public static function generate_settings_header_html( $header_label ): void {
        echo wp_kses_post(
            '<tr>'
            . '<td colspan="2" style="line-height: 0; padding:0;">'
            . '<h2>' . esc_html( $header_label ) . '</h2>'
            . '<hr />'
            . '</td>'
            . '</tr>'
        );
	}

    public static function generate_settings_label_href_html( $label, $id, $setting, $href ): void {
        $setting_value_esc = esc_attr( $setting );
        $label_esc         = esc_html( $label );
        $id_esc            = esc_attr( $id );
        $href_esc          = esc_url( $href );
	    $html              = self::make_settings_label_start( $id_esc, $label_esc, $setting_value_esc );
	    $html .= '<a href="' . $href_esc . '" target="_blank">' . $href_esc . '</a>';
        $html .= '</td>';
        $html .= '</tr>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_settings_label_no_href_html( $label, $id, $setting, $non_href ): void {
        $setting_value_esc = esc_attr( $setting );
        $label_esc         = esc_html( $label );
        $id_esc            = esc_attr( $id );
        $non_href_esc      = esc_html( $non_href );
	    $html              = self::make_settings_label_start( $id_esc, $label_esc, $setting_value_esc );
	    $html .= '<span>' . $non_href_esc . '</span>';
        $html .= '</td>';
        $html .= '</tr>';
        echo wp_kses_post( $html );
    }

    public static function generate_settings_input_html( $label, $id, $setting, $is_password = false, $read_only = false, $message = '' ): void {
        $setting_value       = esc_attr( $setting );
        $input_type          = $is_password ? 'password' : 'text';
        $read_only_attribute = $read_only ? ' readonly="readonly"' : '';
        $label_escaped   = esc_html( $label );
        $id_escaped      = esc_attr( $id );
        $message_escaped = $message;
        $html  = '<tr>';
        $html .= '<th scope="row" class="titledesc">';
        $html .= '<label for="' . $id_escaped . '">' . $label_escaped . '</label>';
        $html .= '</th>';
        $html .= '<td class="forminp forminp-text">';
        $html .= '<input name="' . $id_escaped . '" id="' . $id_escaped . '" type="' . $input_type . '" style="width: 350px;" value="' . $setting_value . '"' . $read_only_attribute . '>';
        $html .= '<br/><span class="description">' . $message_escaped . '</span>';
        $html .= '</td>';
        $html .= '</tr>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_settings_select_html( $label, $id, $selected_value, $options_array, $display_empty = false ): void {
        $id_escaped    = esc_attr( $id );
        $label_escaped = esc_html( $label );
        $empty_option  = $display_empty ? '<option value=""></option>' : '';
        $options_html  = '';
        foreach ( $options_array as $key => $value ) {
            $key_escaped   = esc_attr( $key );
            $value_escaped = esc_html( $value );
            $is_selected   = ( (string) $key === (string) $selected_value ) ? ' selected="selected"' : '';
            $options_html .= '<option class="level-0" value="' . $key_escaped . '"' . $is_selected . '>' . $value_escaped . '</option>';
        }
        $html  = '<tr>';
        $html .= '<th scope="row" class="titledesc">';
        $html .= '<label for="' . $id_escaped . '">' . $label_escaped . '</label>';
        $html .= '</th>';
        $html .= '<td class="forminp forminp-text">';
        $html .= '<select name="' . $id_escaped . '" id="' . $id_escaped . '" style="width: 350px;">';
        $html .= $empty_option;
        $html .= $options_html;
        $html .= '</select>';
        $html .= '</td>';
        $html .= '</tr>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_settings_checkbox_html( string $label, string $id, string $description, bool $is_checked = false ): void {
        $id_escaped          = esc_attr( $id );
	    $allowed_tags = array(
		    'br' => array(),
		    'strong' => array(),
	    );
        $label_escaped       = wp_kses($label, $allowed_tags );
        $description_escaped = wp_kses($description, $allowed_tags );
        $checked_html        = $is_checked ? ' checked="checked"' : '';
        $html  = '<tr>';
        $html .= '<th scope="row" class="titledesc">';
        $html .= '<label for="' . $id_escaped . '">' . $label_escaped . '</label>';
        $html .= '</th>';
        $html .= '<td class="forminp forminp-text">';
        $html .= '<fieldset>';
        $html .= '<legend class="screen-reader-text"><span>' . $label_escaped . '</span></legend>';
        $html .= '<input name="' . $id_escaped . '" id="' . $id_escaped . '" type="checkbox" value="true"' . $checked_html . '>';
        $html .= '<label for="' . $id_escaped . '">' . $description_escaped . '</label>';
        $html .= '</fieldset>';
        $html .= '</td>';
        $html .= '</tr>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_settings_file_extension_html( $label, $id, $selected_settings, $description, $include_table = false ): void {
        $default_array           = array( '.pdf', '.png', '.jpeg', '.jpg', '.gif', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.txt', '.ppt', '.pptx', '.psd', '.ai', '.eps', '.indd', '.cdr', '.zip', '.tif', '.tiff', '.qxd' );
        $id_escaped              = esc_attr( $id );
	    $allowed_tags = array(
		    'br' => array(),
		    'strong' => array(),
	    );
	    $label_escaped           = wp_kses( $label, $allowed_tags );
	    $description_escaped     = wp_kses( $description, $allowed_tags );
        $selected_value_escaped  = esc_attr( is_array( $selected_settings ) ? implode( ',', $selected_settings ) : $selected_settings );
        $selected_settings_array = is_array( $selected_settings ) ? $selected_settings : explode( ',', $selected_settings );
        $hidden_input = '<input type="hidden" id="' . $id_escaped . '" value="' . $selected_value_escaped . '" name="' . $id_escaped . '">';
        $options_html = '<select class="w2p-multiselect-dropdown" data-input="' . $id_escaped . '" id="s_' . $id_escaped . '" multiple="multiple" name="s_' . $id_escaped . '[]">';
        foreach ( $default_array as $value ) {
            $value_escaped = esc_attr( $value );
            $is_selected   = in_array( $value, $selected_settings_array, true ) ? ' selected="selected"' : '';
            $options_html .= '<option data-parent-id="' . $id_escaped . '" value="' . $value_escaped . '"' . $is_selected . '>' . $value_escaped . '</option>';
        }
        $options_html .= '</select>';
        if ( $include_table ) {
            $html  = '<tr>';
            $html .= '<th scope="row" class="titledesc">';
            $html .= '<label for="' . $id_escaped . '">' . $label_escaped . '</label>';
            $html .= '</th>';
            $html .= '<td class="forminp forminp-text">';
            $html .= $hidden_input;
            $html .= $options_html;
            $html .= '<br/>';
            $html .= '<span class="description">' . $description_escaped . '</span>';
            $html .= '</td>';
            $html .= '</tr>';
        } else {
            $html  = '<p class="form-field" id="' . $id_escaped . '_form_group">';
            $html .= '<label for="' . $id_escaped . '">' . $label_escaped . '</label>';
            $html .= $hidden_input;
            $html .= $options_html;
            $html .= '<span class="description" style="position: absolute; bottom: 10px; margin: 0;">' . $description_escaped . '</span>';
            $html .= '</p>';
        }
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_p_options_checkbox_html( string $label, string $id, string $description, bool $is_checked = false ): void {
	    $allowed_tags = array(
		    'br' => array(),
		    'strong' => array(),
	    );
        $checked_html = ( $is_checked ) ? ' checked="checked"' : '';
        $html  = '<p class="form-field" id="' . esc_attr( $id ) . '_form_group">';
        $html .= '<label for="' . esc_attr( $id ) . '">' . wp_kses( $label, $allowed_tags ) . '</label>';
        $html .= '<input type="checkbox" class="checkbox" name="' . esc_attr( $id ) . '" id="' . esc_attr( $id ) . '" value="yes"' . $checked_html . '/>';
        $html .= '<span class="description">' . wp_kses( $description, $allowed_tags ) . '</span>';
        $html .= '</p>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_p_options_dimensions_html( $label, $id, $value = null ): void {
        $value = $value ?? '1';
        $value = preg_replace( '/^(\d+)\.(\d{0,3})\d*|\.+$/', '$1.$2', $value );
        $value_attr = ' value="' . esc_attr( $value ) . '"';
        $html  = '<p class="form-field dimensions_field">';
        $html .= '<label for="' . esc_attr( $id ) . '">' . esc_html( $label ) . '</label>';
        $html .= '<input type="text" class="input-text wc_input_decimal" name="' . esc_attr( $id ) . '" id="' . esc_attr( $id ) . '" size="2" ' . $value_attr . ' style="width: 60px;">';
        $html .= '</p>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_p_options_uom_html( $label, $id, $selected = 'cm' ): void {
        $units = array( 'cm', 'mm', 'inch' );
        $unit_options = '';
        foreach ( $units as $unit ) {
            $selected_attr = ( $unit === $selected ) ? 'selected' : '';
            $unit_options .= "<option value='" . esc_attr( $unit ) . "' $selected_attr>" . esc_html( $unit ) . "</option>";
        }
        $html  = '<p class="form-field" id="' . esc_attr( $id ) . '_form_group">';
        $html .= '<label for="' . esc_attr( $id ) . '">' . esc_html( $label ) . '</label>';
        $html .= '<select name="' . esc_attr( $id ) . '" id="' . esc_attr( $id ) . '">' . $unit_options . '</select>';
        $html .= '</p>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

    public static function generate_p_options_select_html( $label, $id, $selected_value, $options_array, $display_empty = false ): void {
        $id_escaped    = esc_attr( $id );
        $label_escaped = esc_html( $label );
        $empty_option  = $display_empty ? '<option value=""></option>' : '';
        $options_html  = '';
        foreach ( $options_array as $key => $value ) {
            $key_escaped   = esc_attr( $key );
            $value_escaped = esc_html( $value );
            $is_selected   = ( (string) $key === (string) $selected_value ) ? ' selected="selected"' : '';
            $options_html .= '<option class="level-0" value="' . $key_escaped . '"' . $is_selected . '>' . $value_escaped . '</option>';
        }
        $html  = '<p class="form-field" id="' . $id_escaped . '_form_group">';
        $html .= '<label for="' . $id_escaped . '">' . $label_escaped . '</label>';
        $html .= '<select name="' . $id_escaped . '" id="' . $id_escaped . '" style="width: 350px;">';
        $html .= $empty_option;
        $html .= $options_html;
        $html .= '</select>';
        $html .= '</p>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }


    public static function generate_p_options_number_html( $label, $id, $value = '0', $description = '' ): void {
        $allowed_tags = array(
            'br' => array(),
            'strong' => array(),
        );
        $value = ( empty( $value ) ) ? '0' : $value;
        $value_esc       = esc_attr( $value );
        $label_esc       = esc_html( $label );
        $description_esc = wp_kses( $description, $allowed_tags );
        $id_esc          = esc_attr( $id );
        $html  = '<p class="form-field" id="' . $id_esc . '_form_group">';
        $html .= '<label for="' . $id_esc . '">' . $label_esc . '</label>';
        $html .= '<input type="number" class="short" name="' . $id_esc . '" id="' . $id_esc . '" value="' . $value_esc . '" step="1" min="0" max="20">';
        $html .= '<span class="description">' . $description_esc . '</span>';
        $html .= '</p>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

	public static function generate_settings_ace_editor_html( $label, $id, $setting_value, $description, $mode ): void {
		$setting_value = htmlspecialchars( $setting_value, ENT_NOQUOTES );
		echo '<tr class="">
        <th scope="row" class="titledesc">' . esc_attr($label) . '</th>
        <td class="forminp forminp-checkbox">
            <fieldset>
                <textarea name="' . esc_attr($id) . '" rows="7" cols="100" id="' . esc_attr($id) . '" style="display:none;">' . esc_attr($setting_value) . '</textarea>
                <legend class="screen-reader-text"><span>' . esc_attr($label) . '</span></legend>
                <div id="' . esc_attr($id) . '_ace" name="' . esc_attr($id) . '" style="position: relative;width: auto;height: 300px;" class="ace-editor" data-mode="' . esc_attr($mode) . '" data-element="' . esc_attr($id) . '"></div>
                <span class="description"><br />' . esc_attr($description) . '</span>
            </fieldset>
        </td>
    </tr>';
	}

    public static function generate_settings_textarea_html( $label, $id, $setting_value, $rows = '4', $is_checked = false ): void {
        $setting_value = is_null( $setting_value ) ? '' : $setting_value;
        $label_esc         = esc_html( $label );
        $id_esc            = esc_attr( $id );
        $rows_esc          = esc_attr( $rows );
        $setting_value_esc = esc_textarea( $setting_value );
        $html  = '<p class="form-field" id="' . $id_esc . '_form_group">';
        $html .= '<label for="' . $id_esc . '">' . $label_esc . '</label>';
        $html .= '<textarea class="textarea" rows="' . $rows_esc . '" name="' . $id_esc . '" id="' . $id_esc . '">' . $setting_value_esc . '</textarea>';
        $html .= '</p>';
        echo wp_kses( $html, self::ALLOWED_HTML );
    }

	public static function generate_w2pshop_card( $title, $description, $button_array): void {
		echo '<div class="w2pshop-display-card">';
		echo '<div class="w2pshop-display-card-title">'. esc_attr($title) . '</div>';
        echo '<div class="w2pshop-display-card-description">'. esc_attr($description) . '</div>';
        echo '<div class="w2pshop-display-card-button">';
		if ('Change Page' == $button_array[1][0]) {
			echo '<button onclick="window.location.href=\''. esc_attr($button_array[1][1]) .'\'">' . esc_attr( $button_array[0] ) . '</button>';
		} elseif ('Activate' == $button_array[1][0]) {
			echo '<button class="w2pshop-activate-button" data-plugin-name="' . esc_attr($button_array[1][1]) . '">' . esc_attr( $button_array[0] ) . '</button>';
		} else {
			echo '<button>' . esc_attr( $button_array[0] ) . '</button>';
		}
		echo '</div>';
		echo '</div>';
	}

	/**
	 * @param $id_esc
	 * @param $label_esc
	 * @param $setting_value_esc
	 *
	 * @return string
	 */
	private static function make_settings_label_start( $id_esc, $label_esc, $setting_value_esc ): string {
		$html = '<tr>';
		$html .= '<th scope="row" class="titledesc">';
		$html .= '<label for="' . $id_esc . '">' . $label_esc . '</label>';
		$html .= '<input type="hidden" name="' . $id_esc . '" id="' . $id_esc . '" value="' . $setting_value_esc . '">';
		$html .= '</th>';
		$html .= '<td class="forminp forminp-text">';

		return $html;
	}
}
