<?php

namespace BexioConnectorByHelvy;

/**
 * Handle WooCommerce Webhooks Events
 *
 * @since 0.1.0
 */

defined('ABSPATH') || exit;

class WooCommerceWebhooks
{
    private $comprehensive_lock_handles = [];

	public function __construct()
	{
        add_action('woocommerce_new_order', array($this, 'handle_order_created'), 10, 2);
        add_filter('woocommerce_order_status_changed', array($this, 'handle_order_status_changed'), 10, 3 );
        add_action('woocommerce_subscription_payment_complete', array($this, 'handle_subscription_payment_complete'), 10, 2);
        add_action('woocommerce_subscription_renewal_payment_complete', array($this, 'handle_renewal_payment_complete'), 10, 2);
        
        // Hook into WooCommerce email attachments for all email types
        add_filter('woocommerce_email_attachments', array($this, 'add_bexio_attachments_to_woocommerce_email'), 10, 4);
        
        // Hook for sending copy emails via cron
        add_action('bexio_send_copy_email', array($this, 'send_copy_email'));
        
        // Hook into custom invoice email to add attachments (separate dedicated invoice email)
        add_filter('woocommerce_email_attachments', array($this, 'attach_invoice_to_custom_email'), 10, 4);
        
        // Fallback hook to ensure custom invoice email is triggered for all completed orders
        add_action('woocommerce_order_status_completed', array($this, 'handle_order_completed_for_invoice'), 20, 2);
    }

    function handle_order_status_changed($order_id, $old_status, $new_status)
    {
        // Syncing must never break the order flow: catch everything, including
        // fatal \Error (e.g. a function disabled by the host's disable_functions).
        try {
            $this->do_handle_order_status_changed($order_id, $old_status, $new_status);
        } catch (\Throwable $e) {
            _bcbh_log("❌ Unhandled error while handling status change of order {$order_id}: " . $e->getMessage() . " @ " . $e->getFile() . ":" . $e->getLine(), 'ERROR');
        }
    }

    private function do_handle_order_status_changed($order_id, $old_status, $new_status)
    {
        $order = \wc_get_order($order_id);

        if (!$order) {
            _bcbh_log("❌ Cannot handle status change of order $order_id - order not found");
            return;
        }

        // Log status changes
        _bcbh_log("Order ID: " . $order_id);
        _bcbh_log("Old status: " . $old_status);
        _bcbh_log("New status: " . $new_status);
        _bcbh_log("Payment method: " . $order->get_payment_method());
        _bcbh_log("Payment method title: " . $order->get_payment_method_title());

        // Log specifically when order becomes completed (this should trigger custom invoice email)
        if ($new_status === 'completed') {
            _bcbh_log("WebhookHandler: Order {$order_id} changed to completed status - this should trigger custom invoice email");
        }

        // Execute comprehensive sync - the method will internally check what needs to be synced based on status
        $this->execute_comprehensive_order_sync($order, $new_status);

        // Sync based on status
        if (in_array($new_status, array('processing', 'completed'))) {
            _bcbh_log("🔄 Attempting payment sync for order {$order_id} (status: {$new_status})");
            $result = SyncManager::instance()->execute_sync_operation(
                'payment',
                $order_id,
                array(WCToBexio::instance(), 'sync_order_payment'),
                array($order)
            );
            _bcbh_log("Payment sync result: " . print_r($result, true));
        }

        if ($new_status === 'completed') {
            _bcbh_log("🔄 Attempting fulfillment sync for order {$order_id}");
            $result = SyncManager::instance()->execute_sync_operation(
                'fulfillment',
                $order_id,
                array(WCToBexio::instance(), 'sync_order_fulfillment'),
                array($order)
            );
            _bcbh_log("Fulfillment sync result: " . print_r($result, true));
            
            // Trigger custom invoice email for completed orders
            $this->trigger_custom_invoice_email($order_id, $order);
        }
    }

