<?php
/**
 * Plugin Name: Falkemit E-Invoice for XRechnung
 * Description: Erstellt automatisch XRechnung XML (EN 16931 / XRechnung 3.0) und ZUGFeRD-PDFs für Online-Shop-Bestellungen. DSGVO-konform, 100% lokal, kein Abo.
 * Version: 2.0.1
 * Author: Mehmet Sahin
 * WC requires at least: 7.0
 * Requires PHP: 8.0
 * Text Domain: falkemit-einvoice-xrechnung
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 */

if (!defined('ABSPATH')) exit;

define('FMEXR_VERSION', '2.0.1');
define('FMEXR_DIR', plugin_dir_path(__FILE__));
define('FMEXR_URL', plugin_dir_url(__FILE__));

// Load bundled libraries (mPDF for professional ZUGFeRD PDFs) if present
if (file_exists(FMEXR_DIR . 'vendor/autoload.php')) {
    require_once FMEXR_DIR . 'vendor/autoload.php';
}

// ── Helpers ───────────────────────────────────────────────────────────────────
function fmexr_esc(string $s): string {
    return htmlspecialchars($s, ENT_XML1 | ENT_QUOTES, 'UTF-8');
}

function fmexr_file_path(int $order_id): string {
    $dir = wp_upload_dir()['basedir'] . '/xrechnung/';
    if (!file_exists($dir)) wp_mkdir_p($dir);
    return $dir . 'xrechnung-' . $order_id . '.xml';
}

function fmexr_opt(string $key, string $default = ''): string {
    return (string) get_option('fmexr_' . $key, $default);
}

// ── XML Generator ─────────────────────────────────────────────────────────────
function fmexr_generate(WC_Order $order): string {
    $oid      = $order->get_id();
    $inv_num  = fmexr_opt('inv_prefix', 'RE') . '-' . str_pad($oid, 5, '0', STR_PAD_LEFT);
    $inv_date = $order->get_date_created()->format('Y-m-d');
    $due_date = date('Y-m-d', strtotime($inv_date . ' +' . (int)fmexr_opt('payment_days', '30') . ' days'));
    $currency = get_woocommerce_currency();

    // Seller
    $sn  = fmexr_opt('seller_name',       get_bloginfo('name'));
    $ss  = fmexr_opt('seller_street',     '');
    $sz  = fmexr_opt('seller_zip',        '');
    $sc  = fmexr_opt('seller_city',       '');
    $sco = fmexr_opt('seller_country',    'DE');
    $sv  = fmexr_opt('seller_vat_id',     '');
    $st  = fmexr_opt('seller_tax_number', '');
    $si  = fmexr_opt('seller_iban',       '');
    $sb  = fmexr_opt('seller_bic',        '');
    $se  = fmexr_opt('seller_email',      get_bloginfo('admin_email'));
    $sph = fmexr_opt('seller_phone',      '');

    // Buyer
    $company  = $order->get_billing_company();
    $bn       = $company ?: trim($order->get_billing_first_name() . ' ' . $order->get_billing_last_name());
    $bst      = trim($order->get_billing_address_1() . ' ' . $order->get_billing_address_2());
    $bz       = $order->get_billing_postcode();
    $bc       = $order->get_billing_city();
    $bco      = $order->get_billing_country() ?: 'DE';
    $be       = $order->get_billing_email();
    $bph      = $order->get_billing_phone();
    $b_vat    = get_post_meta($oid, '_billing_vat_id', true);
    $b_lei    = get_post_meta($oid, '_billing_leitweg_id', true) ?: fmexr_opt('default_leitweg', 'N/A');

    // Amounts
    $net   = round((float)$order->get_subtotal() - (float)$order->get_discount_total(), 2);
    $tax   = round((float)$order->get_total_tax(), 2);
    $gross = round((float)$order->get_total(), 2);
    $vrate = ($net > 0 && $tax > 0) ? round($tax / $net * 100, 1) : 0.0;
    $tc    = $tax > 0 ? 'S' : 'Z';

    // Lines
    $lines = '';
    $i = 1;
    foreach ($order->get_items() as $item) {
        $qty  = $item->get_quantity();
        $ln   = round((float)$item->get_subtotal(), 2);
        $ltax = round((float)$item->get_subtotal_tax(), 2);
        $up   = $qty > 0 ? round($ln / $qty, 4) : 0;
        $iv   = ($ln > 0 && $ltax > 0) ? round($ltax / $ln * 100, 1) : $vrate;
        $itc  = $ltax > 0 ? 'S' : ($tax > 0 ? 'S' : 'Z');
        $nm   = fmexr_esc($item->get_name());

        $prod = $item->get_product();
        $sku  = $prod ? fmexr_esc($prod->get_sku()) : '';
        $desc = $prod ? fmexr_esc(wp_strip_all_tags($prod->get_short_description())) : '';

        $lines .= "  <cac:InvoiceLine>
    <cbc:ID>{$i}</cbc:ID>
    <cbc:InvoicedQuantity unitCode=\"C62\">{$qty}</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID=\"{$currency}\">{$ln}</cbc:LineExtensionAmount>" .
    ($desc ? "\n    <cbc:Note>" . fmexr_esc(mb_substr($desc, 0, 500)) . "</cbc:Note>" : '') . "
    <cac:Item>
      <cbc:Name>{$nm}</cbc:Name>" .
      ($sku ? "\n      <cac:SellersItemIdentification><cbc:ID>{$sku}</cbc:ID></cac:SellersItemIdentification>" : '') . "
      <cac:ClassifiedTaxCategory>
        <cbc:ID>{$itc}</cbc:ID>
        <cbc:Percent>{$iv}</cbc:Percent>
        <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
      </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID=\"{$currency}\">{$up}</cbc:PriceAmount>
    </cac:Price>
  </cac:InvoiceLine>\n";
        $i++;
    }

    // Shipping line
    $ship_total = (float)$order->get_shipping_total();
    if ($ship_total > 0) {
        $sn2  = round($ship_total, 2);
        $stax = round((float)$order->get_shipping_tax(), 2);
        $sv2  = ($sn2 > 0 && $stax > 0) ? round($stax / $sn2 * 100, 1) : 0.0;
        $stc  = $stax > 0 ? 'S' : 'Z';
        $lines .= "  <cac:InvoiceLine>
    <cbc:ID>{$i}</cbc:ID>
    <cbc:InvoicedQuantity unitCode=\"C62\">1</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID=\"{$currency}\">{$sn2}</cbc:LineExtensionAmount>
    <cac:Item>
      <cbc:Name>Versandkosten</cbc:Name>
      <cac:ClassifiedTaxCategory>
        <cbc:ID>{$stc}</cbc:ID>
        <cbc:Percent>{$sv2}</cbc:Percent>
        <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
      </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price><cbc:PriceAmount currencyID=\"{$currency}\">{$sn2}</cbc:PriceAmount></cac:Price>
  </cac:InvoiceLine>\n";
    }

    // Coupon as negative line
    $discount = (float)$order->get_discount_total();
    if ($discount > 0) {
        $disc = round(-$discount, 2);
        $lines .= "  <cac:InvoiceLine>
    <cbc:ID>{$i}</cbc:ID>
    <cbc:InvoicedQuantity unitCode=\"C62\">1</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID=\"{$currency}\">{$disc}</cbc:LineExtensionAmount>
    <cac:Item>
      <cbc:Name>Rabatt / Gutschein</cbc:Name>
      <cac:ClassifiedTaxCategory>
        <cbc:ID>{$tc}</cbc:ID><cbc:Percent>{$vrate}</cbc:Percent>
        <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
      </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price><cbc:PriceAmount currencyID=\"{$currency}\">{$disc}</cbc:PriceAmount></cac:Price>
  </cac:InvoiceLine>\n";
    }

    $payment_xml = $si ? "
  <cac:PaymentMeans>
    <cbc:PaymentMeansCode>58</cbc:PaymentMeansCode>
    <cbc:PaymentID>" . fmexr_esc($inv_num) . "</cbc:PaymentID>
    <cac:PayeeFinancialAccount>
      <cbc:ID>" . fmexr_esc($si) . "</cbc:ID>" .
      ($sb ? "<cac:FinancialInstitutionBranch><cbc:ID>" . fmexr_esc($sb) . "</cbc:ID></cac:FinancialInstitutionBranch>" : "") . "
      <cbc:Name>" . fmexr_esc($sn) . "</cbc:Name>
    </cac:PayeeFinancialAccount>
  </cac:PaymentMeans>" : '';

    $pt = fmexr_opt('payment_terms', '');
    $pt_xml = $pt ? "\n  <cac:PaymentTerms><cbc:Note>" . fmexr_esc($pt) . "</cbc:Note></cac:PaymentTerms>" : '';

    return '<?xml version="1.0" encoding="UTF-8"?>
<ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
             xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
             xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
  <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_3.0</cbc:CustomizationID>
  <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
  <cbc:ID>' . fmexr_esc($inv_num) . '</cbc:ID>
  <cbc:IssueDate>' . $inv_date . '</cbc:IssueDate>
  <cbc:DueDate>' . $due_date . '</cbc:DueDate>
  <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
  <cbc:DocumentCurrencyCode>' . fmexr_esc($currency) . '</cbc:DocumentCurrencyCode>
  <cbc:BuyerReference>' . fmexr_esc($b_lei) . '</cbc:BuyerReference>
  <cac:AccountingSupplierParty><cac:Party>
    <cac:PartyName><cbc:Name>' . fmexr_esc($sn) . '</cbc:Name></cac:PartyName>
    <cac:PostalAddress>
      <cbc:StreetName>' . fmexr_esc($ss) . '</cbc:StreetName>
      <cbc:CityName>' . fmexr_esc($sc) . '</cbc:CityName>
      <cbc:PostalZone>' . fmexr_esc($sz) . '</cbc:PostalZone>
      <cac:Country><cbc:IdentificationCode>' . fmexr_esc($sco) . '</cbc:IdentificationCode></cac:Country>
    </cac:PostalAddress>' .
    ($sv ? '<cac:PartyTaxScheme><cbc:CompanyID>' . fmexr_esc($sv) . '</cbc:CompanyID><cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:PartyTaxScheme>' : '') .
    ($st ? '<cac:PartyTaxScheme><cbc:CompanyID>' . fmexr_esc($st) . '</cbc:CompanyID><cac:TaxScheme><cbc:ID>FC</cbc:ID></cac:TaxScheme></cac:PartyTaxScheme>' : '') . '
    <cac:PartyLegalEntity><cbc:RegistrationName>' . fmexr_esc($sn) . '</cbc:RegistrationName></cac:PartyLegalEntity>
    <cac:Contact>
      <cbc:ElectronicMail>' . fmexr_esc($se) . '</cbc:ElectronicMail>' .
      ($sph ? '<cbc:Telephone>' . fmexr_esc($sph) . '</cbc:Telephone>' : '') . '
    </cac:Contact>
  </cac:Party></cac:AccountingSupplierParty>
  <cac:AccountingCustomerParty><cac:Party>
    <cac:PartyName><cbc:Name>' . fmexr_esc($bn) . '</cbc:Name></cac:PartyName>
    <cac:PostalAddress>
      <cbc:StreetName>' . fmexr_esc($bst) . '</cbc:StreetName>
      <cbc:CityName>' . fmexr_esc($bc) . '</cbc:CityName>
      <cbc:PostalZone>' . fmexr_esc($bz) . '</cbc:PostalZone>
      <cac:Country><cbc:IdentificationCode>' . fmexr_esc($bco) . '</cbc:IdentificationCode></cac:Country>
    </cac:PostalAddress>' .
    ($b_vat ? '<cac:PartyTaxScheme><cbc:CompanyID>' . fmexr_esc($b_vat) . '</cbc:CompanyID><cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:PartyTaxScheme>' : '') . '
    <cac:PartyLegalEntity><cbc:RegistrationName>' . fmexr_esc($bn) . '</cbc:RegistrationName></cac:PartyLegalEntity>
    <cac:Contact>
      <cbc:ElectronicMail>' . fmexr_esc($be) . '</cbc:ElectronicMail>' .
      ($bph ? '<cbc:Telephone>' . fmexr_esc($bph) . '</cbc:Telephone>' : '') . '
    </cac:Contact>
  </cac:Party></cac:AccountingCustomerParty>' .
  $payment_xml . $pt_xml . '
  <cac:TaxTotal>
    <cbc:TaxAmount currencyID="' . $currency . '">' . number_format($tax, 2, '.', '') . '</cbc:TaxAmount>
    <cac:TaxSubtotal>
      <cbc:TaxableAmount currencyID="' . $currency . '">' . number_format($net, 2, '.', '') . '</cbc:TaxableAmount>
      <cbc:TaxAmount currencyID="' . $currency . '">' . number_format($tax, 2, '.', '') . '</cbc:TaxAmount>
      <cac:TaxCategory>
        <cbc:ID>' . $tc . '</cbc:ID>
        <cbc:Percent>' . number_format($vrate, 1, '.', '') . '</cbc:Percent>
        <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
      </cac:TaxCategory>
    </cac:TaxSubtotal>
  </cac:TaxTotal>
  <cac:LegalMonetaryTotal>
    <cbc:LineExtensionAmount currencyID="' . $currency . '">' . number_format($net, 2, '.', '') . '</cbc:LineExtensionAmount>
    <cbc:TaxExclusiveAmount currencyID="' . $currency . '">' . number_format($net, 2, '.', '') . '</cbc:TaxExclusiveAmount>
    <cbc:TaxInclusiveAmount currencyID="' . $currency . '">' . number_format($gross, 2, '.', '') . '</cbc:TaxInclusiveAmount>
    <cbc:PayableAmount currencyID="' . $currency . '">' . number_format($gross, 2, '.', '') . '</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>
' . $lines . '</ubl:Invoice>';
}

