<?php

namespace Storeplugin\PDFInvoice\App\Integrations;

defined('ABSPATH') || exit;

use Storeplugin\PDFInvoice\App\Contracts\WooHookableInterface;
use Storeplugin\PDFInvoice\App\TempDir;
use Storeplugin\PDFInvoice\App\Utils;
use Storeplugin\PDFInvoice\Config;
use Storeplugin\PDFInvoice\Asset;
use Storeplugin\PDFInvoice\Framework\Utils\File;

class WooCommerceAdminIntegration implements WooHookableInterface {
    /**
     * Initialize WooCommerce integration
     */
    public function init(): void {
        // Add print invoice button to orders list
        add_filter('woocommerce_admin_order_actions', [$this, 'add_order_action'], 10, 2);

        // Add meta box to order page
        add_action('add_meta_boxes', [$this, 'add_order_meta_box']);

        // Handle PDF download
        add_action('admin_init', [$this, 'handle_pdf_download']);

        // Add bulk action
        add_filter('bulk_actions-edit-shop_order', [$this, 'add_bulk_action']);
        add_filter('handle_bulk_actions-edit-shop_order', [$this, 'handle_bulk_action'], 10, 3);

        // HPOS compatibility
        add_filter('bulk_actions-woocommerce_page_wc-orders', [$this, 'add_bulk_action']);
        add_filter('handle_bulk_actions-woocommerce_page_wc-orders', [$this, 'handle_bulk_action'], 10, 3);
    }

    /**
     * Add order action button
     */
    public function add_order_action($actions, $order) {
        Asset::registerAppAdminAssets();
        wp_enqueue_style(Config::asset('admin-style'));
        wp_enqueue_script(Config::asset('common-script'));

        $actions['nxtpdf_invoice_print'] = [
            'url' => wp_nonce_url(
                admin_url('admin.php?action=nxtpdf_invoice_print&order_id=' . $order->get_id()),
                'nxtpdf_invoice_print'
            ),
            'name' => __('Print Invoice', 'storeinvoice-print-pdf-invoices-and-packing-slips'),
            'action' => 'nxtpdf_invoice_print',
        ];

        $actions['nxtpdf_packing_slip_print'] = [
            'url' => wp_nonce_url(
                admin_url('admin.php?action=nxtpdf_packing_slip_print&order_id=' . $order->get_id()),
                'nxtpdf_packing_slip_print'
            ),
            'name' => __('Print Packing Slip', 'storeinvoice-print-pdf-invoices-and-packing-slips'),
            'action' => 'nxtpdf_packing_slip_print',
        ];

        return $actions;
    }

    /**
     * Add meta box to order page
     */
    public function add_order_meta_box() {
        // Register for both legacy (shop_order) and HPOS (woocommerce_page_wc-orders)
        add_meta_box(
            'nxtpdf_invoice_actions',
            __('PDF Invoice', 'storeinvoice-print-pdf-invoices-and-packing-slips'),
            [$this, 'render_meta_box'],
            ['shop_order', 'woocommerce_page_wc-orders'],
            'side',
            'default'
        );
    }

    /**
     * Render meta box
     */
    public function render_meta_box($post_or_order) {
        $order = $post_or_order instanceof \WC_Order ? $post_or_order : wc_get_order($post_or_order->ID);

        if (!$order) {
            return;
        }

        $print_url = wp_nonce_url(
            admin_url('admin.php?action=nxtpdf_invoice_print&order_id=' . $order->get_id()),
            'nxtpdf_invoice_print'
        );

        $download_url = wp_nonce_url(
            admin_url('admin.php?action=nxtpdf_invoice_download&order_id=' . $order->get_id()),
            'nxtpdf_invoice_download'
        );

        $packing_slip_url = wp_nonce_url(
            admin_url('admin.php?action=nxtpdf_packing_slip_download&order_id=' . $order->get_id()),
            'nxtpdf_packing_slip_download'
        );
        ?>
        <div class="storeinvoice-print-pdf-invoices-and-packing-slips-order-actions">
            <p>
                <a href="<?php echo esc_url($print_url); ?>" class="button button-primary" target="_blank">
                    <span class="dashicons dashicons-printer" style="vertical-align: middle;"></span>
                    <?php esc_html_e('View Invoice', 'storeinvoice-print-pdf-invoices-and-packing-slips'); ?>
                </a>
            </p>
            <p>
                <a href="<?php echo esc_url($download_url); ?>" class="button">
                    <span class="dashicons dashicons-download" style="vertical-align: middle;"></span>
                    <?php esc_html_e('Download PDF', 'storeinvoice-print-pdf-invoices-and-packing-slips'); ?>
                </a>
            </p>
            <p>
                <a href="<?php echo esc_url($packing_slip_url); ?>" class="button">
                    <span class="dashicons dashicons-media-document" style="vertical-align: middle;"></span>
                    <?php esc_html_e('Download Packing Slip', 'storeinvoice-print-pdf-invoices-and-packing-slips'); ?>
                </a>
            </p>
            <p>
                <a href="<?php echo esc_url(admin_url('admin.php?page=nxtpdf-invoice-editor-panel')); ?>">
                    <?php esc_html_e('Edit Invoice Template', 'storeinvoice-print-pdf-invoices-and-packing-slips'); ?>
                </a>
            </p>
        </div>
        <?php
    }

