<?php

namespace SGC\eGiftCard\Foundation;

defined('ABSPATH') || exit; // Prevent direct file access.

use SGC\eGiftCard\Config\TranslationHelper;

/**
 * Trait AppHelper
 *
 * Provides various helper methods for the eGift Card application.
 */
trait AppHelper
{
    private static $custom_upload_dir;
    private static $upload_dir;
    private static $upload_directory;

    /**
     * Get the application variables for the eGift Card.
     *
     * This method retrieves various settings and URLs used in the eGift Card application.
     *
     * @return array An associative array of application variables.
     */
    public static function smart_gift_card_app_vars()
    {
        $upload_dir         = wp_upload_dir();
        $uploadUrl          = esc_url( $upload_dir['baseurl'] ) . '/' . SMART_GIFT_CARD_PLUGIN_ASSET_ID;
        $title              = get_bloginfo('name') .' '. __( 'eGift Card (Instant or Scheduled Email Delivery)', 'smart-gift-card' );
        $sub_title          = get_bloginfo('name') .' '. __( 'eGift Card', 'smart-gift-card' );
        $currency_symbol    = function_exists('get_woocommerce_currency_symbol') ? get_woocommerce_currency_symbol() : '&#36;';
        $settings           = self::getOption('sgc_smart_gift_general_settings', []);
        $design_settings    = $settings['design_settings'] ?? [];
        $gift_card_bg_image = $design_settings['gift_card_background'] ?? '';
        $post_page_link     = admin_url('post.php');

        if (isset($settings['gift_amount']) && !empty($settings['gift_amount'])) {
            $gift_amount = $settings['gift_amount'];
        } else {
            $gift_amount = '10,20,30,50';
        }

        if (isset($settings['brand_logo']) && !empty($settings['brand_logo'])) {
            $brand_logo = $settings['brand_logo'];
        } else {
            $brand_logo = SMART_GIFT_CARD_PLUGIN_URL . 'assets/img/logo.png';
        }

        if (isset($settings['gift_product_id']) && !empty($settings['gift_product_id'])) {
            $gift_product_id = $settings['gift_product_id'];
        } else {
            $gift_product_id = 0;
        }

        if( empty( $gift_card_bg_image ) ) {
            $gift_card_bg_image = SMART_GIFT_CARD_PLUGIN_URL . 'assets/img/gift_card_info.png';
        }

        $allow_custom_upload = isset($settings['sgc_allow_custom_upload']) ? $settings['sgc_allow_custom_upload'] : 'yes';
        $allow_video_selection = isset($settings['sgc_allow_video_selection']) ? $settings['sgc_allow_video_selection'] : 'yes';
 
        $plugin_config = array(
            'ajax_url'          => admin_url('admin-ajax.php'),
            'slug'              => 'smart-gift-card',
            'page_title'        => $title,
            'sub_title'         => $sub_title,
            'plugin_assets'     => SMART_GIFT_CARD_PLUGIN_URL . 'assets/',
            'gift_amount'       => $gift_amount,
            'currency_symbol'   => $currency_symbol,
            'upload_url'        => $uploadUrl,
            'image_url'         => $uploadUrl,
            'brand_logo'        => $brand_logo,
            'gift_image'        => esc_url($gift_card_bg_image),
            'post_page_link'    => $post_page_link,
            'product_id'        => $gift_product_id,
            'allow_custom_upload' => $allow_custom_upload,
            'allow_video_selection' => $allow_video_selection,
            'rest_info'         => array(
                'base_url'  => esc_url_raw(rest_url()),
                'rest_url'  => rest_url('smart-gift-card' . '/v2'),
                'nonce'     => wp_create_nonce('wp_rest'),
                'namespace' => 'smart-gift-card',
                'version'   => 'v2',
            ),
            'i18ns' => TranslationHelper::sgcTranslation(),
        );

        return apply_filters( 'smart_gift_card_plugin_config', $plugin_config );
    }