    /**
     * Triggered when a new order is created
     * @param $order_id int Order ID
     * @param $order array Order
     * @return void
     */
	function handle_order_created($order_id, $order) {
        // This runs on woocommerce_new_order, in the middle of checkout: any
        // uncaught error here aborts the customer's purchase. Never let one out.
        try {
            $this->do_handle_order_created($order_id, $order);
        } catch (\Throwable $e) {
            _bcbh_log("❌ Unhandled error while handling creation of order {$order_id}: " . $e->getMessage() . " @ " . $e->getFile() . ":" . $e->getLine(), 'ERROR');
        }
    }

    private function do_handle_order_created($order_id, $order) {
        if (!$order) {
            $order = \wc_get_order($order_id);
        }
        
        if (!$order) {
            _bcbh_log("❌ Cannot sync order $order_id - order not found");
            return;
        }

        // Check if order has line items before attempting sync
        $line_items = $order->get_items();
        _bcbh_log("Line items nr.: " . count($line_items));
        if (empty($line_items)) {
            _bcbh_log("⚠️ Order $order_id has no line items. Skipping sync.");
            return;
        }

        // Execute comprehensive order sync through SyncManager
        $this->execute_comprehensive_order_sync($order, $order->get_status());
        
        // If order is already completed, trigger custom invoice email
        if ($order->get_status() === 'completed') {
            _bcbh_log("Bexio Connector: Order {$order_id} was created with completed status, triggering custom invoice email");
            $this->trigger_custom_invoice_email($order_id, $order);
        }
    }

