<?php

declare(strict_types=1);

usesApiSuite();

const ECONOMIC_DRAFT_CUSTOMER_BLOCKED_MESSAGE = 'Transactions for the configured draft customer cannot be exported to e-conomic.';

function economic_draft_customer_find_config_entry(array $entries, string $variable): ?array
{
    foreach ($entries as $entry) {
        if (is_array($entry) && ($entry['variable'] ?? null) === $variable) {
            return $entry;
        }
    }

    return null;
}

it('lists the draft customer config entry in economic config responses', function (): void {
    api_test_covers('GET /economic/config', 'happy');

    $session = api_fixtures()->createUserSession(['economic_config']);

    $response = api_client()->get('/economic/config', $session['headers']);

    $response
        ->assertStatus(200)
        ->assertEnvelope()
        ->assertSuccess();

    $entry = economic_draft_customer_find_config_entry((array)$response->data(), 'transactionDraftCustomerNumber');

    expect($entry)
        ->not->toBeNull()
        ->and($entry['module'] ?? null)->toBe('economic')
        ->and($entry['type'] ?? null)->toBe('int')
        ->and(is_int($entry['value'] ?? null) || ($entry['value'] ?? null) === null)->toBeTrue();
});

it('round-trips the draft customer config value through economic config updates', function (): void {
    api_test_covers('POST /economic/config', 'happy');

    api_fixtures()->preserveModuleConfig('economic', 'transactionDraftCustomerNumber');
    $session = api_fixtures()->createUserSession(['economic_config']);

    api_client()->post('/economic/config', [
        'variable' => 'transactionDraftCustomerNumber',
        'value' => 667788,
    ], $session['headers'])
        ->assertStatus(200)
        ->assertEnvelope()
        ->assertSuccess();

    $configuredResponse = api_client()->get('/economic/config?variable=transactionDraftCustomerNumber', $session['headers']);
    $configuredResponse
        ->assertStatus(200)
        ->assertEnvelope()
        ->assertSuccess();

    $configuredEntry = economic_draft_customer_find_config_entry((array)$configuredResponse->data(), 'transactionDraftCustomerNumber');
    expect($configuredEntry)
        ->not->toBeNull()
        ->and($configuredEntry['value'] ?? null)->toBe(667788);

    api_client()->post('/economic/config', [
        'variable' => 'transactionDraftCustomerNumber',
        'value' => null,
    ], $session['headers'])
        ->assertStatus(200)
        ->assertEnvelope()
        ->assertSuccess();

    $clearedResponse = api_client()->get('/economic/config?variable=transactionDraftCustomerNumber', $session['headers']);
    $clearedResponse
        ->assertStatus(200)
        ->assertEnvelope()
        ->assertSuccess();

    $clearedEntry = economic_draft_customer_find_config_entry((array)$clearedResponse->data(), 'transactionDraftCustomerNumber');
    expect($clearedEntry)->toBeArray();
    expect(array_key_exists('value', $clearedEntry))->toBeTrue();
    expect($clearedEntry['value'])->toBeNull();
});

it('round-trips the default distribution department config value through economic config updates', function (): void {
    api_test_covers('POST /economic/config', 'happy');

    api_fixtures()->preserveModuleConfig('economic', 'defaultDepartmentId');
    $session = api_fixtures()->createUserSession(['economic_config']);

    api_client()->post('/economic/config', [
        'variable' => 'defaultDepartmentId',
        'value' => 75,
    ], $session['headers'])
        ->assertStatus(200)
        ->assertEnvelope()
        ->assertSuccess();

    $configuredResponse = api_client()->get('/economic/config?variable=defaultDepartmentId', $session['headers']);
    $configuredResponse
        ->assertStatus(200)
        ->assertEnvelope()
        ->assertSuccess();

    $configuredEntry = economic_draft_customer_find_config_entry((array)$configuredResponse->data(), 'defaultDepartmentId');
    expect($configuredEntry)
        ->not->toBeNull()
        ->and($configuredEntry['type'] ?? null)->toBe('int')
        ->and($configuredEntry['value'] ?? null)->toBe(75);
});

it('rejects order draft exports for the configured draft customer', function (): void {
    api_test_covers('POST /economic/invoice/draft/export', 'failure');

    $draftCustomer = api_fixtures()->createUser(['display_name' => 'Draft Export Customer']);
    $department = api_fixtures()->createDepartment();
    $cashier = api_fixtures()->createUser(['display_name' => 'Draft Export Cashier']);
    $order = api_fixtures()->createOrder([
        'customer_id' => $draftCustomer['customer_number'],
        'cashier_id' => $cashier['id'],
        'department_id' => $department['id'],
        'reference' => 'BLOCK-DRAFT',
        'reg_1' => 'DRFT123',
    ]);

    api_fixtures()->setModuleConfig('economic', 'transactionDraftCustomerNumber', (string)$draftCustomer['customer_number'], 'int');
    $session = api_fixtures()->createUserSession(['economic_invoice_draft_export']);

    api_client()->post('/economic/invoice/draft/export', [
        'order_id' => $order['id'],
    ], $session['headers'])
        ->assertStatus(400)
        ->assertEnvelope()
        ->assertSuccess(false)
        ->assertMessage(ECONOMIC_DRAFT_CUSTOMER_BLOCKED_MESSAGE);
});

it('rejects booked invoice exports for the configured draft customer', function (): void {
    api_test_covers('POST /economic/invoice/export', 'failure');

    $draftCustomer = api_fixtures()->createUser(['display_name' => 'Booked Export Customer']);
    $department = api_fixtures()->createDepartment();
    $cashier = api_fixtures()->createUser(['display_name' => 'Booked Export Cashier']);
    $order = api_fixtures()->createOrder([
        'customer_id' => $draftCustomer['customer_number'],
        'cashier_id' => $cashier['id'],
        'department_id' => $department['id'],
        'reference' => 'BLOCK-INVOICE',
        'reg_1' => 'INV1234',
    ]);

    api_fixtures()->setModuleConfig('economic', 'transactionDraftCustomerNumber', (string)$draftCustomer['customer_number'], 'int');
    $session = api_fixtures()->createUserSession(['economic_invoice_export']);

    api_client()->post('/economic/invoice/export', [
        'order_id' => $order['id'],
    ], $session['headers'])
        ->assertStatus(400)
        ->assertEnvelope()
        ->assertSuccess(false)
        ->assertMessage(ECONOMIC_DRAFT_CUSTOMER_BLOCKED_MESSAGE);
});

it('rejects collected invoice exports for the configured draft customer', function (): void {
    api_test_covers('POST /collected-invoices/economic', 'failure');

    $draftCustomer = api_fixtures()->createUser(['display_name' => 'Collected Export Customer']);
    $invoiceCollection = api_fixtures()->createInvoiceCollection([
        'customer_number' => $draftCustomer['customer_number'],
    ]);

    api_fixtures()->setModuleConfig('economic', 'transactionDraftCustomerNumber', (string)$draftCustomer['customer_number'], 'int');
    $session = api_fixtures()->createUserSession(['add_collected_invoice_economic']);

    api_client()->post('/collected-invoices/economic', [
        'id' => $invoiceCollection['id'],
    ], $session['headers'])
        ->assertStatus(400)
        ->assertEnvelope()
        ->assertSuccess(false)
        ->assertMessage(ECONOMIC_DRAFT_CUSTOMER_BLOCKED_MESSAGE);
});
