<?php

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

if (! class_exists('INTEGRAZO_WZ_WooCommerce_Helper')) {

    class INTEGRAZO_WZ_WooCommerce_Helper
    {

        /**
         * Track processed events within a single request
         * to avoid duplicate external calls.
         */
        protected static $processed_customer_events = array();
        protected static $processed_order_events    = array();
        protected static $processed_product_events  = array();

        /**
         * Customer de-dup.
         *
         * @param int    $user_id
         * @param string $event
         * @return bool  true if already processed.
         */
        public static function is_duplicate_customer_event($user_id, $event)
        {
            $key = $event . '_' . (int) $user_id;

            if (isset(self::$processed_customer_events[$key])) {
                return true;
            }

            self::$processed_customer_events[$key] = true;
            return false;
        }

        /**
         * Order de-dup.
         *
         * @param int    $order_id
         * @param string $event
         * @return bool  true if already processed.
         */
        public static function is_duplicate_order_event($order_id, $event)
        {
            $key = $event . '_' . (int) $order_id;

            if (isset(self::$processed_order_events[$key])) {
                return true;
            }

            self::$processed_order_events[$key] = true;
            return false;
        }

        /**
         * Product de-dup.
         *
         * @param int    $product_id
         * @param string $event
         * @return bool  true if already processed.
         */
        public static function is_duplicate_product_event($product_id, $event)
        {
            $key = $event . '_' . (int) $product_id;

            if (isset(self::$processed_product_events[$key])) {
                return true;
            }

            self::$processed_product_events[$key] = true;
            return false;
        }

        /**
         * Get a list of WooCommerce triggerable events.
         *
         * @return array|string
         */
        public static function get_events()
        {
            if (! class_exists('WooCommerce')) {
                return 'WooCommerce is not active. Please install and activate the WooCommerce plugin to continue.';
            }

            return array(
                // Customer events
                array('id' => 'user_register',   'title' => 'Customer Created'),
                array('id' => 'profile_update',  'title' => 'Customer Updated'),
                // array('id' => 'delete_user',     'title' => 'Customer Removed'),

                // Order events
                array('id' => 'woocommerce_new_order',               'title' => 'Order Created'),
                array('id' => 'woocommerce_process_shop_order_meta', 'title' => 'Order Edited'),
                // array('id' => 'woocommerce_trash_order',             'title' => 'Order Trashed'),
                array('id' => 'woocommerce_order_edit_status',       'title' => 'Order Status Changed'),

                // Product events
                array('id' => 'woocommerce_new_product',    'title' => 'Product Created'),
                array('id' => 'woocommerce_update_product', 'title' => 'Product Updated'),
            );
        }

        /**
         * Get all fields for WooCommerce based on event.
         *
         * @param string $event_id
         * @return array
         */
        public static function get_form_fields($event_id)
        {

            // User core fields
            $user_fields = array(
                array('name' => 'user_login',      'type' => 'text',     'label' => 'Username',         'identifier' => 'user_login'),
                array('name' => 'user_email',      'type' => 'email',    'label' => 'Email',            'identifier' => 'user_email'),
                array('name' => 'display_name',    'type' => 'text',     'label' => 'Display Name',     'identifier' => 'display_name'),
                array('name' => 'user_registered', 'type' => 'text',     'label' => 'Registered Date',  'identifier' => 'user_registered'),
                array('name' => 'user_url',        'type' => 'url',      'label' => 'Website URL',      'identifier' => 'user_url'),
                array('name' => 'first_name',      'type' => 'text',     'label' => 'First Name (Meta)', 'identifier' => 'first_name'),
                array('name' => 'last_name',       'type' => 'text',     'label' => 'Last Name (Meta)', 'identifier' => 'last_name'),
                array('name' => 'nickname',        'type' => 'text',     'label' => 'Nickname',         'identifier' => 'nickname'),
                array('name' => 'description',     'type' => 'textarea', 'label' => 'User Description', 'identifier' => 'description'),
            );

            // Billing fields
            $billing_fields = array(
                array('name' => 'billing_first_name', 'type' => 'text',  'label' => 'Billing First Name', 'identifier' => 'billing_first_name'),
                array('name' => 'billing_last_name',  'type' => 'text',  'label' => 'Billing Last Name',  'identifier' => 'billing_last_name'),
                array('name' => 'billing_company',    'type' => 'text',  'label' => 'Billing Company',    'identifier' => 'billing_company'),
                array('name' => 'billing_address_1',  'type' => 'text',  'label' => 'Billing Address 1',  'identifier' => 'billing_address_1'),
                array('name' => 'billing_address_2',  'type' => 'text',  'label' => 'Billing Address 2',  'identifier' => 'billing_address_2'),
                array('name' => 'billing_city',       'type' => 'text',  'label' => 'Billing City',       'identifier' => 'billing_city'),
                array('name' => 'billing_postcode',   'type' => 'text',  'label' => 'Billing Postcode',   'identifier' => 'billing_postcode'),
                array('name' => 'billing_country',    'type' => 'text',  'label' => 'Billing Country',    'identifier' => 'billing_country'),
                array('name' => 'billing_state',      'type' => 'text',  'label' => 'Billing State',      'identifier' => 'billing_state'),
                array('name' => 'billing_phone',      'type' => 'text',  'label' => 'Billing Phone',      'identifier' => 'billing_phone'),
                array('name' => 'billing_email',      'type' => 'email', 'label' => 'Billing Email',      'identifier' => 'billing_email'),
            );

            // Shipping fields
            $shipping_fields = array(
                array('name' => 'shipping_first_name', 'type' => 'text', 'label' => 'Shipping First Name', 'identifier' => 'shipping_first_name'),
                array('name' => 'shipping_last_name',  'type' => 'text', 'label' => 'Shipping Last Name',  'identifier' => 'shipping_last_name'),
                array('name' => 'shipping_company',    'type' => 'text', 'label' => 'Shipping Company',    'identifier' => 'shipping_company'),
                array('name' => 'shipping_address_1',  'type' => 'text', 'label' => 'Shipping Address 1',  'identifier' => 'shipping_address_1'),
                array('name' => 'shipping_address_2',  'type' => 'text', 'label' => 'Shipping Address 2',  'identifier' => 'shipping_address_2'),
                array('name' => 'shipping_city',       'type' => 'text', 'label' => 'Shipping City',       'identifier' => 'shipping_city'),
                array('name' => 'shipping_postcode',   'type' => 'text', 'label' => 'Shipping Postcode',   'identifier' => 'shipping_postcode'),
                array('name' => 'shipping_country',    'type' => 'text', 'label' => 'Shipping Country',    'identifier' => 'shipping_country'),
                array('name' => 'shipping_state',      'type' => 'text', 'label' => 'Shipping State',      'identifier' => 'shipping_state'),
            );

            // Order + line item fields (SKU first)
            $order_fields = array(
                // Line item
                array('name' => 'product_sku',          'type' => 'text', 'label' => 'Line Item Product SKU',   'identifier' => 'product_sku'),
                array('name' => 'product_id',           'type' => 'text', 'label' => 'Line Item Product ID',    'identifier' => 'product_id'),
                array('name' => 'product_name',         'type' => 'text', 'label' => 'Line Item Product Name',  'identifier' => 'product_name'),
                array('name' => 'product_quantity',     'type' => 'text', 'label' => 'Line Item Quantity',      'identifier' => 'product_quantity'),
                array('name' => 'product_subtotal',     'type' => 'text', 'label' => 'Line Item Subtotal',      'identifier' => 'product_subtotal'),
                array('name' => 'product_subtotal_tax', 'type' => 'text', 'label' => 'Line Item Subtotal Tax',  'identifier' => 'product_subtotal_tax'),
                array('name' => 'product_total',        'type' => 'text', 'label' => 'Line Item Total',         'identifier' => 'product_total'),
                array('name' => 'product_total_tax',    'type' => 'text', 'label' => 'Line Item Total Tax',     'identifier' => 'product_total_tax'),

                // Order-level
                array('name' => 'order_id',             'type' => 'text', 'label' => 'Order ID',                'identifier' => 'order_id'),
                array('name' => 'order_number',         'type' => 'text', 'label' => 'Order Number',            'identifier' => 'order_number'),
                array('name' => 'order_key',            'type' => 'text', 'label' => 'Order Key',               'identifier' => 'order_key'),
                array('name' => 'order_status',         'type' => 'text', 'label' => 'Order Status',            'identifier' => 'order_status'),
                array('name' => 'customer_id',          'type' => 'text', 'label' => 'Customer ID',             'identifier' => 'customer_id'),
                array('name' => 'order_currency',       'type' => 'text', 'label' => 'Currency',                'identifier' => 'order_currency'),
                array('name' => 'order_total',          'type' => 'text', 'label' => 'Order Total',             'identifier' => 'order_total'),
                array('name' => 'payment_method',       'type' => 'text', 'label' => 'Payment Method (ID)',     'identifier' => 'payment_method'),
                array('name' => 'payment_method_title', 'type' => 'text', 'label' => 'Payment Method Title',    'identifier' => 'payment_method_title'),
                array('name' => 'date_created',         'type' => 'text', 'label' => 'Date Created',            'identifier' => 'date_created'),
            );

            // Product fields (SKU first)
            $product_fields = array(
                array('name' => 'sku',              'type' => 'text', 'label' => 'SKU',                 'identifier' => 'sku'),
                array('name' => 'product_id',       'type' => 'text', 'label' => 'Product ID',          'identifier' => 'product_id'),
                array('name' => 'product_name',     'type' => 'text', 'label' => 'Product Name',        'identifier' => 'product_name'),
                array('name' => 'product_slug',     'type' => 'text', 'label' => 'Product Slug',        'identifier' => 'product_slug'),
                array('name' => 'product_status',   'type' => 'text', 'label' => 'Product Status',      'identifier' => 'product_status'),
                array('name' => 'product_type',     'type' => 'text', 'label' => 'Product Type',        'identifier' => 'product_type'),
                array('name' => 'regular_price',    'type' => 'text', 'label' => 'Regular Price',       'identifier' => 'regular_price'),
                array('name' => 'sale_price',       'type' => 'text', 'label' => 'Sale Price',          'identifier' => 'sale_price'),
                array('name' => 'price',            'type' => 'text', 'label' => 'Current Price',       'identifier' => 'price'),
                array('name' => 'stock_status',     'type' => 'text', 'label' => 'Stock Status',        'identifier' => 'stock_status'),
                array('name' => 'stock_quantity',   'type' => 'text', 'label' => 'Stock Quantity',      'identifier' => 'stock_quantity'),
                array('name' => 'manage_stock',     'type' => 'text', 'label' => 'Manage Stock',        'identifier' => 'manage_stock'),
                array('name' => 'weight',           'type' => 'text', 'label' => 'Weight',              'identifier' => 'weight'),
                array('name' => 'length',           'type' => 'text', 'label' => 'Length',              'identifier' => 'length'),
                array('name' => 'width',            'type' => 'text', 'label' => 'Width',               'identifier' => 'width'),
                array('name' => 'height',           'type' => 'text', 'label' => 'Height',              'identifier' => 'height'),
                array('name' => 'categories',       'type' => 'text', 'label' => 'Categories',          'identifier' => 'categories'),
                array('name' => 'tags',             'type' => 'text', 'label' => 'Tags',                'identifier' => 'tags'),
                array('name' => 'date_created',     'type' => 'text', 'label' => 'Date Created',        'identifier' => 'date_created'),
                array('name' => 'date_modified',    'type' => 'text', 'label' => 'Date Modified',       'identifier' => 'date_modified'),
            );

            switch ($event_id) {
                case 'user_register':
                case 'profile_update':
                case 'delete_user':
                    return array_merge($user_fields, $billing_fields, $shipping_fields);

                case 'woocommerce_new_order':
                case 'woocommerce_process_shop_order_meta':
                case 'woocommerce_trash_order':
                case 'woocommerce_order_edit_status':
                    return array_merge($order_fields, $billing_fields, $shipping_fields);

                case 'woocommerce_new_product':
                case 'woocommerce_update_product':
                case 'woocommerce_trash_product':
                case 'woocommerce_delete_product':
                    return $product_fields;

                default:
                    return array();
            }
        }

        /**
         * Handle customer events.
         */
        public static function customer_handling($user_id_or_login, $event = '')
        {
            try {
                $user = is_numeric($user_id_or_login)
                    ? get_userdata($user_id_or_login)
                    : get_user_by('login', $user_id_or_login);

                if (! $user) {
                    return;
                }

                $user_id = $user->ID;

                $roles = (array) $user->roles;
                $role  = ! empty($roles) ? $roles[0] : '';

                if ('customer' !== $role) {
                    return;
                }

                $form_data = array(
                    'event'           => $event,
                    'user_login'      => $user->user_login,
                    'user_email'      => $user->user_email,
                    'user_url'        => $user->user_url,
                    'first_name'      => get_user_meta($user_id, 'first_name', true),
                    'last_name'       => get_user_meta($user_id, 'last_name', true),
                    'nickname'        => get_user_meta($user_id, 'nickname', true),
                    'description'     => get_user_meta($user_id, 'description', true),
                    'display_name'    => $user->display_name,
                    'user_registered' => $user->user_registered,

                    // Billing
                    'billing_first_name' => get_user_meta($user_id, 'billing_first_name', true),
                    'billing_last_name'  => get_user_meta($user_id, 'billing_last_name', true),
                    'billing_company'    => get_user_meta($user_id, 'billing_company', true),
                    'billing_address_1'  => get_user_meta($user_id, 'billing_address_1', true),
                    'billing_address_2'  => get_user_meta($user_id, 'billing_address_2', true),
                    'billing_city'       => get_user_meta($user_id, 'billing_city', true),
                    'billing_postcode'   => get_user_meta($user_id, 'billing_postcode', true),
                    'billing_country'    => get_user_meta($user_id, 'billing_country', true),
                    'billing_state'      => get_user_meta($user_id, 'billing_state', true),
                    'billing_phone'      => get_user_meta($user_id, 'billing_phone', true),
                    'billing_email'      => get_user_meta($user_id, 'billing_email', true),

                    // Shipping
                    'shipping_first_name' => get_user_meta($user_id, 'shipping_first_name', true),
                    'shipping_last_name'  => get_user_meta($user_id, 'shipping_last_name', true),
                    'shipping_company'    => get_user_meta($user_id, 'shipping_company', true),
                    'shipping_address_1'  => get_user_meta($user_id, 'shipping_address_1', true),
                    'shipping_address_2'  => get_user_meta($user_id, 'shipping_address_2', true),
                    'shipping_city'       => get_user_meta($user_id, 'shipping_city', true),
                    'shipping_postcode'   => get_user_meta($user_id, 'shipping_postcode', true),
                    'shipping_country'    => get_user_meta($user_id, 'shipping_country', true),
                    'shipping_state'      => get_user_meta($user_id, 'shipping_state', true),
                );

                INTEGRAZO_WZ_Form_Hooks::process_submission($event, $form_data, 'woocommerce');
            } catch (Throwable $e) {
                // Optional: log.
            }
        }

        /**
         * Handle order events:
         * one submission per line item (with SKU).
         */
        public static function order_handling($order_id, $event)
        {
            try {
                $order = wc_get_order($order_id);
                if (! $order) {
                    return;
                }

                $common = array(
                    'event'                => $event,
                    'order_id'             => $order->get_id(),
                    'order_number'         => $order->get_order_number(),
                    'order_key'            => $order->get_order_key(),
                    'order_status'         => $order->get_status(),
                    'customer_id'          => $order->get_customer_id(),
                    'order_currency'       => $order->get_currency(),
                    'order_total'          => $order->get_total(),
                    'payment_method'       => $order->get_payment_method(),
                    'payment_method_title' => $order->get_payment_method_title(),
                    'date_created'         => $order->get_date_created()
                        ? $order->get_date_created()->date('Y-m-d H:i:s')
                        : '',

                    // Billing
                    'billing_email'        => $order->get_billing_email(),
                    'billing_first_name'   => $order->get_billing_first_name(),
                    'billing_last_name'    => $order->get_billing_last_name(),
                    'billing_company'      => $order->get_billing_company(),
                    'billing_phone'        => $order->get_billing_phone(),
                    'billing_address_1'    => $order->get_billing_address_1(),
                    'billing_address_2'    => $order->get_billing_address_2(),
                    'billing_city'         => $order->get_billing_city(),
                    'billing_postcode'     => $order->get_billing_postcode(),
                    'billing_country'      => $order->get_billing_country(),
                    'billing_state'        => $order->get_billing_state(),

                    // Shipping
                    'shipping_first_name'  => $order->get_shipping_first_name(),
                    'shipping_last_name'   => $order->get_shipping_last_name(),
                    'shipping_company'     => $order->get_shipping_company(),
                    'shipping_address_1'   => $order->get_shipping_address_1(),
                    'shipping_address_2'   => $order->get_shipping_address_2(),
                    'shipping_city'        => $order->get_shipping_city(),
                    'shipping_postcode'    => $order->get_shipping_postcode(),
                    'shipping_country'     => $order->get_shipping_country(),
                    'shipping_state'       => $order->get_shipping_state(),
                );

                foreach ($order->get_items() as $item) {
                    $product    = $item->get_product();
                    $product_id = $product ? $product->get_id() : $item->get_product_id();

                    if (! $product_id) {
                        continue;
                    }

                    $form_data = $common;

                    $form_data['product_id']           = $product_id;
                    $form_data['product_name']         = $item->get_name();
                    $form_data['product_sku']          = $product ? $product->get_sku() : '';
                    $form_data['product_quantity']     = $item->get_quantity();
                    $form_data['product_subtotal']     = $item->get_subtotal();
                    $form_data['product_subtotal_tax'] = $item->get_subtotal_tax();
                    $form_data['product_total']        = $item->get_total();
                    $form_data['product_total_tax']    = $item->get_total_tax();

                    INTEGRAZO_WZ_Form_Hooks::process_submission($event, $form_data, 'woocommerce');
                }
            } catch (Throwable $e) {
                // Optional: log.
            }
        }

        /**
         * Handle product events (create / update / trash / delete).
         */
        public static function product_handling($product_id, $event)
        {
            try {
                $product = wc_get_product($product_id);
                if (! $product) {
                    return;
                }

                // Categories
                $cat_names = array();
                $cats      = get_the_terms($product_id, 'product_cat');
                if (! empty($cats) && ! is_wp_error($cats)) {
                    foreach ($cats as $cat) {
                        $cat_names[] = $cat->name;
                    }
                }

                // Tags
                $tag_names = array();
                $tags      = get_the_terms($product_id, 'product_tag');
                if (! empty($tags) && ! is_wp_error($tags)) {
                    foreach ($tags as $tag) {
                        $tag_names[] = $tag->name;
                    }
                }

                $form_data = array(
                    'event'            => $event,
                    'sku'              => $product->get_sku(),
                    'product_id'       => $product->get_id(),
                    'product_name'     => $product->get_name(),
                    'product_slug'     => $product->get_slug(),
                    'product_status'   => $product->get_status(),
                    'product_type'     => $product->get_type(),
                    'regular_price'    => $product->get_regular_price(),
                    'sale_price'       => $product->get_sale_price(),
                    'price'            => $product->get_price(),
                    'stock_status'     => $product->get_stock_status(),
                    'stock_quantity'   => $product->get_stock_quantity(),
                    'manage_stock'     => $product->get_manage_stock() ? 'yes' : 'no',
                    'weight'           => $product->get_weight(),
                    'length'           => $product->get_length(),
                    'width'            => $product->get_width(),
                    'height'           => $product->get_height(),
                    'categories'       => ! empty($cat_names) ? implode(', ', $cat_names) : '',
                    'tags'             => ! empty($tag_names) ? implode(', ', $tag_names) : '',
                    'date_created'     => $product->get_date_created()
                        ? $product->get_date_created()->date('Y-m-d H:i:s')
                        : '',
                    'date_modified'    => $product->get_date_modified()
                        ? $product->get_date_modified()->date('Y-m-d H:i:s')
                        : '',
                );

                INTEGRAZO_WZ_Form_Hooks::process_submission($event, $form_data, 'woocommerce');
            } catch (Throwable $e) {
                // Optional: log.
            }
        }
    }
}