function fmexr_save(int $order_id): bool {
    $order = wc_get_order($order_id);
    if (!$order) return false;

    // Validate required seller fields
    if (!fmexr_opt('seller_vat_id') && !fmexr_opt('seller_tax_number')) {
        $order->add_order_note('⚠️ XRechnung: USt-IdNr. oder Steuernummer fehlt in den Einstellungen!');
        return false;
    }

    try {
        $xml = fmexr_generate($order);
        update_post_meta($order_id, '_fmexr_xml', $xml);
        update_post_meta($order_id, '_fmexr_generated_at', current_time('mysql'));
        update_post_meta($order_id, '_fmexr_inv_num',
            fmexr_opt('inv_prefix', 'RE') . '-' . str_pad($order_id, 5, '0', STR_PAD_LEFT));
        file_put_contents(fmexr_file_path($order_id), $xml);
        return true;
    } catch (Throwable $e) {
        $order->add_order_note('❌ XRechnung Fehler: ' . $e->getMessage());
        return false;
    }
}

// ── Hooks (only when WooCommerce active) ──────────────────────────────────────
add_action('plugins_loaded', function () {
    if (!class_exists('WooCommerce')) return;

    // Auto-generate on completed
    add_action('woocommerce_order_status_completed', function (int $oid) {
        if (!get_post_meta($oid, '_fmexr_xml', true)) {
            if (fmexr_save($oid)) {
                wc_get_order($oid)->add_order_note('✅ XRechnung XML automatisch erstellt (RE-' . str_pad($oid, 5, '0', STR_PAD_LEFT) . ').');
            }
        }
    });

    // Auto-generate on processing (optional)
    add_action('woocommerce_order_status_processing', function (int $oid) {
        if (fmexr_opt('auto_processing') === 'yes' && !get_post_meta($oid, '_fmexr_xml', true)) {
            fmexr_save($oid);
        }
    });

    // Email attachment
    add_filter('woocommerce_email_attachments', function (array $attachments, string $email_id, $order) {
        if (!is_a($order, 'WC_Order')) return $attachments;
        if (fmexr_opt('attach_email', 'yes') !== 'yes') return $attachments;
        $allowed = ['customer_completed_order', 'customer_processing_order', 'customer_invoice'];
        if (!in_array($email_id, $allowed)) return $attachments;
        $file = fmexr_file_path($order->get_id());
        if (file_exists($file)) $attachments[] = $file;
        return $attachments;
    }, 10, 3);

    // ── Checkout fields: USt-IdNr + Leitweg-ID ────────────────────────────────
    add_filter('woocommerce_billing_fields', function (array $fields) {
        $fields['billing_vat_id'] = [
            'label'       => 'USt-IdNr. (optional)',
            'placeholder' => 'DE123456789',
            'required'    => false,
            'class'       => ['form-row-wide'],
            'priority'    => 31,
        ];
        if (fmexr_opt('show_leitweg', 'no') === 'yes') {
            $fields['billing_leitweg_id'] = [
                'label'       => 'Leitweg-ID (für Behörden)',
                'placeholder' => '991-12345678-06',
                'required'    => false,
                'class'       => ['form-row-wide'],
                'priority'    => 32,
            ];
        }
        return $fields;
    });

    // Save checkout fields
    add_action('woocommerce_checkout_update_order_meta', function (int $oid) {
        if (!empty($_POST['billing_vat_id']))
            update_post_meta($oid, '_billing_vat_id', sanitize_text_field($_POST['billing_vat_id']));
        if (!empty($_POST['billing_leitweg_id']))
            update_post_meta($oid, '_billing_leitweg_id', sanitize_text_field($_POST['billing_leitweg_id']));
    });

    // Show in order admin
    add_action('woocommerce_admin_order_data_after_billing_address', function (WC_Order $order) {
        $vat = get_post_meta($order->get_id(), '_billing_vat_id', true);
        $lei = get_post_meta($order->get_id(), '_billing_leitweg_id', true);
        if ($vat) echo '<p><strong>USt-IdNr.:</strong> ' . esc_html($vat) . '</p>';
        if ($lei) echo '<p><strong>Leitweg-ID:</strong> ' . esc_html($lei) . '</p>';
    });

    // ── Customer account: XRechnung download ──────────────────────────────────
    // (Replaced below by the combined PDF+XML download block; kept hook registration only.)

    // Customer download AJAX
    add_action('wp_ajax_fmexr_customer_download', 'fmexr_customer_download');
    add_action('wp_ajax_nopriv_fmexr_customer_download', 'fmexr_customer_download');

    // ── Admin meta box ────────────────────────────────────────────────────────
    add_action('add_meta_boxes', function () {
        foreach (['shop_order', 'woocommerce_page_wc-orders'] as $screen) {
            add_meta_box('fmexr_box', '⚡ XRechnung', 'fmexr_meta_box', $screen, 'side', 'high');
        }
    });

    // ── Admin menu ────────────────────────────────────────────────────────────
    add_action('admin_menu', function () {
        add_submenu_page('woocommerce', 'XRechnung Einstellungen', '⚡ XRechnung',
            'manage_woocommerce', 'fmexr-settings', 'fmexr_settings_page');
    });

    add_action('admin_init', 'fmexr_register_settings');

    // Load WordPress media library + our settings page script (for logo upload)
    add_action('admin_enqueue_scripts', function ($hook) {
        $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
        if ($page !== 'fmexr-settings') {
            return;
        }

        wp_enqueue_media();

        wp_register_script(
            'fmexr-admin-settings',
            FMEXR_URL . 'assets/js/admin-settings.js',
            ['jquery'],
            FMEXR_VERSION,
            true
        );
        wp_localize_script('fmexr-admin-settings', 'fmexrAdminSettings', [
            'mediaTitle'  => __('Logo auswählen', 'falkemit-einvoice-xrechnung'),
            'mediaButton' => __('Logo verwenden', 'falkemit-einvoice-xrechnung'),
        ]);
        wp_enqueue_script('fmexr-admin-settings');
    });

    // ── AJAX: Admin generate ──────────────────────────────────────────────────
    add_action('wp_ajax_fmexr_gen', function () {
        $oid = intval($_GET['order_id'] ?? 0);
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'xr_gen_' . $oid)) wp_die('Nonce failed');
        if (!current_user_can('manage_woocommerce')) wp_die('No permission');
        delete_post_meta($oid, '_fmexr_xml');
        $ok = fmexr_save($oid);
        if ($ok) wc_get_order($oid)->add_order_note('✅ XRechnung manuell erstellt.');
        wp_redirect(admin_url('post.php?post=' . $oid . '&action=edit'));
        exit;
    });

    add_action('wp_ajax_fmexr_regen', function () {
        $oid = intval($_GET['order_id'] ?? 0);
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'xr_regen_' . $oid)) wp_die('Nonce failed');
        if (!current_user_can('manage_woocommerce')) wp_die('No permission');
        delete_post_meta($oid, '_fmexr_xml');
        fmexr_save($oid);
        wc_get_order($oid)->add_order_note('🔄 XRechnung neu generiert.');
        wp_redirect(admin_url('post.php?post=' . $oid . '&action=edit'));
        exit;
    });

    add_action('wp_ajax_fmexr_download', function () {
        $oid = intval($_GET['order_id'] ?? 0);
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'xr_dl_' . $oid)) wp_die('Nonce failed');
        if (!current_user_can('manage_woocommerce')) wp_die('No permission');
        $xml = get_post_meta($oid, '_fmexr_xml', true) ?: @file_get_contents(fmexr_file_path($oid));
        if (!$xml) wp_die('Not found');
        $inv = get_post_meta($oid, '_fmexr_inv_num', true) ?: 'xrechnung-' . $oid;
        header('Content-Type: application/xml; charset=UTF-8');
        header('Content-Disposition: attachment; filename="' . sanitize_file_name($inv) . '.xml"');
        echo $xml; exit;
    });
});

