<?php

declare(strict_types=1);

use App\Framework\Database\Indexing\IndexAnalyzer;
use App\Framework\Database\Indexing\ValueObjects\IndexName;
use App\Framework\Database\Indexing\ValueObjects\IndexType;
use App\Framework\Database\PdoConnection;

describe('IndexAnalyzer', function () {
    beforeEach(function () {
        // Create in-memory SQLite database for testing
        $pdo = new PDO('sqlite::memory:');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // Create test table with indexes
        $pdo->exec('
            CREATE TABLE users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                email TEXT NOT NULL UNIQUE,
                name TEXT NOT NULL,
                status TEXT,
                created_at TEXT
            )
        ');

        $pdo->exec('CREATE INDEX idx_users_status ON users(status)');
        $pdo->exec('CREATE INDEX idx_users_created_at ON users(created_at)');
        $pdo->exec('CREATE INDEX idx_users_email_status ON users(email, status)');

        $this->connection = new PdoConnection($pdo, 'sqlite');
        $this->analyzer = new IndexAnalyzer($this->connection);
    });

    it('can get all indexes for a table', function () {
        $indexes = $this->analyzer->getTableIndexes('users');

        expect($indexes)->toBeArray();
        expect(count($indexes))->toBeGreaterThan(0);

        // Should have at least: PRIMARY, UNIQUE, and our custom indexes
        $indexNames = array_column($indexes, 'name');
        expect($indexNames)->toContain('idx_users_status');
        expect($indexNames)->toContain('idx_users_created_at');
    });

    it('detects index usage in query', function () {
        $sql = 'SELECT * FROM users WHERE status = "active"';
        $analysis = $this->analyzer->analyzeQuery($sql);

        expect($analysis)->toBeArray();
        expect($analysis)->toHaveKey('query');
        expect($analysis)->toHaveKey('indexes_used');
        expect($analysis)->toHaveKey('key_type');
        expect($analysis['query'])->toBe($sql);
    });

    it('detects composite index columns correctly', function () {
        $indexes = $this->analyzer->getTableIndexes('users');

        $compositeIndex = array_values(array_filter($indexes, function ($index) {
            return $index['name'] === 'idx_users_email_status';
        }))[0] ?? null;

        expect($compositeIndex)->not->toBeNull();
        expect($compositeIndex['columns'])->toBe(['email', 'status']);
    });

    it('identifies index types correctly', function () {
        $indexes = $this->analyzer->getTableIndexes('users');

        foreach ($indexes as $index) {
            expect($index['type'])->toBeInstanceOf(IndexType::class);
        }
    });

    it('marks unique indexes correctly', function () {
        $indexes = $this->analyzer->getTableIndexes('users');

        $uniqueIndex = array_values(array_filter($indexes, function ($index) {
            return str_contains($index['name'], 'email');
        }))[0] ?? null;

        expect($uniqueIndex)->not->toBeNull();
        expect($uniqueIndex['is_unique'])->toBeTrue();
    });

    it('analyzes queries without indexes', function () {
        $sql = 'SELECT * FROM users WHERE name LIKE "%John%"';
        $analysis = $this->analyzer->analyzeQuery($sql);

        expect($analysis['indexes_used'])->toBeArray();
        // SQLite might use table scan for LIKE queries
        expect($analysis['key_type'])->toBeIn(['scan', 'ALL', 'index']);
    });
});