    /**
     * Execute all sync operations for an order using the SyncManager
     * The method intelligently determines what needs to be synced based on the current order status
     * 
     * @param WC_Order $order The order object
     * @param string $new_status The new order status (optional, for status-based sync decisions)
     */
    private function execute_comprehensive_order_sync($order, $new_status = null) {
        $order_id = $order->get_id();
        
        // Acquire a comprehensive sync lock to prevent overlapping sync sessions
        $comprehensive_lock_key = "comprehensive_sync_{$order_id}";
        $comprehensive_operation_id = md5($order_id . '_comprehensive_' . time() . '_' . uniqid());
        
        if (!$this->acquire_comprehensive_sync_lock($comprehensive_lock_key, $comprehensive_operation_id)) {
            _bcbh_log("⏸️ Comprehensive sync already in progress for order $order_id, skipping");
            return;
        }
        
        try {
            _bcbh_log("🔄 Starting comprehensive sync for order $order_id");

            // Determine what needs to be synced based on current status and settings
            $sync_orders_statuses = get_option(AdminAPISettings::$prefix . 'sync_orders_statuses', array());
            $sync_invoices_statuses = get_option(AdminAPISettings::$prefix . 'sync_invoices_statuses', array());
            $sync_issue_invoices_statuses = get_option(AdminAPISettings::$prefix . 'sync_issue_invoices_statuses', array());
            $auto_create_delivery_notes = get_option(AdminAPISettings::$prefix . 'auto_create_delivery_notes', true);

            $should_sync_order = $new_status && in_array($new_status, $sync_orders_statuses);
            $should_sync_invoice = $new_status && in_array($new_status, $sync_invoices_statuses);
            $should_issue_invoice = $new_status && in_array($new_status, $sync_issue_invoices_statuses);
            $should_sync_delivery = $new_status && $auto_create_delivery_notes && in_array($new_status, array('processing', 'completed'));

            _bcbh_log("Sync decisions for status '{$new_status}': order={$should_sync_order}, invoice={$should_sync_invoice}, issue={$should_issue_invoice}, delivery={$should_sync_delivery}");

            // 1. Sync order to Bexio (if needed)
            if ($should_sync_order) {
                $result = SyncManager::instance()->execute_sync_operation(
                    'order',
                    $order_id,
                    array(WCToBexio::instance(), 'sync_order'),
                    array($order)
                );
                
                if ($result instanceof \WP_Error || (is_array($result) && isset($result['status']) && $result['status'] === 'LOCKED')) {
                    _bcbh_log("Order sync failed or locked: " . print_r($result, true));
                    return;
                }

                // Re-fetch order to get updated meta
                $order = \wc_get_order($order_id);
            }

            // 2. Create delivery note (if needed)
            if ($should_sync_delivery) {
                $result = SyncManager::instance()->execute_sync_operation(
                    'delivery',
                    $order_id,
                    array(WCToBexio::instance(), 'sync_order_create_delivery'),
                    array($order_id)
                );
                
                if ($result instanceof \WP_Error) {
                    _bcbh_log("Delivery creation failed: " . $result->get_error_message());
                }

                // Re-fetch order
                $order = \wc_get_order($order_id);
            }

            // 3. Create invoice (if needed and only for paid orders)
            if ($should_sync_invoice && $order->get_total() != 0) {
                _bcbh_log("🔄 Creating invoice for order $order_id");
                
                // Double check if invoice already exists before attempting creation
                $existing_invoice_id = get_post_meta($order->get_id(), AdminAPISettings::$prefix . 'bexio_invoice_id', true);
                if ($existing_invoice_id) {
                    _bcbh_log("⏭️ Invoice already exists (ID: {$existing_invoice_id}), skipping creation");
                    $bexio_invoice_id = $existing_invoice_id;
                } else {
                    // Create invoice
                    $result = SyncManager::instance()->execute_sync_operation(
                        'invoice_create',
                        $order_id,
                        array(WCToBexio::instance(), 'sync_order_create_invoice'),
                        array($order_id)
                    );

                    _bcbh_log("Invoice creation result: " . print_r($result, true));
                    
                    if ($result instanceof \WP_Error) {
                        _bcbh_log("Invoice creation failed: " . $result->get_error_message());
                        return;
                    }

                    // Re-fetch order to get the latest meta (invoice might have been created)
                    $order = \wc_get_order($order_id);
                    $bexio_invoice_id = get_post_meta($order->get_id(), AdminAPISettings::$prefix . 'bexio_invoice_id', true);
                }
                
                // Issue invoice if it exists and should be issued (regardless of whether it was just created or already existed)
                if ($bexio_invoice_id && $should_issue_invoice) {
                    _bcbh_log("🔄 Invoice exists (ID: {$bexio_invoice_id}), attempting to issue it");
                    
                    $result = SyncManager::instance()->execute_sync_operation(
                        'invoice_issue',
                        $order_id,
                        array(WCToBexio::instance(), 'sync_order_issue_invoice'),
                        array($order_id)
                    );

                    _bcbh_log("Invoice issuing result: " . print_r($result, true));
                    
                    if ($result instanceof \WP_Error) {
                        _bcbh_log("Invoice issuing failed: " . $result->get_error_message());
                    }

                    // Re-fetch order again
                    $order = \wc_get_order($order_id);
                }

                // Sync payment if order is paid (regardless of invoice issue status)
                if ($order->is_paid()) {
                    _bcbh_log("🔄 Order is paid, attempting payment sync");
                    
                    $result = SyncManager::instance()->execute_sync_operation(
                        'payment',
                        $order_id,
                        array(WCToBexio::instance(), 'sync_order_payment'),
                        array($order)
                    );
                    
                    if ($result instanceof \WP_Error) {
                        _bcbh_log("Payment sync failed: " . $result->get_error_message());
                    } else {
                        _bcbh_log("Payment sync completed: " . print_r($result, true));
                    }
                } else {
                    _bcbh_log("⏭️ Order is not paid yet, skipping payment sync");
                }
            }

            // 4. Handle fulfillment for completed orders
            if ($order->get_status() === 'completed') {
                $result = SyncManager::instance()->execute_sync_operation(
                    'fulfillment',
                    $order_id,
                    array(WCToBexio::instance(), 'sync_order_fulfillment'),
                    array($order)
                );
                
                if ($result instanceof \WP_Error) {
                    _bcbh_log("Fulfillment sync failed: " . $result->get_error_message());
                }
            }

            _bcbh_log("✅ Comprehensive sync completed for order $order_id");

        } catch (\Throwable $e) {
            _bcbh_log("❌ Exception during comprehensive sync for order $order_id: " . $e->getMessage());
        } finally {
            // Always release the comprehensive sync lock
            $this->release_comprehensive_sync_lock($comprehensive_lock_key, $comprehensive_operation_id);
        }
    }