    /**
     * Get the list of events for gift cards.
     *
     * This method retrieves an array of predefined events that can be used for gift cards.
     * The events are filtered through the 'e_gift_card_event_list' filter.
     *
     * @return array An associative array of event keys and their corresponding names.
     */
    public static function get_event_list()
    {
        $occasions = [
            'Birthday' => __('Birthday'),
            'Fathers_Day' => __("Father's Day"),
            'Mothers_Day' => __("Mother's Day"),
            'Valentines_Day' => __("Valentine's Day"),
            'Anniversary' => __('Anniversary'),
            'Job_Anniversary' => __('Job Anniversary'),
            'Engagement_Anniversary' => __('Engagement Anniversary'),
            'Wedding_Anniversary' => __('Wedding Anniversary'),
            'Christmas' => __('Christmas'),
            'Boxing_Day' => __('Boxing Day'),
            'New_Year' => __('New Year'),
            'Easter' => __('Easter'),
            'St_Patricks_Day' => __("St. Patrick's Day"),
            'Halloween' => __('Halloween'),
            'Thanksgiving' => __('Thanksgiving'),
            'Engagement' => __('Engagement'),
            'New_Job' => __('New Job'),
            'Job_Promotion' => __('Job Promotion'),
            'Graduation' => __('Graduation'),
            'Sweet_Sixteen' => __('Sweet Sixteen'),
            'Kindness' => __('Thank You'),
            'Friendship_Day' => __('Friendship Day'),
            'Volunteer_Appreciation' => __('Volunteer Appreciation'),
            'Lunar_New_Year' => __('Lunar New Year')
        ];

        return apply_filters('smart_gift_card_event_list', $occasions);
    }

    /**
     * getOption method will return settings using key
     * This method will get a key as parameter, fetch data from the database, and return it.
     *
     * @param string $key The option key to retrieve.
     * @param mixed $default The default value to return if the option is not found.
     * @return mixed The option value or the default value.
     */
    public static function getOption($key, $default = '')
    {
        // Get settings from options table using the key
        $data = get_option($key);

        // If the data exists, return it; otherwise, return the default value
        return $data !== false ? maybe_unserialize($data) : $default;
    }

    /**
     * Update or insert an option in the wp_options table.
     * This method serializes the data if necessary.
     * 
     * @param string $key   The option key to update.
     * @param mixed  $value The value to store.
     * @return bool True if the value was updated successfully, false otherwise.
     */
    public static function updateOption($key, $value)
    {
        // Serialize the value if it's an array or object.
        return update_option($key, maybe_serialize($value));
    }


