<?php

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

// Import OrderUtil for HPOS compatibility
use Automattic\WooCommerce\Utilities\OrderUtil;

/**
 * OpenPOS Helper Class
 *
 * @package OpenPOS
 * @since 1.0.0
 */
class WCMLIM_OpenPOS_Helper {
    /**
     * Whether OpenPOS integration is enabled
     *
     * @var bool
     */
    private $integration_enabled;

    /**
     * Constructor.
     */
    public function __construct() {
        // Check if OpenPOS integration is enabled
        $this->integration_enabled = get_option('wcmlim_pos_compatiblity') === 'on';
        
        // Always create the table even if disabled, so it's there when enabled
        add_action('init', array($this, 'maybe_create_mapping_table'));
        
        // Only add other hooks if integration is enabled
        if ($this->integration_enabled) {
            // Add menu
            add_action('admin_menu', array($this, 'register_openpos_settings_page'), 99);
            
            // Save mapping
            add_action('admin_post_save_openpos_mapping', array($this, 'save_openpos_mapping'));
            
           
        }
    }

    /**
     * Register the OpenPOS settings page under the main WCMLIM menu.
     */
    public function register_openpos_settings_page() {
        // Don't register if integration disabled
        if (!$this->integration_enabled) {
            return;
        }

        add_submenu_page(
            'multi-location-inventory-management', // Parent slug
            __('OpenPOS Integration', 'wcmlim'),
            __('OpenPOS Integration', 'wcmlim'),
            'manage_options',
            'wcmlim-openpos-settings',
            array($this, 'render_openpos_settings_page')
        );
    }

    /**
     * Create the mapping table if it doesn't exist
     */
    public function maybe_create_mapping_table() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'wcmlim_openpos_mapping';
        
        $charset_collate = $wpdb->get_charset_collate();
        