// ── Customer download (outside plugins_loaded for nopriv) ─────────────────────
function fmexr_customer_download() {
    $oid   = intval($_GET['order_id'] ?? 0);
    $token = sanitize_text_field(wp_unslash($_GET['token'] ?? ''));

    $order = wc_get_order($oid);
    if (!$order) wp_die('Bestellung nicht gefunden.');

    // Nonce is bound to the order's unique key, not just the numeric ID,
    // so it cannot be replayed against a different order even if guessed.
    if (!wp_verify_nonce($token, 'xr_customer_' . $oid . '_' . $order->get_order_key())) {
        wp_die('Ungültiger oder abgelaufener Link.');
    }

    // Logged-in user must own the order
    if (is_user_logged_in()) {
        if ($order->get_customer_id() && $order->get_customer_id() !== get_current_user_id()) {
            wp_die('Keine Berechtigung.');
        }
    } else {
        // Guest checkout: require the WooCommerce order key (not guessable, sent only
        // to the customer), instead of an email address which is trivially known/forwardable.
        $key = sanitize_text_field($_GET['order_key'] ?? '');
        if (!hash_equals($order->get_order_key(), $key)) wp_die('Keine Berechtigung.');
    }

    $xml = get_post_meta($oid, '_fmexr_xml', true) ?: @file_get_contents(fmexr_file_path($oid));
    if (!$xml) wp_die('XRechnung nicht verfügbar.');

    $inv = get_post_meta($oid, '_fmexr_inv_num', true) ?: 'xrechnung-' . $oid;
    header('Content-Type: application/xml; charset=UTF-8');
    header('Content-Disposition: attachment; filename="' . sanitize_file_name($inv) . '.xml"');
    echo $xml; exit;
}