    /**
     * Handle PDF download/print
     */
    public function handle_pdf_download() {
        if (!isset($_GET['action'])) {
            return;
        }

        $action = sanitize_text_field(wp_unslash($_GET['action']));

        $allowed_actions = ['nxtpdf_invoice_print', 'nxtpdf_invoice_download', 'nxtpdf_packing_slip_print', 'nxtpdf_packing_slip_download'];
        if (!in_array($action, $allowed_actions, true)) {
            return;
        }

        if (!current_user_can('edit_shop_orders')) {
            wp_die(esc_html__('You do not have permission to access this page.', 'storeinvoice-print-pdf-invoices-and-packing-slips'));
        }

        check_admin_referer($action);

        $order_id = isset($_GET['order_id']) ? absint($_GET['order_id']) : 0;

        if (!$order_id) {
            wp_die(esc_html__('Invalid order ID.', 'storeinvoice-print-pdf-invoices-and-packing-slips'));
        }

        $is_packing_slip = in_array($action, ['nxtpdf_packing_slip_print', 'nxtpdf_packing_slip_download'], true);
        $editor_group = $is_packing_slip ? Utils::GROUP_PACKING_SLIP_EDITOR : Utils::GROUP_INVOICE_EDITOR;

        $generator = new PdfDocumentGenerator([], $editor_group);
        $result = $generator->generate_order_pdf($order_id);

        if (is_wp_error($result)) {
            wp_die(esc_html($result->get_error_message()));
        }

        $output_destination = in_array($action, ['nxtpdf_invoice_print', 'nxtpdf_packing_slip_print'], true) ? 'I' : 'D';
        $order = wc_get_order($order_id);
        $order_number = $order ? $order->get_order_number() : $order_id;

        if ($is_packing_slip) {
            $filename = 'packing-slip-' . $order_number . '.pdf';
        } else {
            $invoice_number = $order ? $generator->get_invoice_number($order) : '';
            $filename = $generator->get_pdf_filename([
                'order_number' => $order_number,
                'invoice_number' => $invoice_number,
            ]);
        }

        $generator->output($filename, $output_destination);
        exit;
    }

    /**
     * Add bulk action
     */
    public function add_bulk_action($actions) {
        $actions['nxtpdf_invoice_download_bulk'] = __('Download Invoices (PDF)', 'storeinvoice-print-pdf-invoices-and-packing-slips');
        return $actions;
    }

    /**
     * Handle bulk action
     */
    public function handle_bulk_action($redirect_to, $action, $order_ids) {
        if ($action !== 'nxtpdf_invoice_download_bulk') {
            return $redirect_to;
        }

        if (empty($order_ids)) {
            return $redirect_to;
        }

        $generator = new PdfDocumentGenerator();

        // Generate individual PDFs
        $pdf_files = [];
        $used_filenames = [];

        foreach ($order_ids as $order_id) {
            $result = $generator->generate_order_pdf($order_id);

            if (!is_wp_error($result)) {
                $order = wc_get_order($order_id);
                $order_number = $order ? $order->get_order_number() : $order_id;
                $invoice_number = $order ? $generator->get_invoice_number($order) : '';
                $filename = $generator->get_pdf_filename([
                    'order_number' => $order_number,
                    'invoice_number' => $invoice_number,
                ]);
                $base = pathinfo($filename, PATHINFO_FILENAME);
                $ext = pathinfo($filename, PATHINFO_EXTENSION) ?: 'pdf';
                $unique_name = $filename;
                if (isset($used_filenames[$unique_name])) {
                    $unique_name = sanitize_file_name($base . '-' . $order_id) . '.' . $ext;
                }
                $used_filenames[$unique_name] = true;
                $file_path = TempDir::store($unique_name, $generator->get_pdf_string());
                if ($file_path) {
                    $pdf_files[] = $file_path;
                }
            }
        }

        if (count($pdf_files) === 1) {
            // Single file, just download it
            $downloaded = File::sendDownload($pdf_files[0], basename($pdf_files[0]), 'application/pdf');
            TempDir::remove($pdf_files[0]);
            if ($downloaded === false) {
                if (! headers_sent()) {
                    status_header(500);
                    wp_die(esc_html__('Failed to download invoice PDF.', 'storeinvoice-print-pdf-invoices-and-packing-slips'));
                }
                exit;
            }
            exit;
        }

        if (count($pdf_files) > 1) {
            // Create ZIP for multiple files
            $zip_file = TempDir::path() . '/invoices-' . time() . '.zip';
            $zip = new \ZipArchive();

            if ($zip->open($zip_file, \ZipArchive::CREATE) === true) {
                foreach ($pdf_files as $file) {
                    $zip->addFile($file, basename($file));
                }
                $zip->close();

                $downloaded = File::sendDownload($zip_file, 'invoices.zip', 'application/zip');

                // Cleanup
                TempDir::remove($zip_file);
                foreach ($pdf_files as $file) {
                    TempDir::remove($file);
                }

                if ($downloaded === false) {
                    if (! headers_sent()) {
                        status_header(500);
                        wp_die(esc_html__('Failed to download invoice archive.', 'storeinvoice-print-pdf-invoices-and-packing-slips'));
                    }
                    exit;
                }
                exit;
            }
        }

        return $redirect_to;
    }
}
