<?php

app_require('classes/object_property.php');
app_require('objects/orders_o.php');

use classes\object_property;
use objects\orders_o;

if (!class_exists('OrdersIncludeInInvoiceOverrideOrderDouble')) {
    class OrdersIncludeInInvoiceOverrideOrderDouble extends orders_o
    {
        public bool $departmentIncluded = true;

        public function __construct()
        {
            $this->id = -1;
            $this->customer_id = new object_property('orders', -1, 'customer_id', 'int', true);
            $this->cashier_id = new object_property('orders', -1, 'cashier_id', 'int', true);
            $this->reference = new object_property('orders', -1, 'reference', 'string', false);
            $this->notes = new object_property('orders', -1, 'notes', 'string', false);
            $this->department_id = new object_property('orders', -1, 'department_id', 'int', true);
            $this->reg_1 = new object_property('orders', -1, 'reg_1', 'string', false);
            $this->reg_2 = new object_property('orders', -1, 'reg_2', 'string', false);
            $this->reg_3 = new object_property('orders', -1, 'reg_3', 'string', false);
            $this->created_at = new object_property('orders', -1, 'created_at', 'timestamp', false);
            $this->include_in_invoice = new object_property('orders', -1, 'include_in_invoice', 'bool', false);
            $this->completed_at = new object_property('orders', -1, 'completed_at', 'timestamp', false);
            $this->deleted_at = new object_property('orders', -1, 'deleted_at', 'timestamp', false);
            $this->invoice_collection_id = new object_property('orders', -1, 'invoice_collection_id', 'int', false);
            $this->booking_id = new object_property('orders', -1, 'booking_id', 'int', false);
            $this->wash_id = new object_property('orders', -1, 'wash_id', 'string', false);
            $this->lane = new object_property('orders', -1, 'lane', 'string', false);
            $this->po = new object_property('orders', -1, 'po', 'string', false);
            $this->safety_seal = new object_property('orders', -1, 'safety_seal', 'string', false);
            $this->using_hand_held = new object_property('orders', -1, 'using_hand_held', 'bool', false);
            $this->temporary_net_amount = 125.5;

            $this->customer_id->set(1234567);
            $this->cashier_id->set(42);
            $this->department_id->set(12);
            $this->created_at->set('2026-04-09 12:34:56');
            $this->reference->set('Ref');
        }

        protected function resolveDepartmentIncludedInInvoicing(): bool
        {
            return $this->departmentIncluded;
        }

        public function isPendingHandheld(): bool
        {
            return false;
        }
    }
}

it('lets the order-level override include an otherwise excluded order', function (): void {
    $order = new OrdersIncludeInInvoiceOverrideOrderDouble();
    $order->departmentIncluded = false;
    $order->include_in_invoice->set(true);

    expect($order->getIncludeInInvoiceOverride())->toBeTrue();
    expect($order->isIncludedInInvoicing())->toBeTrue();
});

it('lets the order-level override exclude an otherwise included order', function (): void {
    $order = new OrdersIncludeInInvoiceOverrideOrderDouble();
    $order->departmentIncluded = true;
    $order->include_in_invoice->set(false);

    expect($order->getIncludeInInvoiceOverride())->toBeFalse();
    expect($order->isIncludedInInvoicing())->toBeFalse();
});

it('falls back to the department invoicing rule when the override is null', function (): void {
    $order = new OrdersIncludeInInvoiceOverrideOrderDouble();
    $order->departmentIncluded = false;
    $order->include_in_invoice->set(null);

    expect($order->getIncludeInInvoiceOverride())->toBeNull();
    expect($order->isIncludedInInvoicing())->toBeFalse();
});

it('serializes both raw and effective include_in_invoice values', function (): void {
    $order = new OrdersIncludeInInvoiceOverrideOrderDouble();
    $order->departmentIncluded = true;
    $order->include_in_invoice->set(null);

    expect($order->asArray(true, false))->toMatchArray([
        'include_in_invoice' => null,
        'include_in_invoice_effective' => true,
        'safety_seal' => null,
        'created_at' => '2026-04-09 12:34:56',
        'total_net_amount' => 125.5,
    ]);
});