// ── Admin meta box ────────────────────────────────────────────────────────────
function fmexr_meta_box($post_or_order) {
    $oid      = is_a($post_or_order, 'WC_Order') ? $post_or_order->get_id() : $post_or_order->ID;
    $xml      = get_post_meta($oid, '_fmexr_xml', true);
    $gen_at   = get_post_meta($oid, '_fmexr_generated_at', true);
    $inv_num  = get_post_meta($oid, '_fmexr_inv_num', true);

    echo '<div style="font-size:13px;line-height:1.5">';

    if (!fmexr_opt('seller_vat_id') && !fmexr_opt('seller_tax_number')) {
        echo '<div style="background:#fef2f2;border:1px solid #fecaca;border-radius:6px;padding:10px;margin-bottom:10px;font-size:12px">';
        echo '⚠️ <b>Einstellungen unvollständig!</b><br>USt-IdNr. oder Steuernummer fehlt.';
        echo ' <a href="' . esc_url(admin_url('admin.php?page=fmexr-settings')) . '">→ Jetzt einrichten</a>';
        echo '</div>';
    }

    if ($xml) {
        echo '<div style="background:#f0fdf4;border:1px solid #bbf7d0;border-radius:6px;padding:10px;margin-bottom:10px">';
        echo '<b style="color:#166534">✅ XRechnung erstellt</b>';
        if ($inv_num) echo '<br><span style="font-size:11px;color:#64748b">Nr: ' . esc_html($inv_num) . '</span>';
        if ($gen_at)  echo '<br><span style="font-size:11px;color:#64748b">am ' . esc_html($gen_at) . '</span>';
        echo '</div>';

        $dl_url  = wp_nonce_url(admin_url('admin-ajax.php?action=fmexr_download&order_id=' . $oid), 'xr_dl_' . $oid);
        $pdf_url = wp_nonce_url(admin_url('admin-ajax.php?action=fmexr_pdf&order_id=' . $oid), 'xr_pdf_' . $oid);
        $rg_url  = wp_nonce_url(admin_url('admin-ajax.php?action=fmexr_regen&order_id=' . $oid), 'xr_regen_' . $oid);
        echo '<a href="' . esc_url($pdf_url) . '" style="display:block;padding:9px;background:#7c3aed;color:#fff;border-radius:6px;text-decoration:none;text-align:center;font-weight:600;margin-bottom:6px">📄 PDF-Rechnung (ZUGFeRD)</a>';
        echo '<a href="' . esc_url($dl_url) . '" style="display:block;padding:7px;background:#1e40af;color:#fff;border-radius:6px;text-decoration:none;text-align:center;font-weight:600;margin-bottom:6px">⬇️ XRechnung XML</a>';
        echo '<a href="' . esc_url($rg_url) . '" style="display:block;padding:7px;background:#f1f5f9;color:#374155;border-radius:6px;text-decoration:none;text-align:center;font-size:12px">🔄 Neu generieren</a>';
    } else {
        echo '<div style="background:#fef9c3;border:1px solid #fde68a;border-radius:6px;padding:10px;margin-bottom:10px">';
        echo '<b style="color:#92400e">⏳ Noch nicht erstellt</b><br>';
        echo '<span style="font-size:11px;color:#64748b">Wird bei Status "Abgeschlossen" automatisch erstellt.</span>';
        echo '</div>';

        $gen_url = wp_nonce_url(admin_url('admin-ajax.php?action=fmexr_gen&order_id=' . $oid), 'xr_gen_' . $oid);
        echo '<a href="' . esc_url($gen_url) . '" style="display:block;padding:9px;background:#1e40af;color:#fff;border-radius:6px;text-decoration:none;text-align:center;font-weight:600">⚡ Jetzt generieren</a>';
    }

    echo '</div>';
}

// ── Settings ──────────────────────────────────────────────────────────────────

// Restricts a value to a fixed allowlist (used for yes/no select fields).
function fmexr_sanitize_yes_no(string $value): string {
    return ($value === 'yes') ? 'yes' : 'no';
}

// Country / Land (ISO 3166-1 alpha-2) — keep only letters, uppercase, max 2 chars.
function fmexr_sanitize_country_code(string $value): string {
    $value = strtoupper(sanitize_text_field($value));
    $value = preg_replace('/[^A-Z]/', '', $value);
    return substr($value, 0, 2);
}

function fmexr_register_settings() {
    // Map each option to the sanitize_callback that actually matches its data type.
    $callbacks = [
        'seller_name'      => 'sanitize_text_field',
        'seller_street'    => 'sanitize_text_field',
        'seller_zip'       => 'sanitize_text_field',
        'seller_city'      => 'sanitize_text_field',
        'seller_country'   => 'fmexr_sanitize_country_code',
        'seller_vat_id'    => 'sanitize_text_field',
        'seller_tax_number'=> 'sanitize_text_field',
        'seller_iban'      => 'sanitize_text_field',
        'seller_bic'       => 'sanitize_text_field',
        'seller_email'     => 'sanitize_email',
        'seller_phone'     => 'sanitize_text_field',
        'inv_prefix'       => 'sanitize_text_field',
        'payment_days'     => 'absint',
        'payment_terms'    => 'sanitize_textarea_field',
        'attach_email'     => 'fmexr_sanitize_yes_no',
        'auto_processing'  => 'fmexr_sanitize_yes_no',
        'show_leitweg'     => 'fmexr_sanitize_yes_no',
        'default_leitweg'  => 'sanitize_text_field',
        'seller_logo'      => 'esc_url_raw',
    ];

    foreach ($callbacks as $option => $cb) {
        register_setting('fmexr_settings', 'fmexr_' . $option, [
            'type'              => 'string',
            'sanitize_callback' => $cb,
        ]);
    }
}

