<?php

/**
 * Validates an order for receipt generation.
 *
 * @package northmill-online-shared
 */
declare (strict_types=1);
namespace Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Abstracts\Hub_API\Factories;

use WC_Order_Item_Product;
use WP_Error;
/**
 * Class Receipt_Validator
 */
class Receipt_Order_Validator
{
    /**
     * The receipt factory.
     *
     * @var Receipt_Factory
     */
    protected Receipt_Factory $receipt_factory;
    /**
     * Receipt_Validator constructor.
     *
     * @param Receipt_Factory $receipt_factory The receipt factory.
     */
    public function __construct(Receipt_Factory $receipt_factory)
    {
        $this->receipt_factory = $receipt_factory;
    }
    /**
     * Validates an order for receipt generation.
     *
     * @return WP_Error|true
     */
    public function validate_placed_order_for_receipt(): WP_Error|true
    {
        $order_items = $this->receipt_factory->wc_order->get_items();
        if (empty($order_items)) {
            return new WP_Error('receipt_no_order_items', 'Order contains no items: ' . $this->receipt_factory->wc_order->get_id());
        }
        foreach ($order_items as $order_item) {
            if (!is_a($order_item, WC_Order_Item_Product::class)) {
                return new WP_Error('receipt_unknown_order_item', 'Unknown order item: ' . $order_item->get_name());
            }
        }
        $this->receipt_factory->order_items = $order_items;
        $order_payment_method = !$this->receipt_factory->is_for_refund ? $this->receipt_factory->wc_order->get_payment_method() : $this->receipt_factory->parent_order->get_payment_method();
        $payment_method_account = $this->receipt_factory->get_income_account_code_from_payment_method($order_payment_method);
        if (empty($payment_method_account)) {
            return new WP_Error('receipt_no_payment_method_account', 'No bookkeeping account set for payment method: ' . $order_payment_method);
        }
        $this->receipt_factory->order_payment_method = $order_payment_method;
        $this->receipt_factory->payment_method_account = $payment_method_account;
        $this->receipt_factory->generate_articles();
        if (in_array(null, $this->receipt_factory->articles, \true)) {
            return new WP_Error('receipt_articles_missing', __('Articles from order are missing', 'northmill-online-shared'));
        }
        $this->receipt_factory->generate_vat();
        if (in_array(null, $this->receipt_factory->vat, \true)) {
            return new WP_Error('vat_account_code_missing', __('VAT account code missing.', 'northmill-online-shared'));
        }
        $this->receipt_factory->generate_voucher();
        if (!$this->receipt_factory->voucher) {
            return new WP_Error('voucher_error', __('Could not create voucher', 'northmill-online-shared'));
        }
        $voucher_validation = $this->validate_voucher();
        if (is_wp_error($voucher_validation)) {
            return $voucher_validation;
        }
        return \true;
    }
    /**
     * Validates a voucher.
     *
     * @return true|WP_Error.
     */
    private function validate_voucher(): true|WP_Error
    {
        $debit_sum = 0.0;
        $credit_sum = 0.0;
        $tolerance = 0.01;
        // Tolerance value for floating-point comparison.
        foreach ($this->receipt_factory->voucher->get_rows() as $row) {
            $debit_sum += $row->get_debit_amount_float();
            $credit_sum += $row->get_credit_amount_float();
        }
        if (abs($debit_sum - $credit_sum) > $tolerance) {
            return new WP_Error('voucher_balance_error', 'The debit and credit amounts are not balanced. Debit: ' . $debit_sum . ', Credit: ' . $credit_sum);
        }
        return \true;
    }
}