/**
 * Register hooks.
 */
if (class_exists('INTEGRAZO_WZ_WooCommerce_Helper')) {

    // Customer events
    add_action('user_register', function ($user_id) {
        if (INTEGRAZO_WZ_WooCommerce_Helper::is_duplicate_customer_event($user_id, 'user_register')) {
            return;
        }
        INTEGRAZO_WZ_WooCommerce_Helper::customer_handling($user_id, 'user_register');
    }, 5, 1);

    add_action('profile_update', function ($user_id) {
        if (INTEGRAZO_WZ_WooCommerce_Helper::is_duplicate_customer_event($user_id, 'profile_update')) {
            return;
        }
        INTEGRAZO_WZ_WooCommerce_Helper::customer_handling($user_id, 'profile_update');
    }, 10, 1);

    // Order events
    add_action('woocommerce_new_order', function ($order_id) {
        if (INTEGRAZO_WZ_WooCommerce_Helper::is_duplicate_order_event($order_id, 'woocommerce_new_order')) {
            return;
        }
        INTEGRAZO_WZ_WooCommerce_Helper::order_handling($order_id, 'woocommerce_new_order');
    }, 20, 1);

    add_action('woocommerce_process_shop_order_meta', function ($order_id) {
        if (INTEGRAZO_WZ_WooCommerce_Helper::is_duplicate_order_event($order_id, 'woocommerce_process_shop_order_meta')) {
            return;
        }
        INTEGRAZO_WZ_WooCommerce_Helper::order_handling($order_id, 'woocommerce_process_shop_order_meta');
    }, 25, 1);

    add_action('woocommerce_order_edit_status', function ($order_id, $new_status) {
        if (INTEGRAZO_WZ_WooCommerce_Helper::is_duplicate_order_event($order_id, 'woocommerce_order_edit_status')) {
            return;
        }
        INTEGRAZO_WZ_WooCommerce_Helper::order_handling($order_id, 'woocommerce_order_edit_status');
    }, 30, 2);


    /**
     * Product create/update:
     * Use a single hook and decide event based on created vs modified timestamp.
     */
    add_action('woocommerce_after_product_object_save', function ($product, $data_store) {
        if (! $product instanceof WC_Product) {
            return;
        }

        $product_id = $product->get_id();

        // Detect create vs update
        $created  = $product->get_date_created();
        $modified = $product->get_date_modified();

        $event = 'woocommerce_update_product';
        if ($created && $modified && $created->getTimestamp() === $modified->getTimestamp()) {
            $event = 'woocommerce_new_product';
        }

        if (INTEGRAZO_WZ_WooCommerce_Helper::is_duplicate_product_event($product_id, $event)) {
            return;
        }

        INTEGRAZO_WZ_WooCommerce_Helper::product_handling($product_id, $event);
    }, 15, 2);
}