function fmexr_settings_page() {
    if (!current_user_can('manage_woocommerce')) return;
    $saved = isset($_GET['settings-updated']);
    ?>
    <div class="wrap">
        <h1 style="display:flex;align-items:center;gap:8px">⚡ Falkemit E-Invoice <span style="font-size:13px;background:#e2e8f0;color:#64748b;padding:3px 10px;border-radius:20px;font-weight:normal">v<?php echo esc_html(FMEXR_VERSION) ?></span></h1>

        <?php if ($saved): ?>
            <div class="notice notice-success is-dismissible"><p>✅ Einstellungen erfolgreich gespeichert!</p></div>
        <?php endif; ?>

        <?php if (!fmexr_opt('seller_vat_id') && !fmexr_opt('seller_tax_number')): ?>
            <div class="notice notice-error"><p>⚠️ <strong>Pflichtfeld fehlt:</strong> Bitte USt-IdNr. oder Steuernummer eingeben (Pflicht für gültige XRechnungen nach BR-CO-9).</p></div>
        <?php endif; ?>

        <form method="post" action="options.php" style="margin-top:16px">
            <?php settings_fields('fmexr_settings'); ?>

            <div style="display:grid;grid-template-columns:1fr 1fr;gap:24px;max-width:1000px">

                <!-- Verkäufer -->
                <div style="background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:24px">
                    <h2 style="font-size:15px;font-weight:700;margin:0 0 4px;color:#0f172a">🏢 Ihre Firmendaten</h2>
                    <p style="font-size:12px;color:#64748b;margin:0 0 16px">Erscheinen auf jeder XRechnung als Aussteller</p>
                    <div style="height:1px;background:#e2e8f0;margin-bottom:16px"></div>

                    <!-- Logo Upload -->
                    <div style="margin-bottom:16px">
                        <label style="display:block;font-size:13px;font-weight:600;color:#334155;margin-bottom:6px">Firmenlogo</label>
                        <?php $fmexr_logo = fmexr_opt('seller_logo', ''); ?>
                        <div style="display:flex;align-items:center;gap:12px">
                            <img id="fmexr_logo_preview" src="<?php echo esc_url($fmexr_logo); ?>"
                                 style="max-height:50px;max-width:140px;<?php echo $fmexr_logo ? '' : 'display:none;'; ?>border:1px solid #e2e8f0;border-radius:6px;padding:4px;background:#fff" />
                            <button type="button" class="button" id="fmexr_logo_btn">Logo auswählen</button>
                            <button type="button" class="button" id="fmexr_logo_remove" style="<?php echo $fmexr_logo ? '' : 'display:none;'; ?>">Entfernen</button>
                        </div>
                        <input type="hidden" name="fmexr_seller_logo" id="fmexr_seller_logo" value="<?php echo esc_attr($fmexr_logo); ?>" />
                        <p style="font-size:11px;color:#94a3b8;margin:6px 0 0">Erscheint oben auf der PDF-Rechnung. Empfohlen: PNG, max. 200×60 px.</p>
                    </div>
                    <?php
                    fmexr_field('Firmenname *', 'seller_name', get_bloginfo('name'), 'Musterfirma GmbH');
                    fmexr_field('Straße & Hausnummer *', 'seller_street', '', 'Musterstraße 1');
                    fmexr_field('PLZ *', 'seller_zip', '', '10115');
                    fmexr_field('Stadt *', 'seller_city', '', 'Berlin');
                    fmexr_field('Land (ISO 3166)', 'seller_country', 'DE', 'DE');
                    fmexr_field('USt-IdNr. (DE...) *', 'seller_vat_id', '', 'DE123456789',
                        '⚠️ Pflicht: USt-IdNr. ODER Steuernummer (BR-CO-9)');
                    fmexr_field('Steuernummer', 'seller_tax_number', '', '123/456/78901');
                    fmexr_field('IBAN', 'seller_iban', '', 'DE89370400440532013000',
                        'Für Zahlungsanweisung (PaymentMeans)');
                    fmexr_field('BIC / SWIFT', 'seller_bic', '', 'COBADEFFXXX');
                    fmexr_field('E-Mail *', 'seller_email', get_bloginfo('admin_email'), 'info@firma.de');
                    fmexr_field('Telefon', 'seller_phone', '', '+49 30 123456');
                    ?>
                </div>

                <div>
                    <!-- Rechnungseinstellungen -->
                    <div style="background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:24px;margin-bottom:20px">
                        <h2 style="font-size:15px;font-weight:700;margin:0 0 4px;color:#0f172a">⚙️ Rechnungseinstellungen</h2>
                        <p style="font-size:12px;color:#64748b;margin:0 0 16px">Nummern, Fristen & Konditionen</p>
                        <div style="height:1px;background:#e2e8f0;margin-bottom:16px"></div>
                        <?php
                        fmexr_field('Rechnungs-Präfix', 'inv_prefix', 'RE', 'RE',
                            'z.B. "RE" → RE-00015');
                        fmexr_field('Zahlungsziel (Tage)', 'payment_days', '30', '30',
                            'Fälligkeitsdatum = Rechnungsdatum + X Tage');
                        fmexr_field('Zahlungsbedingungen (optional)', 'payment_terms', '',
                            'Zahlbar innerhalb 30 Tagen ohne Abzug',
                            'Erscheint als Freitext in der XRechnung');
                        fmexr_field('Standard Leitweg-ID', 'default_leitweg', 'N/A', 'N/A',
                            'Fallback wenn Kunde keine eingibt (N/A für B2B)');
                        ?>

                        <div style="margin-bottom:14px">
                            <label style="display:block;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#374151;margin-bottom:5px">XML per E-Mail anhängen</label>
                            <select name="fmexr_attach_email" style="width:100%;padding:9px 10px;border:1.5px solid #e2e8f0;border-radius:7px;font-size:13px;background:#fff">
                                <option value="yes" <?php selected(fmexr_opt('attach_email','yes'),'yes') ?>>✅ Ja — automatisch an Kunden-E-Mail</option>
                                <option value="no"  <?php selected(fmexr_opt('attach_email','yes'),'no')  ?>>❌ Nein</option>
                            </select>
                        </div>

                        <div style="margin-bottom:14px">
                            <label style="display:block;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#374151;margin-bottom:5px">Bei "In Bearbeitung" erstellen</label>
                            <select name="fmexr_auto_processing" style="width:100%;padding:9px 10px;border:1.5px solid #e2e8f0;border-radius:7px;font-size:13px;background:#fff">
                                <option value="no"  <?php selected(fmexr_opt('auto_processing','no'),'no')  ?>>Nein — nur bei "Abgeschlossen"</option>
                                <option value="yes" <?php selected(fmexr_opt('auto_processing','no'),'yes') ?>>Ja — auch bei "In Bearbeitung"</option>
                            </select>
                        </div>

                        <div style="margin-bottom:14px">
                            <label style="display:block;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#374151;margin-bottom:5px">Leitweg-ID Feld im Checkout</label>
                            <select name="fmexr_show_leitweg" style="width:100%;padding:9px 10px;border:1.5px solid #e2e8f0;border-radius:7px;font-size:13px;background:#fff">
                                <option value="no"  <?php selected(fmexr_opt('show_leitweg','no'),'no')  ?>>Nein — nur B2B (kein Behördenfeld)</option>
                                <option value="yes" <?php selected(fmexr_opt('show_leitweg','no'),'yes') ?>>Ja — B2G (Behörden/öffentliche Hand)</option>
                            </select>
                        </div>
                    </div>

                    <!-- Info -->
                    <div style="background:#eff6ff;border:1px solid #bfdbfe;border-radius:12px;padding:20px">
                        <h3 style="font-size:13px;font-weight:700;color:#1e40af;margin:0 0 12px">📋 Gesetzliche Anforderungen</h3>
                        <ul style="font-size:12px;color:#334155;margin:0;padding-left:16px;line-height:2">
                            <li><b>BR-CO-9:</b> USt-IdNr. ODER Steuernummer Pflicht</li>
                            <li><b>Leitweg-ID:</b> Pflicht für B2G (Behörden)</li>
                            <li><b>XRechnung 3.0</b> (EN 16931) Standard</li>
                            <li><b>Aufbewahrung:</b> 10 Jahre (§14b UStG)</li>
                            <li><b>PDF allein</b> ist <u>keine</u> E-Rechnung</li>
                        </ul>
                        <div style="margin-top:12px;padding:10px;background:#fff;border-radius:6px;font-size:11px;color:#64748b">
                            💡 Seit 27.11.2020 sind E-Rechnungen für B2G Pflicht. Ab 2025 schrittweise auch für B2B.
                        </div>
                    </div>
                </div>
            </div>

            <div style="margin-top:20px;display:flex;align-items:center;gap:12px">
                <?php submit_button('💾 Einstellungen speichern', 'primary', 'submit', false,
                    ['style' => 'padding:10px 28px;font-size:14px;margin:0']) ?>
                <a href="<?php echo esc_url(admin_url('admin.php?page=wc-orders')) ?>"
                   style="padding:10px 20px;background:#f1f5f9;color:#334155;border-radius:6px;text-decoration:none;font-size:13px;font-weight:500">
                    → Bestellungen ansehen
                </a>
            </div>
        </form>
    </div>
    <?php
}

function fmexr_field(string $label, string $key, string $default='', string $ph='', string $hint='') {
    $val = fmexr_opt($key, $default);
    $name = 'fmexr_' . $key;
    echo '<div style="margin-bottom:14px">';
    echo '<label style="display:block;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#374151;margin-bottom:5px">' . esc_html($label) . '</label>';
    echo '<input type="text" name="' . esc_attr($name) . '" value="' . esc_attr($val) . '" placeholder="' . esc_attr($ph) . '" style="width:100%;padding:9px 12px;border:1.5px solid #e2e8f0;border-radius:7px;font-size:13px;font-family:inherit">';
    if ($hint) echo '<p style="font-size:11px;color:#94a3b8;margin:3px 0 0">' . esc_html($hint) . '</p>';
    echo '</div>';
}

// ── Activation / Deactivation ─────────────────────────────────────────────────
register_activation_hook(__FILE__, function () {
    $dir = wp_upload_dir()['basedir'] . '/xrechnung/';
    if (!file_exists($dir)) wp_mkdir_p($dir);
    file_put_contents($dir . '.htaccess', "Options -Indexes\ndeny from all\n");
    file_put_contents($dir . 'index.php', '<?php // Silence is golden');
});

// ═══════════════════════════════════════════════════════════════════════════════
// ZUGFeRD PDF GENERATOR
// Erstellt ein visuelles PDF mit eingebettetem XRechnung XML (ZUGFeRD 2.3)
// Der Kunde sieht ein normales PDF, die XRechnung XML ist unsichtbar eingebettet
// ═══════════════════════════════════════════════════════════════════════════════