    /**
     * Acquire comprehensive sync lock using file-based atomic locking
     */
    private function acquire_comprehensive_sync_lock($lock_key, $operation_id) {
        $lock_dir = wp_upload_dir()['basedir'] . '/bexio-sync-locks';
        if (!file_exists($lock_dir)) {
            wp_mkdir_p($lock_dir);
        }
        
        $lock_file = $lock_dir . '/' . $lock_key . '.lock';
        
        // Try to acquire exclusive lock with timeout
        $lock_handle = fopen($lock_file, 'c+');
        if (!$lock_handle) {
            _bcbh_log("❌ Failed to open lock file for {$lock_key}");
            return false;
        }
        
        // Try to acquire exclusive lock (non-blocking)
        if (flock($lock_handle, LOCK_EX | LOCK_NB)) {
            // Check if lock is stale
            $lock_data = fread($lock_handle, 1024);
            if ($lock_data) {
                $existing_lock = json_decode($lock_data, true);
                if ($existing_lock && isset($existing_lock['timestamp'])) {
                    $age = time() - $existing_lock['timestamp'];
                    if ($age < 120) { // Lock is still fresh, someone else owns it
                        flock($lock_handle, LOCK_UN);
                        fclose($lock_handle);
                        _bcbh_log("❌ Fresh lock exists for {$lock_key}, age: {$age}s");
                        return false;
                    }
                }
            }
            
            // Write our lock data
            $lock_data = json_encode([
                'operation_id' => $operation_id,
                'timestamp' => time(),
                'pid' => _bcbh_getpid(),
            ]);
            
            ftruncate($lock_handle, 0);
            rewind($lock_handle);
            fwrite($lock_handle, $lock_data);
            fflush($lock_handle);
            
            // Store handle for later release
            $this->comprehensive_lock_handles = $this->comprehensive_lock_handles ?? [];
            $this->comprehensive_lock_handles[$lock_key] = [
                'handle' => $lock_handle,
                'operation_id' => $operation_id
            ];
            
            _bcbh_log("🔒 Comprehensive sync lock acquired for {$lock_key} (file-based)");
            return true;
        } else {
            fclose($lock_handle);
            _bcbh_log("❌ Failed to acquire file lock for {$lock_key}");
            return false;
        }
    }

    /**
     * Release comprehensive sync lock
     */
    private function release_comprehensive_sync_lock($lock_key, $operation_id) {
        if (!isset($this->comprehensive_lock_handles[$lock_key])) {
            return;
        }
        
        $lock_info = $this->comprehensive_lock_handles[$lock_key];
        if ($lock_info['operation_id'] !== $operation_id) {
            return; // Not our lock
        }
        
        $lock_handle = $lock_info['handle'];
        if (is_resource($lock_handle)) {
            flock($lock_handle, LOCK_UN);
            fclose($lock_handle);
            
            // Remove the lock file
            $lock_dir = wp_upload_dir()['basedir'] . '/bexio-sync-locks';
            $lock_file = $lock_dir . '/' . $lock_key . '.lock';
            if (file_exists($lock_file)) {
                unlink($lock_file);
            }
            
            unset($this->comprehensive_lock_handles[$lock_key]);
            _bcbh_log("🔓 Comprehensive sync lock released for {$lock_key} (file-based)");
        }
    }

    /**
     * Handle subscription payment complete (which creates the first order of the subscription)
     * @param WC_Subscription $subscription Subscription object
     * @return void
     */
    public function handle_subscription_payment_complete($subscription) {
        $order = $subscription->get_last_order();
        if ($order) {
            if (is_int($order)) {
                $order = \wc_get_order($order);
            }
            $this->handle_order_created($order->get_id(), $order);
        }
    }

    /**
     * Handle subscription renewal payment complete (which creates the renewal order of the subscription)
     * @param WC_Subscription $subscription Subscription object
     * @param WC_Order $last_order Last order object
     * @return void
     */
    public function handle_renewal_payment_complete($subscription, $last_order) {
        $this->handle_order_created($last_order->get_id(), $last_order);
    }

