<?php

app_require('objects/users_o.php');

use objects\users_o;

final class CustomerAttributesLegacySchemaResultStub
{
    public int $num_rows;

    /** @var list<array<string, mixed>> */
    private array $rows;

    /** @param list<array<string, mixed>> $rows */
    public function __construct(array $rows)
    {
        $this->rows = array_values($rows);
        $this->num_rows = count($rows);
    }

    /** @return array<string, mixed>|null */
    public function fetch_assoc(): ?array
    {
        if ($this->rows === []) {
            return null;
        }

        return array_shift($this->rows);
    }

    /** @return list<array<string, mixed>> */
    public function rows(): array
    {
        return $this->rows;
    }
}

final class CustomerAttributesLegacySchemaDbStub
{
    /** @var list<string> */
    public array $queries = [];

    public function query(string $sql): CustomerAttributesLegacySchemaResultStub
    {
        $this->queries[] = $sql;

        if (str_contains($sql, 'SELECT customer_number FROM users')) {
            return new CustomerAttributesLegacySchemaResultStub([
                ['customer_number' => 5501],
            ]);
        }

        if (str_contains($sql, 'SELECT id FROM users WHERE customer_number')) {
            return new CustomerAttributesLegacySchemaResultStub([
                ['id' => 12],
                ['id' => 13],
            ]);
        }

        if (str_contains($sql, 'FROM customer_attributes')) {
            $columnReferences = str_replace('NULL AS created_at', '', $sql);
            if (str_contains($columnReferences, 'created_at')) {
                throw new RuntimeException("Unknown column 'created_at' in 'SELECT'");
            }

            return new CustomerAttributesLegacySchemaResultStub([
                ['id' => 4, 'user_id' => 12, 'attribute' => 'onlyTankCleaning', 'created_at' => null],
                ['id' => 7, 'user_id' => 13, 'attribute' => 'restrictSpotFree', 'created_at' => null],
            ]);
        }

        return new CustomerAttributesLegacySchemaResultStub([]);
    }

    /** @return list<array<string, mixed>> */
    public function fetch_all(CustomerAttributesLegacySchemaResultStub $result): array
    {
        return $result->rows();
    }
}

it('loads sibling customer attributes when the legacy table has no created_at column', function (): void {
    $hadDb = array_key_exists('db', $GLOBALS);
    $previousDb = $hadDb ? $GLOBALS['db'] : null;
    $db = new CustomerAttributesLegacySchemaDbStub();
    $GLOBALS['db'] = $db;

    try {
        $attributes = (new users_o())->getUserAttributes(12);

        expect(array_column($attributes, 'attribute'))
            ->toBe(['onlyTankCleaning', 'restrictSpotFree'])
            ->and(array_column($attributes, 'created_at'))
            ->toBe([null, null]);

        $attributeQuery = $db->queries[2] ?? '';
        expect($attributeQuery)
            ->toContain('SELECT MIN(id) AS id, MIN(user_id) AS user_id, attribute, NULL AS created_at')
            ->toContain('WHERE user_id IN (12,13)')
            ->not->toContain('MIN(created_at)');
    } finally {
        if ($hadDb) {
            $GLOBALS['db'] = $previousDb;
        } else {
            unset($GLOBALS['db']);
        }
    }
});
