<?php

namespace Tests\Unit;

use App\Controllers\Admin\OrderController;
use PHPUnit\Framework\TestCase;

class OrderControllerPayloadTest extends TestCase
{
    public function testNormalizeOrderItemsFromNestedPayload(): void
    {
        $items = OrderController::normalizeOrderItems([
            'items' => [
                [
                    'id_product' => '12',
                    'product_name' => 'Produk A',
                    'qty' => '2',
                    'price' => '15000',
                    'description' => 'Pisahkan warna',
                    'is_custom' => '0',
                ],
            ],
        ]);

        $this->assertCount(1, $items);
        $this->assertSame('12', $items[0]['id_product']);
        $this->assertSame('Produk A', $items[0]['product_name']);
        $this->assertSame(2, $items[0]['qty']);
        $this->assertSame(15000.0, $items[0]['price']);
    }

    public function testNormalizeOrderItemsFromFlatPayload(): void
    {
        $items = OrderController::normalizeOrderItems([
            'product' => ['12', 'custom_1'],
            'product_name' => ['Produk A', 'Produk Custom'],
            'qty' => ['2', '1'],
            'price' => ['15000', '25000'],
            'description' => ['Pisahkan warna', 'Ukuran XL'],
            'is_custom' => ['0', '1'],
        ]);

        $this->assertCount(2, $items);
        $this->assertSame('12', $items[0]['id_product']);
        $this->assertSame('custom_1', $items[1]['id_product']);
        $this->assertSame('Produk Custom', $items[1]['product_name']);
        $this->assertSame(1, $items[1]['qty']);
        $this->assertSame(25000.0, $items[1]['price']);
    }

    public function testNormalizeOrderItemsMarksCustomItemAndKeepsItsDetails(): void
    {
        $items = OrderController::normalizeOrderItems([
            'product' => ['custom_1'],
            'product_name' => ['Jaket Bordir Nama'],
            'qty' => ['2'],
            'price' => ['75000'],
            'description' => ['Ukuran XL, bordir dada kiri'],
            'is_custom' => ['1'],
        ]);

        $this->assertCount(1, $items);
        $this->assertTrue($items[0]['is_custom']);
        $this->assertSame('Jaket Bordir Nama', $items[0]['product_name']);
        $this->assertSame('Ukuran XL, bordir dada kiri', $items[0]['description']);
        $this->assertSame(150000.0, $items[0]['subtotal']);
    }

    public function testNormalizeOrderItemsSupportsMoreThanFiveProducts(): void
    {
        $items = OrderController::normalizeOrderItems([
            'items' => array_map(
                static fn (int $id): array => [
                    'id_product' => (string) $id,
                    'product_name' => 'Produk ' . $id,
                    'qty' => '1',
                    'price' => '10000',
                ],
                range(1, 6)
            ),
        ]);

        $this->assertCount(6, $items);
        $this->assertSame('6', $items[5]['id_product']);
    }

    public function testPoProductRequiresTheWholeOrderToUsePoFlow(): void
    {
        $items = OrderController::normalizeOrderItems([
            'product' => ['4', '7'],
            'qty' => ['1', '1'],
            'price' => ['10000', '20000'],
        ]);

        $this->assertTrue(OrderController::requiresPreOrder($items, [
            '4' => ['stock_type' => 'ready'],
            '7' => ['stock_type' => 'po'],
        ]));

        $this->assertFalse(OrderController::requiresPreOrder($items, [
            '4' => ['stock_type' => 'ready'],
            '7' => ['stock_type' => 'ready'],
        ]));
    }

    public function testReadyStockAvailabilityDetectsEmptyAndInsufficientStock(): void
    {
        $emptyStockError = OrderController::readyStockAvailabilityError([
            ['id_product' => '12', 'qty' => 1, 'is_custom' => false],
        ], [
            '12' => ['nama_product' => 'Produk Ready', 'stock_type' => 'pcs', 'stok' => 0],
        ]);

        $insufficientStockError = OrderController::readyStockAvailabilityError([
            ['id_product' => '12', 'qty' => 3, 'is_custom' => false],
        ], [
            '12' => ['nama_product' => 'Produk Ready', 'stock_type' => 'ready', 'stok' => 2],
        ]);

        $poError = OrderController::readyStockAvailabilityError([
            ['id_product' => '18', 'qty' => 10, 'is_custom' => false],
        ], [
            '18' => ['nama_product' => 'Produk PO', 'stock_type' => 'po', 'stok' => 0],
        ]);

        $this->assertSame('Stok produk ready "Produk Ready" sedang kosong. Perbarui stok atau gunakan produk PO.', $emptyStockError);
        $this->assertSame('Stok produk ready "Produk Ready" tidak mencukupi. Tersedia 2, diminta 3.', $insufficientStockError);
        $this->assertNull($poError);
    }
}