    /**
     * Add Bexio attachments to WooCommerce emails using the proper filter
     * This works for all email types including automatic emails sent due to order status changes
     * Note: Custom invoice email (bexio_invoice_email) is handled separately by attach_invoice_to_custom_email
     */
    public function add_bexio_attachments_to_woocommerce_email($attachments, $email_id, $object, $email) {
        // Skip if not an order object
        if (!is_a($object, 'WC_Order')) {
            return $attachments;
        }

        // Skip custom invoice email - it's handled separately
        if ($email_id === 'bexio_invoice_email') {
            return $attachments;
        }

        $order = $object;
        _bcbh_log("Bexio Connector: Processing attachments for email ID: " . $email_id . " | Order ID: " . $order->get_id());

        // Check plugin settings for which attachments to include
        $attach_invoice_statuses = get_option(AdminAPISettings::$prefix . 'attach_bexio_invoice_to_woocommerce_email_statuses', array());
        $attach_order_statuses = get_option(AdminAPISettings::$prefix . 'attach_bexio_order_to_woocommerce_email_statuses', array());
        $attach_for_payment_methods = get_option(AdminAPISettings::$prefix . 'attach_bexio_document_to_woocommerce_email_for_payment_methods', array());

        if (empty($attach_invoice_statuses) && empty($attach_order_statuses)) {
            _bcbh_log("Bexio Connector: No email statuses configured for attachments");
            return $attachments;
        }

        // Check payment method restrictions
        if (is_array($attach_for_payment_methods) && !empty($attach_for_payment_methods)) {
            $payment_method = $order->get_payment_method();
            if (!in_array(strtolower($payment_method), array_map('strtolower', $attach_for_payment_methods))) {
                _bcbh_log("Bexio Connector: Payment method {$payment_method} not allowed for attachments");
                return $attachments;
            }
        }

        // Create temp directory
        $upload_dir = wp_upload_dir();
        $temp_dir = $upload_dir['basedir'] . '/bexio-temp';
        if (!file_exists($temp_dir)) {
            mkdir($temp_dir, 0755, true);
        }

        // Check if invoice PDF should be attached for this email type
        $should_attach_invoice = in_array($email_id, $attach_invoice_statuses);
        $invoice_id = get_post_meta($order->get_id(), AdminAPISettings::$prefix . 'bexio_invoice_id', true);
        
        if ($should_attach_invoice && $invoice_id) {
            _bcbh_log("Bexio Connector: Email ID '{$email_id}' is configured for invoice attachment. Fetching invoice PDF for invoice ID: " . $invoice_id);
            
            try {
                $invoice_pdf = API::instance()->get_invoice_pdf($invoice_id);
                if (!($invoice_pdf instanceof \WP_Error) && !empty($invoice_pdf['content'])) {
                    $document_name = get_option(AdminAPISettings::$prefix . 'attach_bexio_invoice_to_woocommerce_document_name', "invoice-{woocommerce_order_number}");
                    $document_name = str_replace('{woocommerce_order_number}', $order->get_id(), $document_name);
                    $pdf_path = $temp_dir . '/' . $document_name . '.pdf';
                    $result = file_put_contents($pdf_path, base64_decode($invoice_pdf['content']));
                    
                    if ($result !== false) {
                        $attachments[] = $pdf_path;
                        _bcbh_log("Bexio Connector: Invoice PDF attached successfully: " . $pdf_path);
                        
                        // Clean up file after email is sent
                        add_action('wp_mail_succeeded', function() use ($pdf_path) {
                            if (file_exists($pdf_path)) {
                                unlink($pdf_path);
                            }
                        });
                    } else {
                        _bcbh_log("Bexio Connector: Failed to write invoice PDF to file");
                    }
                } else {
                    _bcbh_log("Bexio Connector: Failed to get invoice PDF from API");
                }
            } catch (\Throwable $e) {
                _bcbh_log("Bexio Connector: Error fetching invoice PDF: " . $e->getMessage());
            }
        } else if (!$should_attach_invoice && $invoice_id) {
            _bcbh_log("Bexio Connector: Email ID '{$email_id}' is NOT configured for invoice attachment");
        }

        // Check if order PDF should be attached for this email type
        $should_attach_order = in_array($email_id, $attach_order_statuses);
        $bexio_order_id = get_post_meta($order->get_id(), AdminAPISettings::$prefix . 'bexio_order_id', true);
        
        if ($should_attach_order && $bexio_order_id) {
            _bcbh_log("Bexio Connector: Email ID '{$email_id}' is configured for order attachment. Fetching order PDF for order ID: " . $bexio_order_id);
            
            try {
                $order_pdf = API::instance()->get_order_pdf($bexio_order_id);
                if (!($order_pdf instanceof \WP_Error) && !empty($order_pdf['content'])) {
                    $document_name = get_option(AdminAPISettings::$prefix . 'attach_bexio_order_to_woocommerce_document_name', "order-{woocommerce_order_number}");
                    $document_name = str_replace('{woocommerce_order_number}', $order->get_id(), $document_name);
                    $pdf_path = $temp_dir . '/' . $document_name . '.pdf';
                    $result = file_put_contents($pdf_path, base64_decode($order_pdf['content']));
                    
                    if ($result !== false) {
                        $attachments[] = $pdf_path;
                        _bcbh_log("Bexio Connector: Order PDF attached successfully: " . $pdf_path);
                        
                        // Clean up file after email is sent
                        add_action('wp_mail_succeeded', function() use ($pdf_path) {
                            if (file_exists($pdf_path)) {
                                unlink($pdf_path);
                            }
                        });
                    } else {
                        _bcbh_log("Bexio Connector: Failed to write order PDF to file");
                    }
                } else {
                    _bcbh_log("Bexio Connector: Failed to get order PDF from API");
                }
            } catch (\Throwable $e) {
                _bcbh_log("Bexio Connector: Error fetching order PDF: " . $e->getMessage());
            }
        } else if (!$should_attach_order && $bexio_order_id) {
            _bcbh_log("Bexio Connector: Email ID '{$email_id}' is NOT configured for order attachment");
        }

        _bcbh_log("Bexio Connector: Final attachment count: " . count($attachments));
        return $attachments;
    }

