<?php

declare(strict_types=1);

usesApiSuite();

function moved_invoice_collection_customer_number(int $invoiceCollectionId): int
{
    $row = api_test_runtime()->queryOne('SELECT customer_number FROM collected_order_invoices WHERE id = ' . $invoiceCollectionId . ' LIMIT 1');
    return (int)($row['customer_number'] ?? 0);
}

function moved_order_customer_number(int $orderId): int
{
    $row = api_test_runtime()->queryOne('SELECT customer_id FROM orders WHERE id = ' . $orderId . ' LIMIT 1');
    return (int)($row['customer_id'] ?? 0);
}

it('moves a collected invoice collection and all attached orders to another customer', function (): void {
    api_test_covers('POST /collected-invoices/move-to-customer', 'happy');

    $sourceCustomer = api_fixtures()->createUser(['display_name' => 'Move Source Customer']);
    $targetCustomer = api_fixtures()->createUser(['display_name' => 'Move Target Customer']);
    $department = api_fixtures()->createDepartment();
    $invoiceCollection = api_fixtures()->createInvoiceCollection([
        'customer_number' => $sourceCustomer['customer_number'],
    ]);
    $firstOrder = api_fixtures()->createOrder([
        'customer_id' => $sourceCustomer['customer_number'],
        'department_id' => $department['id'],
        'invoice_collection_id' => $invoiceCollection['id'],
    ]);
    $secondOrder = api_fixtures()->createOrder([
        'customer_id' => $sourceCustomer['customer_number'],
        'department_id' => $department['id'],
        'invoice_collection_id' => $invoiceCollection['id'],
    ]);
    $session = api_fixtures()->createUserSession(['move_collected_invoice_customer']);

    $response = api_client()->post('/collected-invoices/move-to-customer', [
        'id' => $invoiceCollection['id'],
        'customer_number' => $targetCustomer['customer_number'],
    ], $session['headers']);

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

    $payload = $response->data();
    $moveMeta = $response->meta()['move'] ?? [];

    expect($payload['id'] ?? null)->toBe((int)$invoiceCollection['id'])
        ->and($payload['customer_number'] ?? null)->toBe((int)$targetCustomer['customer_number'])
        ->and($moveMeta['source_customer_number'] ?? null)->toBe((int)$sourceCustomer['customer_number'])
        ->and($moveMeta['target_customer_number'] ?? null)->toBe((int)$targetCustomer['customer_number'])
        ->and($moveMeta['moved_order_count'] ?? null)->toBe(2)
        ->and(moved_invoice_collection_customer_number((int)$invoiceCollection['id']))->toBe((int)$targetCustomer['customer_number'])
        ->and(moved_order_customer_number((int)$firstOrder['id']))->toBe((int)$targetCustomer['customer_number'])
        ->and(moved_order_customer_number((int)$secondOrder['id']))->toBe((int)$targetCustomer['customer_number']);
});

it('rejects moving a collection that already has an external invoice reference', function (): void {
    api_test_covers('POST /collected-invoices/move-to-customer', 'external-guard');

    $sourceCustomer = api_fixtures()->createUser(['display_name' => 'Move External Source Customer']);
    $targetCustomer = api_fixtures()->createUser(['display_name' => 'Move External Target Customer']);
    $department = api_fixtures()->createDepartment();
    $invoiceCollection = api_fixtures()->createInvoiceCollection([
        'customer_number' => $sourceCustomer['customer_number'],
        'external_id' => 'external-invoice-123',
    ]);
    $order = api_fixtures()->createOrder([
        'customer_id' => $sourceCustomer['customer_number'],
        'department_id' => $department['id'],
        'invoice_collection_id' => $invoiceCollection['id'],
    ]);
    $session = api_fixtures()->createUserSession(['move_collected_invoice_customer']);

    $response = api_client()->post('/collected-invoices/move-to-customer', [
        'id' => $invoiceCollection['id'],
        'customer_number' => $targetCustomer['customer_number'],
    ], $session['headers']);

    $response
        ->assertStatus(400)
        ->assertEnvelope()
        ->assertSuccess(false);

    expect($response->data()['message'] ?? '')->toContain('external or booked invoice')
        ->and(moved_invoice_collection_customer_number((int)$invoiceCollection['id']))->toBe((int)$sourceCustomer['customer_number'])
        ->and(moved_order_customer_number((int)$order['id']))->toBe((int)$sourceCustomer['customer_number']);
});