function fmexr_generate_zugferd_pdf(WC_Order $order): ?string {
    // Check if TCPDF is available (bundled with many WP plugins or manually installed)
    if (!class_exists('TCPDF')) {
        // Try to load bundled TCPDF
        $tcpdf_paths = [
            FMEXR_DIR . 'lib/tcpdf/tcpdf.php',
        ];
        // Optionally use WooCommerce's bundled TCPDF if available (path-safe)
        if (defined('WC_ABSPATH')) {
            $tcpdf_paths[] = WC_ABSPATH . 'packages/woocommerce-blocks/vendor/tcpdf/tcpdf.php';
        }
        foreach ($tcpdf_paths as $path) {
            if (file_exists($path)) { require_once $path; break; }
        }
    }

    if (!class_exists('TCPDF')) {
        // Fallback: generate PDF with PHP only (no TCPDF)
        return fmexr_generate_simple_pdf($order);
    }

    return fmexr_generate_tcpdf($order);
}

// ── Simple PDF without TCPDF (basic but works) ────────────────────────────────
function fmexr_generate_simple_pdf(WC_Order $order): string {
    $oid      = $order->get_id();
    $inv_num  = fmexr_opt('inv_prefix', 'RE') . '-' . str_pad($oid, 5, '0', STR_PAD_LEFT);
    $inv_date = $order->get_date_created()->format('d.m.Y');
    $due_date = date('d.m.Y', strtotime($order->get_date_created()->format('Y-m-d') . ' +' . (int)fmexr_opt('payment_days', '30') . ' days'));
    $currency = get_woocommerce_currency_symbol();

    $sn = fmexr_opt('seller_name', get_bloginfo('name'));
    $ss = fmexr_opt('seller_street', '');
    $sz = fmexr_opt('seller_zip', '');
    $sc = fmexr_opt('seller_city', '');
    $sv = fmexr_opt('seller_vat_id', '');
    $si = fmexr_opt('seller_iban', '');
    $sb = fmexr_opt('seller_bic', '');
    $se = fmexr_opt('seller_email', '');
    $slogo = fmexr_opt('seller_logo', '');

    $company = $order->get_billing_company();
    $bn = $company ?: trim($order->get_billing_first_name() . ' ' . $order->get_billing_last_name());
    $bst = $order->get_billing_address_1();
    $bz  = $order->get_billing_postcode();
    $bc  = $order->get_billing_city();

    $net   = number_format((float)$order->get_subtotal() - (float)$order->get_discount_total(), 2, ',', '.');
    $tax   = number_format((float)$order->get_total_tax(), 2, ',', '.');
    $gross = number_format((float)$order->get_total(), 2, ',', '.');

    // Get XRechnung XML
    $xml = get_post_meta($oid, '_fmexr_xml', true);
    if (!$xml) $xml = fmexr_generate($order);

    // Build HTML for PDF
    $items_html = '';
    $i = 1;
    foreach ($order->get_items() as $item) {
        $qty   = $item->get_quantity();
        $total = number_format((float)$item->get_subtotal(), 2, ',', '.');
        $up    = number_format($qty > 0 ? (float)$item->get_subtotal() / $qty : 0, 2, ',', '.');
        $bg    = $i % 2 === 0 ? '#f8fafc' : '#ffffff';
        $items_html .= "
        <tr style='background:{$bg}'>
            <td style='padding:8px 10px;border-bottom:1px solid #e2e8f0'>{$i}. " . esc_html($item->get_name()) . "</td>
            <td style='padding:8px 10px;border-bottom:1px solid #e2e8f0;text-align:center'>{$qty}</td>
            <td style='padding:8px 10px;border-bottom:1px solid #e2e8f0;text-align:right'>{$up} {$currency}</td>
            <td style='padding:8px 10px;border-bottom:1px solid #e2e8f0;text-align:right;font-weight:600'>{$total} {$currency}</td>
        </tr>";
        $i++;
    }

    $pt = fmexr_opt('payment_terms', 'Zahlbar innerhalb von ' . fmexr_opt('payment_days', '30') . ' Tagen ohne Abzug.');

    $html = "<!DOCTYPE html>
<html>
<head><meta charset='UTF-8'></head>
<body style='padding:40px;font-family:Arial,sans-serif;font-size:11px;color:#1e293b;margin:0'>

<!-- Header -->
<table width='100%' style='margin-bottom:30px'>
<tr>
<td>
" . ($slogo ? "<img src='" . esc_url($slogo) . "' style='max-height:60px;max-width:200px;margin-bottom:8px' />" : '') . "
<div style='font-size:22px;font-weight:900;color:#0f172a'>" . esc_html($sn) . "</div>
<div style='font-size:11px;color:#64748b;margin-top:4px'>" . esc_html($ss) . " · " . esc_html($sz) . " " . esc_html($sc) . "</div>
" . ($sv ? "<div style='font-size:11px;color:#64748b'>USt-IdNr.: " . esc_html($sv) . "</div>" : '') . "
" . ($se ? "<div style='font-size:11px;color:#64748b'>E-Mail: " . esc_html($se) . "</div>" : '') . "
</td>
<td style='text-align:right'>
<div style='font-size:28px;font-weight:900;color:#1e40af;letter-spacing:-1px'>RECHNUNG</div>
<div style='margin-top:8px;background:#1e40af;color:#fff;padding:8px 16px;border-radius:6px;display:inline-block'>
<div style='font-size:10px;opacity:.7;text-transform:uppercase;letter-spacing:1px'>Rechnungsnummer</div>
<div style='font-size:16px;font-weight:700'>" . esc_html($inv_num) . "</div>
</div>
</td>
</tr>
</table>

<!-- Dates & Buyer -->
<table width='100%' style='margin-bottom:30px'>
<tr>
<td width='50%' style='vertical-align:top'>
<div style='background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:16px'>
<div style='font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:#64748b;margin-bottom:10px'>Rechnungsempfänger</div>
<div style='font-size:13px;font-weight:700;color:#0f172a'>" . esc_html($bn) . "</div>
<div style='color:#64748b;margin-top:4px'>" . esc_html($bst) . "<br>" . esc_html($bz) . " " . esc_html($bc) . "</div>
</div>
</td>
<td width='10%'></td>
<td width='40%' style='vertical-align:top'>
<table width='100%' style='background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:16px'>
<tr><td style='color:#64748b;padding:3px 0'>Rechnungsdatum:</td><td style='text-align:right;font-weight:600'>" . esc_html($inv_date) . "</td></tr>
<tr><td style='color:#64748b;padding:3px 0'>Fälligkeitsdatum:</td><td style='text-align:right;font-weight:600;color:#ef4444'>" . esc_html($due_date) . "</td></tr>
<tr><td style='color:#64748b;padding:3px 0'>Bestellnummer:</td><td style='text-align:right'>#" . esc_html($oid) . "</td></tr>
</table>
</td>
</tr>
</table>

<!-- Items -->
<table width='100%' style='border-collapse:collapse;margin-bottom:20px'>
<thead>
<tr style='background:#0f172a;color:#fff'>
<th style='padding:10px;text-align:left;border-radius:6px 0 0 0'>Beschreibung</th>
<th style='padding:10px;text-align:center'>Menge</th>
<th style='padding:10px;text-align:right'>Einzelpreis</th>
<th style='padding:10px;text-align:right;border-radius:0 6px 0 0'>Betrag</th>
</tr>
</thead>
<tbody>" . $items_html . "</tbody>
</table>

<!-- Totals -->
<table width='100%' style='margin-bottom:30px'>
<tr>
<td width='60%'></td>
<td width='40%'>
<table width='100%' style='background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:16px'>
<tr><td style='padding:4px 10px;color:#64748b'>Nettobetrag:</td><td style='text-align:right;padding:4px 10px'>" . esc_html($net) . " " . esc_html($currency) . "</td></tr>
<tr><td style='padding:4px 10px;color:#64748b'>MwSt.:</td><td style='text-align:right;padding:4px 10px'>" . esc_html($tax) . " " . esc_html($currency) . "</td></tr>
<tr style='border-top:2px solid #1e40af'>
<td style='padding:8px 10px;font-weight:700;font-size:14px;color:#0f172a'>Gesamtbetrag:</td>
<td style='text-align:right;padding:8px 10px;font-weight:900;font-size:16px;color:#1e40af'>" . esc_html($gross) . " " . esc_html($currency) . "</td>
</tr>
</table>
</td>
</tr>
</table>

<!-- Payment -->
" . ($si ? "
<div style='background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:16px;margin-bottom:20px'>
<div style='font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:#166534;margin-bottom:8px'>Bankverbindung</div>
<table>
<tr><td style='color:#166534;padding:2px 16px 2px 0'>Kontoinhaber:</td><td style='font-weight:600'>" . esc_html($sn) . "</td></tr>
<tr><td style='color:#166534;padding:2px 16px 2px 0'>IBAN:</td><td style='font-weight:600;font-family:monospace'>" . esc_html($si) . "</td></tr>
" . ($sb ? "<tr><td style='color:#166534;padding:2px 16px 2px 0'>BIC:</td><td style='font-weight:600;font-family:monospace'>" . esc_html($sb) . "</td></tr>" : '') . "
<tr><td style='color:#166534;padding:2px 16px 2px 0'>Verwendungszweck:</td><td style='font-weight:600'>" . esc_html($inv_num) . "</td></tr>
</table>
</div>" : '') . "

<!-- Payment terms -->
<div style='font-size:11px;color:#64748b;margin-bottom:30px'>" . esc_html($pt) . "</div>

<!-- Fixed page footer (mPDF pins this to the bottom of every page) -->
<htmlpagefooter name='fmexrFooter'>
<div style='border-top:1px solid #e2e8f0;padding-top:12px;font-size:10px;color:#94a3b8;text-align:center'>
<span style='background:#1e40af;color:#fff;padding:2px 8px;border-radius:4px;font-size:9px;font-weight:700;margin-right:8px'>ZUGFeRD 2.3</span>
Diese Rechnung enthält eine eingebettete XRechnung XML-Datei (EN 16931). · " . esc_html($sn) . " · " . esc_html($se) . "
</div>
</htmlpagefooter>
<sethtmlpagefooter name='fmexrFooter' value='on' />

</body></html>";

    // Convert HTML to PDF using WordPress/PHP
    // We embed the XML as a PDF attachment
    $pdf = fmexr_html_to_pdf_with_xml($html, $xml, $inv_num);
    return $pdf;
}