    /**
     * Trigger custom invoice email for completed orders
     * This ensures the custom invoice email is sent when orders are completed
     *
     * @param int $order_id
     * @param WC_Order $order
     */
    private function trigger_custom_invoice_email($order_id, $order) {
        _bcbh_log("Bexio Connector: Triggering custom invoice email for completed order {$order_id}");
        
        // Check if custom invoice email is enabled
        $email_enabled = get_option(AdminAPISettings::$prefix . 'custom_invoice_email_enabled', false);
        _bcbh_log("Bexio Connector: Custom invoice email enabled setting: " . ($email_enabled ? 'true' : 'false'));
        _bcbh_log("Bexio Connector: Setting key: " . AdminAPISettings::$prefix . 'custom_invoice_email_enabled');
        
        if (!$email_enabled) {
            _bcbh_log("Bexio Connector: Custom invoice email is disabled, skipping trigger");
            return;
        }
        
        // Check if WooCommerce is available and get the mailer
        if (!class_exists('WooCommerce')) {
            _bcbh_log("Bexio Connector: WooCommerce class not available for custom invoice email");
            return;
        }
        
        global $woocommerce;
        if (!$woocommerce || !method_exists($woocommerce, 'mailer')) {
            _bcbh_log("Bexio Connector: WooCommerce mailer not available for custom invoice email");
            return;
        }
        
        // Get the mailer and email classes
        $mailer = $woocommerce->mailer();
        $email_classes = $mailer->get_emails();
        
        _bcbh_log("Bexio Connector: Available email classes: " . implode(', ', array_keys($email_classes)));
        
        // Check if our custom email class exists
        if (isset($email_classes['bexio_invoice_email'])) {
            _bcbh_log("Bexio Connector: Found custom invoice email class, triggering email");
            try {
                $email_classes['bexio_invoice_email']->trigger($order_id, $order);
                _bcbh_log("Bexio Connector: Custom invoice email trigger called successfully");
            } catch (\Throwable $e) {
                _bcbh_log("Bexio Connector: Error triggering custom invoice email: " . $e->getMessage());
            }
        } else {
            _bcbh_log("Bexio Connector: Custom invoice email class 'bexio_invoice_email' not found");
            _bcbh_log("Bexio Connector: This might indicate the custom email class is not properly registered");
        }
    }

