<?php

namespace Storeplugin\PDFInvoice\App\Integrations;

defined('ABSPATH') || exit;

use Storeplugin\PDFInvoice\App\Contracts\WooHookableInterface;
use Storeplugin\PDFInvoice\App\Integrations\PdfDocumentGenerator;
use Storeplugin\PDFInvoice\App\Utils;

class WooCommerceFrontendIntegration implements WooHookableInterface {
    public function init(): void {
        // Add invoice link to My Account > Orders
        add_filter('woocommerce_my_account_my_orders_actions', [$this, 'add_invoice_action'], 10, 2);

        // Handle frontend invoice request
        add_action('init', [$this, 'handle_invoice_request']);

        // Add invoice link to order details page
        add_action('woocommerce_order_details_after_order_table', [$this, 'add_invoice_link_to_order']);
    }

    public function add_invoice_action($actions, $order) {
        $access_mode = (string) Utils::getOption('customer_print_access', Utils::GROUP_SETTINGS);

        if ($access_mode === 'disabled') {
            return $actions;
        }

        $actions['invoice'] = [
            'url' => $this->get_invoice_url($order),
            'name' => __('Invoice', 'storeinvoice-print-pdf-invoices-and-packing-slips'),
        ];

        return $actions;
    }

    public function add_invoice_link_to_order($order) {
        $access_mode = (string) Utils::getOption('customer_print_access', Utils::GROUP_SETTINGS);

        if ($access_mode === 'disabled') {
            return;
        }

        $url = $this->get_invoice_url($order);
        ?>
        <p class="nxts-invoice-link">
            <a href="<?php echo esc_url($url); ?>" class="button" target="_blank">
                <?php esc_html_e('Download Invoice', 'storeinvoice-print-pdf-invoices-and-packing-slips'); ?>
            </a>
        </p>
        <?php
    }

    public function get_invoice_url($order, $action = 'view') {
        $access_mode = (string) Utils::getOption('customer_print_access', Utils::GROUP_SETTINGS);

        $args = ['nxts_invoice' => $order->get_id()];

        if ($access_mode === 'guest_token') {
            $args['token'] = $this->generate_order_token($order);
        }

        if ($action === 'download') {
            $args['nxts_action'] = 'download';
        }

        return add_query_arg($args, home_url('/'));
    }

    public function handle_invoice_request() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Access control is handled separately based on settings
        if (!isset($_GET['nxts_invoice'])) {
            return;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Access control is handled separately based on settings
        $order_id = absint($_GET['nxts_invoice']);
        $order = wc_get_order($order_id);

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

        $access_mode = (string) Utils::getOption('customer_print_access', Utils::GROUP_SETTINGS);

        if ($access_mode === 'disabled') {
            wp_die(esc_html__('Invoice access is disabled.', 'storeinvoice-print-pdf-invoices-and-packing-slips'));
        }

        // Verify access
        if (!$this->verify_access($order, $access_mode)) {
            wp_die(esc_html__('You do not have permission to view this invoice.', 'storeinvoice-print-pdf-invoices-and-packing-slips'));
        }

        // Generate and output PDF
        $generator = new PdfDocumentGenerator();
        $result = $generator->generate_order_pdf($order_id);

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

        $filename = $generator->get_pdf_filename([
            'order_number' => $order->get_order_number(),
            'invoice_number' => $generator->get_invoice_number($order),
        ]);

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Access control is handled separately based on settings
        $dest = isset($_GET['nxts_action']) && $_GET['nxts_action'] === 'download' ? 'D' : 'I';
        $generator->output($filename, $dest);
        exit;
    }

    private function verify_access($order, $access_mode) {
        // Admin always has access
        if (current_user_can('edit_shop_orders')) {
            return true;
        }

        if ($access_mode === 'logged_in') {
            return is_user_logged_in() &&
                get_current_user_id() === $order->get_customer_id();
        }

        if ($access_mode === 'guest_token') {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Access control is handled separately based on settings
            $token = isset($_GET['token']) ? sanitize_text_field(wp_unslash($_GET['token'])) : '';
            return $this->verify_order_token($order, $token);
        }

        return false;
    }

    private function generate_order_token($order) {
        $data = $order->get_id() . '|' . $order->get_order_key();
        return hash_hmac('sha256', $data, wp_salt('auth'));
    }

    private function verify_order_token($order, $token) {
        $expected = $this->generate_order_token($order);
        return hash_equals($expected, $token);
    }
}