// ── Embed XML into PDF ────────────────────────────────────────────────────────
function fmexr_html_to_pdf_with_xml(string $html, string $xml, string $inv_num): string {
    // Use mPDF if available (popular WordPress PDF library)
    if (class_exists('\Mpdf\Mpdf')) {
        try {
            $mpdf = new \Mpdf\Mpdf(['margin_left'=>15,'margin_right'=>15,'margin_top'=>15,'margin_bottom'=>25,'margin_footer'=>10]);
            $mpdf->SetTitle($inv_num);
            $mpdf->SetAuthor(fmexr_opt('seller_name', get_bloginfo('name')));
            $mpdf->SetCreator('Falkemit E-Invoice for XRechnung');
            // Embed XML as file attachment (ZUGFeRD)
            $mpdf->SetAssociatedFiles([[
                'name'          => 'factur-x.xml',
                'mime'          => 'text/xml',
                'description'   => 'XRechnung',
                'AFRelationship'=> 'Data',
                'content'       => $xml,
            ]]);
            $mpdf->WriteHTML($html);
            return $mpdf->Output('', 'S');
        } catch (\Exception $e) {
            error_log('FMEXR mPDF Error: ' . $e->getMessage());
        }
    }

    // Fallback: return a minimal PDF with XML embedded as comment
    // (not true ZUGFeRD but functional)
    return fmexr_minimal_pdf($html, $xml, $inv_num);
}

// ── Minimal PDF with embedded XML (no library needed) ────────────────────────
function fmexr_minimal_pdf(string $html, string $xml, string $inv_num): string {
    // No external library available: build a valid PDF with VISIBLE content,
    // plus the XRechnung XML embedded as a ZUGFeRD attachment. Pure PHP, no deps.

    // Extract plain text lines from the HTML (strip tags, keep readable content)
    $text = preg_replace('/<(script|style)[^>]*>.*?<\/\1>/is', '', $html);
    $text = preg_replace('/<br\s*\/?>/i', "\n", $text);
    $text = preg_replace('/<\/(tr|div|table|p|h1|h2|h3|td)>/i', "\n", $text);
    $text = html_entity_decode(strip_tags($text), ENT_QUOTES | ENT_HTML5, 'UTF-8');
    // Collapse excess blank lines / whitespace
    $rawlines = preg_split('/\n/', $text);
    $clean = [];
    foreach ($rawlines as $l) {
        $l = trim(preg_replace('/[ \t]+/', ' ', $l));
        if ($l !== '') $clean[] = $l;
    }

    // PDF text helpers (WinAnsi/latin1 — ZUGFeRD viewers read the XML anyway)
    $esc = function(string $s): string {
        // Convert UTF-8 to CP1252 so umlauts render; fall back gracefully
        $conv = @iconv('UTF-8', 'CP1252//TRANSLIT', $s);
        if ($conv === false) $conv = preg_replace('/[^\x20-\x7E]/', '?', $s);
        return str_replace(['\\', '(', ')'], ['\\\\', '\\(', '\\)'], $conv);
    };

    // Build the page content stream: write each line top-to-bottom
    $y = 800;            // start near top (page height 842)
    $leading = 15;
    $content = "BT\n/F1 10 Tf\n40 {$y} Td\n{$leading} TL\n";
    $first = true;
    foreach ($clean as $line) {
        // Wrap very long lines at ~90 chars
        foreach (str_split_unicode($line, 90) as $chunk) {
            if ($y < 50) break 2; // page full — stop (single page invoice)
            if ($first) {
                $content .= '(' . $esc($chunk) . ") Tj\n";
                $first = false;
            } else {
                $content .= 'T* (' . $esc($chunk) . ") Tj\n";
            }
            $y -= $leading;
        }
    }
    $content .= "ET";
    $content_len = strlen($content);

    $date  = 'D:' . date('YmdHis') . "+00'00'";
    $title = $inv_num;
    $xml_len = strlen($xml);

    // Assemble PDF objects
    $pdf = "%PDF-1.7\n%\xE2\xE3\xCF\xD3\n";
    $off = [];

    $off[1] = strlen($pdf);
    $pdf .= "1 0 obj\n<< /Type /Catalog /Pages 2 0 R /Names << /EmbeddedFiles << /Names [(factur-x.xml) 7 0 R] >> >> /AF [7 0 R] >>\nendobj\n";

    $off[2] = strlen($pdf);
    $pdf .= "2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n";

    $off[3] = strlen($pdf);
    $pdf .= "3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 5 0 R >> >> /Contents 4 0 R >>\nendobj\n";

    $off[4] = strlen($pdf);
    $pdf .= "4 0 obj\n<< /Length {$content_len} >>\nstream\n{$content}\nendstream\nendobj\n";

    $off[5] = strlen($pdf);
    $pdf .= "5 0 obj\n<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >>\nendobj\n";

    $title_esc = $esc($title);
    $off[6] = strlen($pdf);
    $pdf .= "6 0 obj\n<< /Title ({$title_esc}) /Creator (Falkemit E-Invoice for XRechnung) /Producer (Falkemit E-Invoice v2.0) /CreationDate ({$date}) >>\nendobj\n";

    // Embedded XML (ZUGFeRD attachment)
    $off[7] = strlen($pdf);
    $pdf .= "7 0 obj\n<< /Type /Filespec /F (factur-x.xml) /UF (factur-x.xml) /EF << /F 8 0 R >> /Desc (XRechnung) /AFRelationship /Data >>\nendobj\n";

    $off[8] = strlen($pdf);
    $pdf .= "8 0 obj\n<< /Type /EmbeddedFile /Subtype /text#2Fxml /Length {$xml_len} >>\nstream\n{$xml}\nendstream\nendobj\n";

    // xref
    $xref_off = strlen($pdf);
    $count = count($off) + 1;
    $pdf .= "xref\n0 {$count}\n0000000000 65535 f \n";
    for ($i = 1; $i < $count; $i++) {
        $pdf .= str_pad($off[$i], 10, '0', STR_PAD_LEFT) . " 00000 n \n";
    }
    $pdf .= "trailer\n<< /Size {$count} /Root 1 0 R /Info 6 0 R >>\nstartxref\n{$xref_off}\n%%EOF";

    return $pdf;
}