    /**
     * Retrieve all published WordPress pages and format them as an array.
     *
     * This function queries the WordPress database to retrieve all pages 
     * with a post type of 'page' and a post status of 'publish'. 
     * It returns an array of formatted pages containing their ID and title.
     *
     * @return array $formattedPages An array of formatted pages with 'id' and 'title'.
     */
    public static function getWPPages()
    {
        global $wpdb;
        // @codingStandardsIgnoreStart
        // Query to get all published pages
        $pages = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT ID, post_title 
                FROM {$wpdb->prefix}posts 
                WHERE post_type = %s 
                AND post_status = %s 
                ORDER BY ID DESC",
                'page',
                'publish'
            )
        );
        // @codingStandardsIgnoreEnd

        // Initialize the formatted pages array
        $formattedPages = [];

        // Loop through each page and format the output
        foreach ($pages as $page) {
            $formattedPages[] = [
                'id'    => strval($page->ID),  // Convert ID to string as per requirement
                'title' => $page->post_title
            ];
        }

        return $formattedPages;
    }


    /**
     * Retrieve all published WooCommerce products and format them as an array.
     *
     * This function queries the WordPress database to retrieve all products 
     * (post type 'product') with a post status of 'publish'. 
     * It returns an array of formatted products containing their ID and title.
     *
     * @return array $formattedProducts An array of formatted WooCommerce products with 'id' and 'title'.
     */
    public static function getWooCommerceProducts()
    {
        global $wpdb;

        // Query to get all published WooCommerce products
        // @codingStandardsIgnoreStart
        $products = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT ID, post_title 
                FROM {$wpdb->prefix}posts 
                WHERE post_type = %s 
                AND post_status = %s 
                ORDER BY ID DESC",
                'product',
                'publish'
            )
        );
        // @codingStandardsIgnoreEnd

        // Initialize the formatted products array
        $formattedProducts = [];

        // Loop through each product and format the output
        foreach ($products as $product) {
            $formattedProducts[] = [
                'id'    => strval($product->ID),   // Convert ID to string as per requirement
                'title' => $product->post_title
            ];
        }

        return $formattedProducts;
    }

    /**
     * getGiftCardPageUrl will get the Gift Card Page id and return link of the page
     * @return mixed
     */
    public static function getGiftCardPageUrl()
    {
        $settings = self::getOption('sgc_smart_gift_general_settings', []);

        if (!empty($settings) && isset($settings['gift_card_page_id'])) {
            $page_id = $settings['gift_card_page_id'];
            $baseUrl = get_permalink($page_id);
            $baseUrl = rtrim($baseUrl, '/\\');
        } else {
            $baseUrl = '';
        }

        return apply_filters('e_gift_card_customizer_page_url', $baseUrl);
    }

    /**
     * getGiftRedeemPageUrl will get the Gift Reedem Page id and return link of the page
     * @return mixed
     */
    public static function getGiftRedeemPageUrl()
    {

        $settings = self::getOption('sgc_smart_gift_general_settings', []);

        if (!empty($settings) && isset($settings['redeem_gift_page_id'])) {
            $page_id = $settings['redeem_gift_page_id'];
            $baseUrl = get_permalink($page_id);
            $baseUrl = rtrim($baseUrl, '/\\');
        } else {
            $baseUrl = '';
        }

        return apply_filters('e_gift_card_customizer_page_url', $baseUrl);
    }

    // Define the callback function
    public static function smart_gift_card_upload_dir( $dirs ) {
        $dirs['path']   = self::$custom_upload_dir;
        $dirs['url']    = self::$upload_dir['baseurl'] . '/' . self::$upload_directory;
        $dirs['subdir'] = '';

        return $dirs;
    }

    /**
     * Handle file uploads.
     *
     * @param string $file_key
     * @return string|WP_Error The file name of the uploaded file, or WP_Error on failure
     */
    public static function handle_file_upload($file_key, $upload_directory = SMART_GIFT_CARD_PLUGIN_ASSET_ID)
    {
        if ( ! function_exists('wp_handle_upload') ) {
            require_once( ABSPATH . 'wp-admin/includes/file.php' );
        }

        // Check if the file was uploaded successfully
        //Nonce already validated in the calling function
        if ( ! isset( $_FILES[$file_key] ) || !isset( $_FILES[$file_key]['error'] ) || $_FILES[$file_key]['error'] != UPLOAD_ERR_OK ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
            return new WP_Error('file_upload_error', 'File upload failed.');
        }

        // Get the WordPress upload directory
        self::$upload_dir = wp_upload_dir();
        self::$custom_upload_dir = self::$upload_dir['basedir'] . '/' . $upload_directory;
        self::$upload_directory = $upload_directory;

        // Ensure the directory exists, if not, create it
        if (!file_exists(self::$custom_upload_dir)) {
            wp_mkdir_p(self::$custom_upload_dir);
        }

        // Set global variables for the callback function
        global $custom_upload_dir, $upload_directory;
        $custom_upload_dir = self::$custom_upload_dir;
        $upload_directory = $upload_directory;

        // Temporarily change the upload directory
        add_filter('upload_dir', [self::class, 'smart_gift_card_upload_dir']);


        // Handle the file upload
        //nonce already validated in the calling function
        $uploaded_file = wp_handle_upload( $_FILES[$file_key], ['test_form' => false] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

        // Remove the filter to restore default upload directory
        remove_filter('upload_dir', [self::class, 'smart_gift_card_upload_dir']);

        if ( isset( $uploaded_file['error'] ) ) {
            return new WP_Error( 'upload_error', $uploaded_file['error'] );
        }

        // File renaming with a unique prefix
        $file_path = $uploaded_file['file'];
        $file_info = pathinfo($file_path);
        $new_file_name = uniqid('egc_', true) . '.' . $file_info['extension'];
        $new_file_path = $file_info['dirname'] . '/' . $new_file_name;

        // Initialize the WordPress filesystem
        global $wp_filesystem;
        if (!function_exists('WP_Filesystem')) {
            require_once( ABSPATH . 'wp-admin/includes/file.php');
        }
        WP_Filesystem();

        if (!$wp_filesystem->move($file_path, $new_file_path)) {
            return new WP_Error('move_error', 'Failed to move the uploaded file.');
        }

        return $new_file_name;
    }

    /**
     * Get the currency symbols for gift cards.
     *
     * This method retrieves an array of currency symbols used for gift cards.
     * The symbols are filtered through the 'gift_card_currency_symbols' filter.
     *
     * @return array An associative array of currency codes and their corresponding symbols.
     */
    public static function get_sgc_gift_card_currency_symbols()
    {

        $symbols = apply_filters(
            'sgc_smart_gift_card_currency_symbols',
            array(
                'AED' => '&#x62f;.&#x625;',
                'AFN' => '&#x60b;',
                'ALL' => 'L',
                'AMD' => 'AMD',
                'ANG' => '&fnof;',
                'AOA' => 'Kz',
                'ARS' => '&#36;',
                'AUD' => '&#36;',
                'AWG' => 'Afl.',
                'AZN' => '&#8380;',
                'BAM' => 'KM',
                'BBD' => '&#36;',
                'BDT' => '&#2547;&nbsp;',
                'BGN' => '&#1083;&#1074;.',
                'BHD' => '.&#x62f;.&#x628;',
                'BIF' => 'Fr',
                'BMD' => '&#36;',
                'BND' => '&#36;',
                'BOB' => 'Bs.',
                'BRL' => '&#82;&#36;',
                'BSD' => '&#36;',
                'BTC' => '&#3647;',
                'BTN' => 'Nu.',
                'BWP' => 'P',
                'BYR' => 'Br',
                'BYN' => 'Br',
                'BZD' => '&#36;',
                'CAD' => '&#36;',
                'CDF' => 'Fr',
                'CHF' => '&#67;&#72;&#70;',
                'CLP' => '&#36;',
                'CNY' => '&yen;',
                'COP' => '&#36;',
                'CRC' => '&#x20a1;',
                'CUC' => '&#36;',
                'CUP' => '&#36;',
                'CVE' => '&#36;',
                'CZK' => '&#75;&#269;',
                'DJF' => 'Fr',
                'DKK' => 'kr.',
                'DOP' => 'RD&#36;',
                'DZD' => '&#x62f;.&#x62c;',
                'EGP' => 'EGP',
                'ERN' => 'Nfk',
                'ETB' => 'Br',
                'EUR' => '&euro;',
                'FJD' => '&#36;',
                'FKP' => '&pound;',
                'GBP' => '&pound;',
                'GEL' => '&#x20be;',
                'GGP' => '&pound;',
                'GHS' => '&#x20b5;',
                'GIP' => '&pound;',
                'GMD' => 'D',
                'GNF' => 'Fr',
                'GTQ' => 'Q',
                'GYD' => '&#36;',
                'HKD' => '&#36;',
                'HNL' => 'L',
                'HRK' => 'kn',
                'HTG' => 'G',
                'HUF' => '&#70;&#116;',
                'IDR' => 'Rp',
                'ILS' => '&#8362;',
                'IMP' => '&pound;',
                'INR' => '&#8377;',
                'IQD' => '&#x62f;.&#x639;',
                'IRR' => '&#xfdfc;',
                'IRT' => '&#x062A;&#x0648;&#x0645;&#x0627;&#x0646;',
                'ISK' => 'kr.',
                'JEP' => '&pound;',
                'JMD' => '&#36;',
                'JOD' => '&#x62f;.&#x627;',
                'JPY' => '&yen;',
                'KES' => 'KSh',
                'KGS' => '&#x441;&#x43e;&#x43c;',
                'KHR' => '&#x17db;',
                'KMF' => 'Fr',
                'KPW' => '&#x20a9;',
                'KRW' => '&#8361;',
                'KWD' => '&#x62f;.&#x643;',
                'KYD' => '&#36;',
                'KZT' => '&#8376;',
                'LAK' => '&#8365;',
                'LBP' => '&#x644;.&#x644;',
                'LKR' => '&#xdbb;&#xdd4;',
                'LRD' => '&#36;',
                'LSL' => 'L',
                'LYD' => '&#x62f;.&#x644;',
                'MAD' => '&#x62f;.&#x645;.',
                'MDL' => 'MDL',
                'MGA' => 'Ar',
                'MKD' => '&#x434;&#x435;&#x43d;',
                'MMK' => 'Ks',
                'MNT' => '&#x20ae;',
                'MOP' => 'P',
                'MRU' => 'UM',
                'MUR' => '&#x20a8;',
                'MVR' => '.&#x783;',
                'MWK' => 'MK',
                'MXN' => '&#36;',
                'MYR' => '&#82;&#77;',
                'MZN' => 'MT',
                'NAD' => 'N&#36;',
                'NGN' => '&#8358;',
                'NIO' => 'C&#36;',
                'NOK' => '&#107;&#114;',
                'NPR' => '&#8360;',
                'NZD' => '&#36;',
                'OMR' => '&#x631;.&#x639;.',
                'PAB' => 'B/.',
                'PEN' => 'S/',
                'PGK' => 'K',
                'PHP' => '&#8369;',
                'PKR' => '&#8360;',
                'PLN' => '&#122;&#322;',
                'PRB' => '&#x440;.',
                'PYG' => '&#8370;',
                'QAR' => '&#x631;.&#x642;',
                'RMB' => '&yen;',
                'RON' => 'lei',
                'RSD' => '&#1088;&#1089;&#1076;',
                'RUB' => '&#8381;',
                'RWF' => 'Fr',
                'SAR' => '&#x631;.&#x633;',
                'SBD' => '&#36;',
                'SCR' => '&#x20a8;',
                'SDG' => '&#x62c;.&#x633;.',
                'SEK' => '&#107;&#114;',
                'SGD' => '&#36;',
                'SHP' => '&pound;',
                'SLL' => 'Le',
                'SOS' => 'Sh',
                'SRD' => '&#36;',
                'SSP' => '&pound;',
                'STN' => 'Db',
                'SYP' => '&#x644;.&#x633;',
                'SZL' => 'E',
                'THB' => '&#3647;',
                'TJS' => '&#x405;&#x41c;',
                'TMT' => 'm',
                'TND' => '&#x62f;.&#x62a;',
                'TOP' => 'T&#36;',
                'TRY' => '&#8378;',
                'TTD' => '&#36;',
                'TWD' => '&#78;&#84;&#36;',
                'TZS' => 'Sh',
                'UAH' => '&#8372;',
                'UGX' => 'UGX',
                'USD' => '&#36;',
                'UYU' => '&#36;',
                'UZS' => 'UZS',
                'VEF' => 'Bs F',
                'VES' => 'Bs.',
                'VND' => '&#8363;',
                'VUV' => 'Vt',
                'WST' => 'T',
                'XAF' => 'CFA',
                'XCD' => '&#36;',
                'XOF' => 'CFA',
                'XPF' => 'Fr',
                'YER' => '&#xfdfc;',
                'ZAR' => '&#82;',
                'ZMW' => 'ZK',
            )
        );

        return $symbols;
    }
}
