<?php

namespace SoftminalB2B\Storefront;

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

use SoftminalB2B\Pricing\Context;

/**
 * Purchase-order numbers at checkout (FEATURES F — trade buyers reconcile every
 * order against an internal PO).
 *
 * Registered through WooCommerce's additional-checkout-fields API, so the one
 * field renders and validates in both the block checkout and the classic form.
 * It is offered only to B2B customers — a retail shopper never sees a PO box.
 * The value is mirrored to a stable `_smb2b_po_number` meta so the invoice and
 * anything reading it never depends on Woo's internal field-storage key.
 */
class PurchaseOrder
{
    public const FIELD_ID  = 'smb2b/po-number';
    public const META_KEY  = '_smb2b_po_number';

    private static bool $registered = false;

    public static function init(): void
    {
        if (self::$registered) {
            return;
        }

        self::$registered = true;

        add_action('woocommerce_init', [self::class, 'registerField']);

        // Copy the submitted value to a canonical meta key on both checkout
        // paths, so downstream code has one place to read it.
        add_action('woocommerce_set_additional_field_value', [self::class, 'mirrorValue'], 10, 4);

        // Show it on the PDF invoice.
        add_filter('smb2b_invoice_data', [self::class, 'addToInvoice'], 10, 2);
    }

    /**
     * Register the PO field — but only for a buyer who is actually on a B2B
     * account, so retail checkouts stay clean.
     */
    public static function registerField(): void
    {
        if (!function_exists('woocommerce_register_additional_checkout_field')) {
            return;
        }

        if (Context::forUser()->isRetail()) {
            return;
        }

        woocommerce_register_additional_checkout_field([
            'id'            => self::FIELD_ID,
            'label'         => __('Purchase order number', 'softminal-b2b-wholesale-for-woocommerce'),
            'optionalLabel' => __('Purchase order number (optional)', 'softminal-b2b-wholesale-for-woocommerce'),
            'location'      => 'order',
            'type'          => 'text',
            'required'      => false,
            'attributes'    => ['autocomplete' => 'off', 'maxLength' => 60],
        ]);
    }

    /**
     * @param string $key   The additional field id.
     * @param mixed  $value Submitted value.
     * @param string $group 'billing' | 'shipping' | 'other'.
     * @param object $wcObject The order or customer the value is set on.
     */
    public static function mirrorValue($key, $value, $group, $wcObject): void
    {
        if ($key !== self::FIELD_ID || !$wcObject instanceof \WC_Order) {
            return;
        }

        $po = sanitize_text_field((string) $value);

        if ($po !== '') {
            $wcObject->update_meta_data(self::META_KEY, $po);
        } else {
            $wcObject->delete_meta_data(self::META_KEY);
        }
    }

    /**
     * The PO number stored on an order, or ''.
     */
    public static function forOrder(\WC_Order $order): string
    {
        return (string) $order->get_meta(self::META_KEY);
    }

    /**
     * Add the PO number to the invoice's header fields.
     *
     * @param array<string, mixed> $data
     * @return array<string, mixed>
     */
    public static function addToInvoice($data, $order)
    {
        if ($order instanceof \WC_Order) {
            $po = self::forOrder($order);

            if ($po !== '') {
                $data['po_number'] = $po;
            }
        }

        return $data;
    }
}