    /**
     * Send copy email via cron
     * This method is called by the bexio_send_copy_email action
     */
    public function send_copy_email() {
        // Implementation for sending copy emails via cron
        // This can be implemented based on specific requirements
        _bcbh_log("Bexio Connector: Copy email cron job triggered");
    }

    /**
     * Add invoice PDF attachment to custom invoice email
     * This method sends a separate, dedicated invoice email when orders are completed
     * It's different from regular WooCommerce email attachments
     *
     * @param array $attachments
     * @param string $email_id
     * @param mixed $object
     * @param mixed $email
     * @return array
     */
    public function attach_invoice_to_custom_email($attachments, $email_id, $object, $email) {
        // Only attach to our custom invoice email
        if ($email_id !== 'bexio_invoice_email') {
            return $attachments;
        }

        if (!is_a($object, 'WC_Order')) {
            return $attachments;
        }

        $order = $object;
        $bexio_invoice_id = get_post_meta($order->get_id(), AdminAPISettings::$prefix . 'bexio_invoice_id', true);
        
        if (!$bexio_invoice_id) {
            _bcbh_log("CustomInvoiceEmail: No Bexio invoice found for order {$order->get_id()}, no attachment added");
            return $attachments;
        }

        // Check payment method restrictions
        $attach_for_payment_methods = get_option(AdminAPISettings::$prefix . 'attach_bexio_document_to_woocommerce_email_for_payment_methods', array());
        if (is_array($attach_for_payment_methods) && !empty($attach_for_payment_methods)) {
            $payment_method = $order->get_payment_method();
            if (!in_array(strtolower($payment_method), array_map('strtolower', $attach_for_payment_methods))) {
                _bcbh_log("CustomInvoiceEmail: Payment method {$payment_method} not allowed for attachments");
                return $attachments;
            }
        }

        // Create temp directory
        $upload_dir = wp_upload_dir();
        $temp_dir = $upload_dir['basedir'] . '/bexio-temp';
        if (!file_exists($temp_dir)) {
            mkdir($temp_dir, 0755, true);
        }

        try {
            $invoice_pdf = API::instance()->get_invoice_pdf($bexio_invoice_id);
            if (!($invoice_pdf instanceof \WP_Error) && !empty($invoice_pdf['content'])) {
                $pdf_path = $temp_dir . '/invoice-' . $order->get_id() . '.pdf';
                $result = file_put_contents($pdf_path, base64_decode($invoice_pdf['content']));
                
                if ($result !== false) {
                    $attachments[] = $pdf_path;
                    _bcbh_log("CustomInvoiceEmail: Invoice PDF attached successfully: " . $pdf_path);
                    
                    // Clean up file after email is sent
                    add_action('wp_mail_succeeded', function() use ($pdf_path) {
                        if (file_exists($pdf_path)) {
                            unlink($pdf_path);
                        }
                    });
                } else {
                    _bcbh_log("CustomInvoiceEmail: Failed to write invoice PDF to file");
                }
            } else {
                _bcbh_log("CustomInvoiceEmail: Failed to get invoice PDF from API");
            }
        } catch (\Throwable $e) {
            _bcbh_log("CustomInvoiceEmail: Error fetching invoice PDF: " . $e->getMessage());
        }

        return $attachments;
    }

    /**
     * Fallback hook to ensure custom invoice email is triggered for all completed orders
     * This is a separate action to avoid conflicts with the main handle_order_status_changed
     * and to ensure it runs even if the webhook handler is not called for a specific order.
     *
     * @param int $order_id
     * @param WC_Order $order
     */
    public function handle_order_completed_for_invoice($order_id, $order) {
        _bcbh_log("Bexio Connector: Fallback - Triggering custom invoice email for order {$order_id} (status: completed)");
        $this->trigger_custom_invoice_email($order_id, $order);
    }


}
