<?php

namespace BexioConnectorByHelvy;

/**
 * Setup Bulk Actions
 *
 * @since 0.3.0
 */

defined('ABSPATH') || exit;

class BulkActions
{
    public function __construct()
    {
        add_filter('bulk_actions-woocommerce_page_wc-orders', array($this, 'download_bexio_pdfs_bulk_action'));
        add_filter('handle_bulk_actions-woocommerce_page_wc-orders', array($this, 'handle_download_bexio_pdfs_bulk_action'), 10, 3);
        add_action('admin_notices', array($this, "download_bexio_pdfs_bulk_action_admin_notice"));

        // Add a hook to handle the download of the zip file
        add_action('admin_init', array($this, "download_bexio_zip_file"));
    }

    /**
     * Add "Download bexio invoices/orders" bulk actions to the orders list
     *
     * @since 0.3.0
     */
    public function download_bexio_pdfs_bulk_action($bulk_actions)
    {
        $bulk_actions['download_bexio_invoices'] = 'Download bexio invoices (PDF)';
        $bulk_actions['download_bexio_orders'] = 'Download bexio orders (PDF)';
        return $bulk_actions;
    }

    /**
     * Handle "Download bexio invoices" bulk action
     *
     * @since 0.3.0
     */
    public function handle_download_bexio_pdfs_bulk_action($redirect_to, $action, $post_ids)
    {
        if (!in_array($action, array('download_bexio_invoices', 'download_bexio_orders'))) {
            return $redirect_to;
        }
        
        $bexio_resource = $action === 'download_bexio_invoices' ? 'invoice' : 'order';
        $successful_ids = [];
        $errors = [];
        $zip = new \ZipArchive();
        $upload_dir = wp_upload_dir();
        $zip_file_path = $upload_dir['basedir'] . '/bexio_' . $bexio_resource . 's_' . time() . '.zip';
        if ($zip->open($zip_file_path, \ZipArchive::CREATE) !== true) {
            _bcbh_log("Cannot create zip file");
            return $redirect_to;
        }

        foreach ($post_ids as $post_id) {
            $order = wc_get_order($post_id);
            if (!$order) {
                $errors[] = "Order not found: " . $post_id;
                continue;
            }

            _bcbh_log("Processing order " . $order->get_id());
            $bexio_resource_id = $order->get_meta(AdminAPISettings::$prefix . 'bexio_' . $bexio_resource . '_id') ?: get_post_meta($post_id, AdminAPISettings::$prefix . 'bexio_' . $bexio_resource . '_id', true);
            if (empty($bexio_resource_id)) {
                $errors[] = "No bexio " . $bexio_resource . " found for order " . $order->get_id();
                continue;
            }

            $invoice_base64 = null;
            if ($bexio_resource === 'invoice') {
                $invoice_pdf = API::instance()->get_invoice_pdf($bexio_resource_id);
                if ($invoice_pdf instanceof \WP_Error) {
                    $errors[] = "Failed to get invoice PDF for order " . $order->get_id() . ": " . $invoice_pdf->get_error_message();
                    continue;
                }

                $invoice_base64 = $invoice_pdf["content"];
            } else {
                $order_pdf = API::instance()->get_order_pdf($bexio_resource_id);
                if ($order_pdf instanceof \WP_Error) {
                    $errors[] = "Failed to get order PDF for order " . $order->get_id() . ": " . $order_pdf->get_error_message();
                    continue;
                }

                $invoice_base64 = $order_pdf["content"];
            }

            if ($invoice_base64) {
                $decoded_pdf = base64_decode($invoice_base64);
                if ($decoded_pdf === false) {
                    $errors[] = "Failed to decode the " . $bexio_resource . " PDF for order " . $order->get_id();
                    continue;
                }

                $temp_file_path = tempnam($upload_dir['basedir'], 'invoice-' . $order->get_id() . '-');
                $custom_temp_file_path = $temp_file_path . '.pdf';
                rename($temp_file_path, $custom_temp_file_path);

                $temp_file = fopen($custom_temp_file_path, 'w');
                $file_written = fwrite($temp_file, $decoded_pdf);
                if ($file_written === false) {
                    $errors[] = "Failed to store the " . $bexio_resource . " PDF for order " . $order->get_id();
                    continue;
                }
                fclose($temp_file);

                $zip->addFile($custom_temp_file_path, $bexio_resource . '-' . $order->get_id() . '.pdf');
                $successful_ids[] = $post_id;
            }
        }

        $zip->close();

        // Redirect to the zip file for download
        return add_query_arg(array(
            'download_bexio_invoices' => '1',
            'zip_file' => $zip_file_path,
            'processed_count' => count($successful_ids),
            'successful_ids' => implode(',', $successful_ids),
            'errors' => implode(',', $errors),
        ), $redirect_to);
    }

    /**
     * Display admin notice after invoices download bulk action
     *
     * @since 0.3.0
     */
    public function download_bexio_pdfs_bulk_action_admin_notice() {
        global $pagenow;

        if ('admin.php' === $pagenow && isset($_GET['page']) && 'wc-orders' === $_GET['page'] && isset($_GET['download_bexio_invoices'])) {
            $count = intval( $_REQUEST['processed_count'] );

            $successful_ids = isset($_GET['successful_ids']) ? explode(',', $_GET['successful_ids']) : [];
            $errors = isset($_GET['errors']) ? explode(',', $_GET['errors']) : [];

            printf('<div class="notice notice-success fade is-dismissible"><p>' . (
                sprintf(__('Successfully downloaded %s invoices (ZIP archive). Orders: %s', 'bexio-connector-by-helvy'), number_format_i18n($count), implode(', ', $successful_ids))
            ) . '</p></div>', $count);

            if (!empty($errors)) {
                echo '<div class="notice notice-error fade is-dismissible"><p>' . __('Errors occurred:', 'bexio-connector-by-helvy') . '</p><ul>';
                foreach ($errors as $error) {
                    echo '<li>' . esc_html($error) . '</li>';
                }
                echo '</ul></div>';
            }
        }
    }

    /**
     * Download the zip file (invoices or orders bulk action)
     *
     * @since 0.3.0
     */
    public function download_bexio_zip_file() {
        if (isset($_GET['download_bexio_invoices']) && $_GET['download_bexio_invoices'] === '1' && isset($_GET['zip_file'])) {
            $zip_file = $_GET['zip_file'];
            if (file_exists($zip_file)) {
                header('Content-Type: application/zip');
                header('Content-Disposition: attachment; filename="' . basename($zip_file) . '"');
                header('Content-Length: ' . filesize($zip_file));
                readfile($zip_file);
                unlink($zip_file); // Delete the zip file after download
                exit;
            }
        }
    }
}