// UTF-8 safe str_split helper
if (!function_exists('str_split_unicode')) {
    function str_split_unicode(string $str, int $len = 1): array {
        $arr = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
        if ($len <= 1) return $arr ?: [''];
        $out = [];
        for ($i = 0, $n = count($arr); $i < $n; $i += $len) {
            $out[] = implode('', array_slice($arr, $i, $len));
        }
        return $out ?: [''];
    }
}
// ── Hooks for ZUGFeRD PDF ─────────────────────────────────────────────────────
add_action('plugins_loaded', function() {
    if (!class_exists('WooCommerce')) return;

    // Generate ZUGFeRD PDF when XRechnung is created
    add_action('woocommerce_order_status_completed', function(int $oid) {
        // Small delay to ensure XRechnung XML is already generated
        add_action('shutdown', function() use ($oid) {
            $order = wc_get_order($oid);
            if ($order && !get_post_meta($oid, '_fmexr_pdf_path', true)) {
                fmexr_create_zugferd_pdf($oid);
            }
        });
    }, 20); // priority 20 = after XML generation (priority 10)

    // AJAX: Admin PDF download
    add_action('wp_ajax_fmexr_pdf', function() {
        $oid = intval($_GET['order_id'] ?? 0);
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'xr_pdf_' . $oid)) wp_die('Nonce failed');
        if (!current_user_can('manage_woocommerce')) wp_die('No permission');

        $pdf = fmexr_get_or_create_pdf($oid);
        if (!$pdf) wp_die('PDF konnte nicht erstellt werden.');

        $inv = get_post_meta($oid, '_fmexr_inv_num', true) ?: 'rechnung-' . $oid;
        header('Content-Type: application/pdf');
        header('Content-Disposition: attachment; filename="' . sanitize_file_name($inv) . '.pdf"');
        echo $pdf; exit;
    });

    // AJAX: Customer PDF download
    add_action('wp_ajax_fmexr_customer_pdf', 'fmexr_customer_pdf_download');
    add_action('wp_ajax_nopriv_fmexr_customer_pdf', 'fmexr_customer_pdf_download');

    // Show PDF download in customer order page
    add_action('woocommerce_order_details_after_order_table', function(WC_Order $order) {
        $xml = get_post_meta($order->get_id(), '_fmexr_xml', true);
        if (!$xml) return;

        $oid     = $order->get_id();
        $ord_key = $order->get_order_key();

        $xml_url = add_query_arg([
            'action'    => 'fmexr_customer_download',
            'order_id'  => $oid,
            'order_key' => $ord_key,
            'token'     => wp_create_nonce('xr_customer_' . $oid . '_' . $ord_key),
        ], admin_url('admin-ajax.php'));

        $pdf_url = add_query_arg([
            'action'    => 'fmexr_customer_pdf',
            'order_id'  => $oid,
            'order_key' => $ord_key,
            'token'     => wp_create_nonce('xr_pdf_customer_' . $oid . '_' . $ord_key),
        ], admin_url('admin-ajax.php'));

        echo '<div style="margin:20px 0;padding:20px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px">';
        echo '<h3 style="margin:0 0 6px;font-size:15px;color:#1e40af">📄 Ihre Rechnung</h3>';
        echo '<p style="margin:0 0 14px;font-size:13px;color:#334155">Laden Sie Ihre Rechnung als PDF oder XRechnung XML herunter.</p>';
        echo '<div style="display:flex;gap:10px;flex-wrap:wrap">';

        echo '<a href="' . esc_url($pdf_url) . '" style="display:inline-flex;align-items:center;gap:6px;padding:10px 18px;background:#1e40af;color:#fff;border-radius:7px;text-decoration:none;font-size:13px;font-weight:600">📄 PDF-Rechnung (ZUGFeRD)</a>';

        echo '<a href="' . esc_url($xml_url) . '" style="display:inline-flex;align-items:center;gap:6px;padding:10px 18px;background:#fff;color:#1e40af;border:2px solid #bfdbfe;border-radius:7px;text-decoration:none;font-size:13px;font-weight:600">⚡ XRechnung XML</a>';

        echo '</div>';
        echo '<p style="margin:10px 0 0;font-size:11px;color:#64748b">Die PDF-Rechnung enthält eine eingebettete XRechnung (ZUGFeRD 2.3) für Ihre Buchhaltungssoftware.</p>';
        echo '</div>';
    }, 5);

    // Email: attach PDF instead of XML
    add_filter('woocommerce_email_attachments', function(array $attachments, string $email_id, $order) {
        if (!is_a($order, 'WC_Order')) return $attachments;
        if (fmexr_opt('attach_email', 'yes') !== 'yes') return $attachments;
        if (!in_array($email_id, ['customer_completed_order','customer_processing_order','customer_invoice'])) return $attachments;

        $oid = $order->get_id();
        // Remove XML attachment (from previous filter)
        $xml_file = fmexr_file_path($oid);
        $attachments = array_filter($attachments, fn($a) => $a !== $xml_file);

        // Attach PDF (contains embedded XML)
        $pdf_path = fmexr_get_pdf_path($oid);
        if ($pdf_path && file_exists($pdf_path)) {
            $attachments[] = $pdf_path;
        }
        return array_values($attachments);
    }, 20, 3); // priority 20 = after XML filter
});

function fmexr_get_pdf_path(int $oid): string {
    $dir = wp_upload_dir()['basedir'] . '/xrechnung/';
    return $dir . 'rechnung-' . $oid . '.pdf';
}

function fmexr_get_or_create_pdf(int $oid): ?string {
    $path = fmexr_get_pdf_path($oid);
    if (file_exists($path)) return file_get_contents($path);

    $order = wc_get_order($oid);
    if (!$order) return null;

    return fmexr_create_zugferd_pdf($oid);
}

function fmexr_create_zugferd_pdf(int $oid): ?string {
    $order = wc_get_order($oid);
    if (!$order) return null;

    $pdf = fmexr_generate_zugferd_pdf($order);
    if (!$pdf) return null;

    $path = fmexr_get_pdf_path($oid);
    file_put_contents($path, $pdf);
    update_post_meta($oid, '_fmexr_pdf_path', $path);

    return $pdf;
}

function fmexr_customer_pdf_download() {
    $oid   = intval($_GET['order_id'] ?? 0);
    $token = sanitize_text_field(wp_unslash($_GET['token'] ?? ''));

    $order = wc_get_order($oid);
    if (!$order) wp_die('Bestellung nicht gefunden.');

    if (!wp_verify_nonce($token, 'xr_pdf_customer_' . $oid . '_' . $order->get_order_key())) {
        wp_die('Ungültiger oder abgelaufener Link.');
    }

    if (is_user_logged_in()) {
        if ($order->get_customer_id() && $order->get_customer_id() !== get_current_user_id()) {
            wp_die('Keine Berechtigung.');
        }
    } else {
        $key = sanitize_text_field($_GET['order_key'] ?? '');
        if (!hash_equals($order->get_order_key(), $key)) wp_die('Keine Berechtigung.');
    }

    $pdf = fmexr_get_or_create_pdf($oid);
    if (!$pdf) wp_die('PDF nicht verfügbar.');

    $inv = get_post_meta($oid, '_fmexr_inv_num', true) ?: 'rechnung-' . $oid;
    header('Content-Type: application/pdf');
    header('Content-Disposition: inline; filename="' . sanitize_file_name($inv) . '.pdf"');
    echo $pdf; exit;
}

// ── Add PDF download button to admin meta box ─────────────────────────────────
add_filter('fmexr_meta_box_after_download', function(string $html, int $oid): string {
    $pdf_url = wp_nonce_url(admin_url('admin-ajax.php?action=fmexr_pdf&order_id=' . $oid), 'xr_pdf_' . $oid);
    return $html . '<a href="' . esc_url($pdf_url) . '" style="display:block;padding:7px;background:#7c3aed;color:#fff;border-radius:6px;text-decoration:none;text-align:center;font-size:12px;margin-top:6px">📄 PDF herunterladen</a>';
}, 10, 2);