        if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
            $sql = "CREATE TABLE $table_name (
                id mediumint(9) NOT NULL AUTO_INCREMENT,
                location_id bigint(20) NOT NULL,
                warehouse_id bigint(20) NOT NULL,
                PRIMARY KEY  (id),
                UNIQUE KEY location_warehouse (location_id, warehouse_id)
            ) $charset_collate;";
            
            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
            dbDelta($sql);
        }
    }

    /**
     * Render the OpenPOS settings page.
     */
    public function render_openpos_settings_page() {
        // Don't render if integration disabled
        if (!$this->integration_enabled) {
            wp_die(__('OpenPOS integration is currently disabled. Enable it in the plugin settings.', 'wcmlim'));
        }

        // Check user capabilities
        if (!current_user_can('manage_options')) {
            return;
        }
        
        // Get all locations
        $locations = get_terms(array(
            'taxonomy' => 'locations',
            'hide_empty' => false,
            'parent' => 0,
        ));
        
        // Get all OpenPOS warehouses
        $args = array(
            'post_type' => '_op_warehouse',
            'posts_per_page' => -1,
            'post_status' => 'publish'
        );
        $warehouses = get_posts($args);
        
        // Get existing mappings
        $mappings = $this->get_mappings();
        
        ?>
        <div class="wrap">
            <h1><?php echo esc_html__('OpenPOS Integration Settings', 'wcmlim'); ?></h1>
            
            <div class="wcmlim-openpos-settings-container">
                <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                    <input type="hidden" name="action" value="save_openpos_mapping">
                    <?php wp_nonce_field('wcmlim_openpos_mapping_nonce', 'wcmlim_openpos_mapping_nonce'); ?>
                    
                    <h2><?php echo esc_html__('Map Locations to OpenPOS Outlets', 'wcmlim'); ?></h2>
                    <p class="description"><?php echo esc_html__('Connect your locations with OpenPOS warehouses/outlets to synchronize inventory.', 'wcmlim'); ?></p>
                    
                    <table class="wp-list-table widefat fixed striped">
                        <thead>
                            <tr>
                                <th><?php echo esc_html__('Location', 'wcmlim'); ?></th>
                                <th><?php echo esc_html__('OpenPOS Outlet/Warehouse', 'wcmlim'); ?></th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($locations as $location) : ?>
                                <tr>
                                    <td><?php echo esc_html($location->name); ?></td>
                                    <td>
                                        <select name="location_mapping[<?php echo esc_attr($location->term_id); ?>]" class="regular-text">
                                            <option value=""><?php echo esc_html__('-- Select OpenPOS Outlet --', 'wcmlim'); ?></option>
                                            <?php foreach ($warehouses as $warehouse) : ?>
                                                <option value="<?php echo esc_attr($warehouse->ID); ?>" <?php selected(isset($mappings[$location->term_id]) && $mappings[$location->term_id] == $warehouse->ID); ?>>
                                                    <?php echo esc_html($warehouse->post_title); ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                    
                    <?php submit_button(__('Save Mappings', 'wcmlim'), 'primary', 'submit', true); ?>
                </form>
            </div>
        </div>
        <style>
            .wcmlim-openpos-settings-container {
                margin-top: 20px;
            }
            .wcmlim-openpos-settings-container table {
                margin-top: 15px;
                margin-bottom: 15px;
            }
        </style>
        <?php
    }

    /**
     * Save the OpenPOS mappings.
     */
    public function save_openpos_mapping() {
        // Don't process if integration disabled
        if (!$this->integration_enabled) {
            wp_redirect(admin_url('admin.php?page=multi-location-inventory-management'));
            exit;
        }
        
        // Check if user has proper permissions
        if (!current_user_can('manage_options')) {
            wp_die(__('You do not have sufficient permissions to access this page.', 'wcmlim'));
        }
        
        // Verify nonce
        if (!isset($_POST['wcmlim_openpos_mapping_nonce']) || !wp_verify_nonce($_POST['wcmlim_openpos_mapping_nonce'], 'wcmlim_openpos_mapping_nonce')) {
            wp_die(__('Nonce verification failed.', 'wcmlim'));
        }
        
        global $wpdb;
        $table_name = $wpdb->prefix . 'wcmlim_openpos_mapping';
        
        // Clear existing mappings
        $wpdb->query("TRUNCATE TABLE $table_name");
        
        // Save new mappings
        $location_mapping = isset($_POST['location_mapping']) ? $_POST['location_mapping'] : array();
        
        foreach ($location_mapping as $location_id => $warehouse_id) {
            if (!empty($warehouse_id)) {
                $wpdb->insert(
                    $table_name,
                    array(
                        'location_id' => intval($location_id),
                        'warehouse_id' => intval($warehouse_id),
                    ),
                    array('%d', '%d')
                );
            }
        }
        
        // Redirect back to the settings page with a success message
        $redirect_url = add_query_arg(
            array('page' => 'wcmlim-openpos-settings', 'message' => 'success'),
            admin_url('admin.php')
        );
        
        wp_redirect($redirect_url);
        exit;
    }

    /**
     * Get all mappings between locations and warehouses.
     *
     * @return array Associative array of location_id => warehouse_id
     */
    public function get_mappings() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'wcmlim_openpos_mapping';
        
        $results = $wpdb->get_results("SELECT location_id, warehouse_id FROM $table_name", ARRAY_A);
        
        $mappings = array();
        if (!empty($results)) {
            foreach ($results as $result) {
                $mappings[$result['location_id']] = $result['warehouse_id'];
            }
        }
        
        return $mappings;
    }
    
    /**
     * Get location ID from warehouse ID.
     *
     * @param int $warehouse_id OpenPOS warehouse ID
     * @return int|null Location ID or null if not found
     */
    public function get_location_id_from_warehouse($warehouse_id) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'wcmlim_openpos_mapping';
        
        $location_id = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT location_id FROM $table_name WHERE warehouse_id = %d",
                $warehouse_id
            )
        );
        
        return $location_id ? intval($location_id) : null;
    }
    
    /**
     * Check if HPOS is enabled
     * 
     * @return bool True if HPOS is enabled, false otherwise
     */
    private function is_hpos_enabled() {
        if (class_exists('Automattic\WooCommerce\Utilities\OrderUtil') && 
            method_exists('Automattic\WooCommerce\Utilities\OrderUtil', 'custom_orders_table_usage_is_enabled') &&
            function_exists('wc_get_container')) {
            try {
                return OrderUtil::custom_orders_table_usage_is_enabled();
            } catch (Exception $e) {
                // Fallback if there's an error
                return get_option('woocommerce_custom_orders_table_enabled') === 'yes';
            }
        }
        return get_option('woocommerce_custom_orders_table_enabled') === 'yes';
    }
    
    /**
     * Get order meta considering HPOS compatibility
     * 
     * @param WC_Order|int $order Order object or ID
     * @param string $key Meta key
     * @param bool $single Whether to return a single value
     * @return mixed Meta value
     */
    private function get_order_meta($order, $key, $single = true) {
        if (is_numeric($order)) {
            $order = wc_get_order($order);
        }
        
        if (!$order) {
            return null;
        }
        
        if ($this->is_hpos_enabled()) {
            return $order->get_meta($key, $single);
        } else {
            return get_post_meta($order->get_id(), $key, $single);
        }
    }
    
    /**
     * Update order meta considering HPOS compatibility
     * 
     * @param WC_Order|int $order Order object or ID
     * @param string $key Meta key
     * @param mixed $value Meta value
     * @return void
     */
    private function update_order_meta($order, $key, $value) {
        if (is_numeric($order)) {
            $order = wc_get_order($order);
        }
        
        if (!$order) {
            return;
        }
        
        if ($this->is_hpos_enabled()) {
            $order->update_meta_data($key, $value);
            $order->save();
        } else {
            update_post_meta($order->get_id(), $key, $value);
        }
    }
    
    /**
     * Handle stock adjustment for OpenPOS orders when order status changes
     *
     * @param int $order_id Order ID
     * @param string $old_status Previous status
     * @param string $new_status New status
     */
    public function handle_openpos_order_status_change($order_id, $old_status, $new_status) {
        // Don't process if integration disabled
        if (!$this->integration_enabled) {
            return;
        }
        
        $order = wc_get_order($order_id);
        
        // Check if this is an OpenPOS order
        $pos_order_id = $this->get_order_meta($order, '_pos_order_id');
        if (!$pos_order_id) {
            return; // Not an OpenPOS order
        }
        
        // Handle refunded or cancelled orders
        if ($new_status === 'cancelled' || $new_status === 'refunded') {
            $this->restore_openpos_stock($order);
        }
        
        // Handle completed orders (if needed to reduce stock)
        if ($new_status === 'completed' && $old_status !== 'completed') {
            $this->reduce_openpos_stock($order);
        }
    }
    
    /**
     * Handle stock reduction for new OpenPOS orders
     *
     * @param int $order_id Order ID
     */
    public function handle_openpos_new_order($order_id) {
        // Don't process if integration disabled
        if (!$this->integration_enabled) {
            return;
        }
        
        $order = wc_get_order($order_id);
        
        // Check if this is an OpenPOS order
        $pos_order_id = $this->get_order_meta($order, '_pos_order_id');
        if (!$pos_order_id) {
            return; // Not an OpenPOS order
        }
        
        $this->reduce_openpos_stock($order);
    }
    
    /**
     * Reduce stock for OpenPOS order
     *
     * @param WC_Order $order Order object
     */
    private function reduce_openpos_stock($order) {
        // Don't process if integration disabled
        if (!$this->integration_enabled) {
            return;
        }
        
        // Get the warehouse ID from order meta
        $warehouse_id = $this->get_order_meta($order, '_pos_order_warehouse');
        if (!$warehouse_id) {
            return;
        }
        
        // Get the mapped location ID
        $location_id = $this->get_location_id_from_warehouse($warehouse_id);
        if (!$location_id) {
            return;
        }
        
        // Loop through order items and reduce stock
        foreach ($order->get_items() as $item) {
            $product_id = $item->get_product_id();
            $variation_id = $item->get_variation_id();
            $qty = $item->get_quantity();
            
            // Determine which ID to use for stock management
            $stock_product_id = $variation_id > 0 ? $variation_id : $product_id;
            
            // Get current stock level for this location
            $stock_key = "wcmlim_stock_at_{$location_id}";
            $current_stock = get_post_meta($stock_product_id, $stock_key, true);
            
            if ($current_stock !== '') {
                $new_stock = max(0, intval($current_stock) - $qty);
                update_post_meta($stock_product_id, $stock_key, $new_stock);
                
                // Add note to the order
                $product = wc_get_product($stock_product_id);
                $product_name = $product ? $product->get_formatted_name() : "#$stock_product_id";
                $location = get_term($location_id, 'locations');
                $location_name = $location ? $location->name : "Location #$location_id";
                
                $order->add_order_note(
                    sprintf(
                        __('OpenPOS: Reduced %s stock by %d at %s. New stock: %d', 'wcmlim'),
                        $product_name,
                        $qty,
                        $location_name,
                        $new_stock
                    )
                );
                
                // Store that we've reduced stock for this item
                $item->add_meta_data('_wcmlim_openpos_stock_reduced', $qty, true);
                $item->add_meta_data('_wcmlim_openpos_location_id', $location_id, true);
                $item->save();
            }
        }
    }
    
    /**
     * Restore stock for OpenPOS order (in case of refund or cancellation)
     *
     * @param WC_Order $order Order object
     */
    private function restore_openpos_stock($order) {
        // Don't process if integration disabled
        if (!$this->integration_enabled) {
            return;
        }
        
        // Loop through order items and restore stock
        foreach ($order->get_items() as $item) {
            $product_id = $item->get_product_id();
            $variation_id = $item->get_variation_id();
            
            // Determine which ID to use for stock management
            $stock_product_id = $variation_id > 0 ? $variation_id : $product_id;
            
            // Check if we previously reduced stock for this item
            $reduced_qty = $item->get_meta('_wcmlim_openpos_stock_reduced', true);
            $location_id = $item->get_meta('_wcmlim_openpos_location_id', true);
            
            if ($reduced_qty && $location_id) {
                // Get current stock level for this location
                $stock_key = "wcmlim_stock_at_{$location_id}";
                $current_stock = get_post_meta($stock_product_id, $stock_key, true);
                
                if ($current_stock !== '') {
                    $new_stock = intval($current_stock) + intval($reduced_qty);
                    update_post_meta($stock_product_id, $stock_key, $new_stock);
                    
                    // Add note to the order
                    $product = wc_get_product($stock_product_id);
                    $product_name = $product ? $product->get_formatted_name() : "#$stock_product_id";
                    $location = get_term($location_id, 'locations');
                    $location_name = $location ? $location->name : "Location #$location_id";
                    
                    $order->add_order_note(
                        sprintf(
                            __('OpenPOS: Restored %s stock by %d at %s. New stock: %d', 'wcmlim'),
                            $product_name,
                            $reduced_qty,
                            $location_name,
                            $new_stock
                        )
                    );
                    
                    // Remove the meta since we've restored it
                    $item->delete_meta_data('_wcmlim_openpos_stock_reduced');
                    $item->save();
                }
            }
        }
    }
}

// Only initialize the class if OpenPOS integration is enabled
if (get_option('wcmlim_pos_compatiblity') === 'on') {
    $wcmlim_openpos_helper = new WCMLIM_OpenPOS_Helper();
}
?>