<?php

declare(strict_types=1);

require_once __DIR__ . '/../../src/Framework/Database/Schema/MaterializedView.php';
require_once __DIR__ . '/../../src/Framework/Database/MaterializedViews/MaterializedViewService.php';

use App\Framework\Database\Schema\MaterializedView;
use App\Framework\Database\MaterializedViews\MaterializedViewService;

echo "Testing PostgreSQL Materialized Views\n";
echo "======================================\n\n";

try {
    $pdo = new PDO(
        'pgsql:host=db;dbname=michaelschiemer',
        'postgres',
        'StartSimple2024!'
    );
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    echo "✅ Database connection established\n\n";

    $service = new MaterializedViewService($pdo);

    // Cleanup
    echo "Cleanup...\n";
    $pdo->exec("DROP TABLE IF EXISTS test_sales CASCADE");
    $pdo->exec("DROP MATERIALIZED VIEW IF EXISTS sales_summary");
    $pdo->exec("DROP MATERIALIZED VIEW IF EXISTS top_products");
    echo "✅ Cleanup complete\n\n";

    // Create test table
    echo "Test 1: Create Test Data\n";
    echo "=========================\n";
    $pdo->exec("
        CREATE TABLE test_sales (
            id SERIAL PRIMARY KEY,
            product_name VARCHAR(100),
            category VARCHAR(50),
            amount NUMERIC(10,2),
            sale_date DATE
        )
    ");

    $pdo->exec("
        INSERT INTO test_sales (product_name, category, amount, sale_date) VALUES
        ('Laptop', 'Electronics', 1200.00, '2025-01-10'),
        ('Mouse', 'Electronics', 25.00, '2025-01-10'),
        ('Desk', 'Furniture', 350.00, '2025-01-11'),
        ('Chair', 'Furniture', 150.00, '2025-01-11'),
        ('Keyboard', 'Electronics', 75.00, '2025-01-12')
    ");
    echo "✅ Test table created with 5 sales records\n\n";

    // Test 2: Create Materialized View
    echo "Test 2: Create Materialized View\n";
    echo "=================================\n";

    $view = new MaterializedView(
        'sales_summary',
        "SELECT category, COUNT(*) as total_sales, SUM(amount) as total_amount FROM test_sales GROUP BY category"
    );

    $service->create($view);
    echo "✅ Materialized view 'sales_summary' created\n";

    // Query materialized view
    $stmt = $pdo->query("SELECT * FROM sales_summary ORDER BY category");
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    echo "   Initial data:\n";
    foreach ($results as $row) {
        echo "   - {$row['category']}: {$row['total_sales']} sales, Total: €{$row['total_amount']}\n";
    }
    echo "\n";

    // Test 3: Add more data (materialized view doesn't auto-update)
    echo "Test 3: Add Data (View Doesn't Auto-Update)\n";
    echo "============================================\n";

    $pdo->exec("INSERT INTO test_sales (product_name, category, amount, sale_date) VALUES ('Monitor', 'Electronics', 300.00, '2025-01-13')");
    echo "✅ Added new sale (Electronics, €300)\n";

    $stmt = $pdo->query("SELECT * FROM sales_summary WHERE category = 'Electronics'");
    $before = $stmt->fetch(PDO::FETCH_ASSOC);
    echo "   Electronics BEFORE refresh: {$before['total_sales']} sales, €{$before['total_amount']}\n";
    echo "   (Should still show old data)\n\n";

    // Test 4: Refresh Materialized View
    echo "Test 4: REFRESH Materialized View\n";
    echo "==================================\n";

    $service->refresh('sales_summary');
    echo "✅ Materialized view refreshed\n";

    $stmt = $pdo->query("SELECT * FROM sales_summary WHERE category = 'Electronics'");
    $after = $stmt->fetch(PDO::FETCH_ASSOC);
    echo "   Electronics AFTER refresh: {$after['total_sales']} sales, €{$after['total_amount']}\n";
    echo ($after['total_amount'] > $before['total_amount']) ? "✅ Data updated after refresh\n" : "❌ Should have updated\n";
    echo "\n";

    // Test 5: Create view with index (for CONCURRENTLY refresh)
    echo "Test 5: View With Index (Concurrent Refresh)\n";
    echo "=============================================\n";

    $topProductsView = new MaterializedView(
        'top_products',
        "SELECT product_name, amount FROM test_sales ORDER BY amount DESC LIMIT 3"
    );

    $service->create($topProductsView);
    echo "✅ Materialized view 'top_products' created\n";

    // Create unique index (required for CONCURRENTLY)
    $pdo->exec("CREATE UNIQUE INDEX top_products_idx ON top_products (product_name)");
    echo "✅ Unique index created\n";

    // Concurrent refresh
    $service->refresh('top_products', concurrently: true);
    echo "✅ Concurrent refresh successful\n\n";

    // Test 6: List all materialized views
    echo "Test 6: List All Materialized Views\n";
    echo "====================================\n";

    $views = $service->listAll();
    echo "✅ Found " . count($views) . " materialized views:\n";
    foreach ($views as $v) {
        echo "   - {$v['name']} (has_indexes: " . ($v['has_indexes'] ? 'yes' : 'no') . ")\n";
    }
    echo "\n";

    // Test 7: exists() check
    echo "Test 7: exists() Check\n";
    echo "======================\n";
    echo $service->exists('sales_summary') ? "✅ sales_summary exists\n" : "❌ Should exist\n";
    echo !$service->exists('non_existent') ? "✅ non_existent doesn't exist\n" : "❌ Should not exist\n";
    echo "\n";

    // Cleanup
    echo "Cleanup...\n";
    $pdo->exec("DROP TABLE IF EXISTS test_sales CASCADE");
    echo "✅ Test data cleaned up\n";

    echo "\n✅ All Materialized View tests passed!\n";
    echo "\nSummary:\n";
    echo "========\n";
    echo "✅ CREATE MATERIALIZED VIEW works\n";
    echo "✅ Materialized views store computed results\n";
    echo "✅ REFRESH MATERIALIZED VIEW updates data\n";
    echo "✅ REFRESH ... CONCURRENTLY works with unique index\n";
    echo "✅ Listing and checking existence works\n";

} catch (\Exception $e) {
    echo "❌ Error: " . $e->getMessage() . "\n";
    echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
    exit(1);
}
