<?php
/**
 * Diagnostic Script — Run on server to verify processing works
 * 
 * Usage: php app/cron/diagnose.php
 */

declare(strict_types=1);

require_once __DIR__ . '/../bootstrap/init.php';

use App\Core\Database;

echo "=== Musadaq Processing Diagnostics ===\n";
echo "Time: " . date('Y-m-d H:i:s') . "\n";
echo "PHP: " . PHP_VERSION . "\n";
echo "SAPI: " . php_sapi_name() . "\n\n";

// 1. Check DB connection
echo "--- Database ---\n";
try {
    $db = Database::getInstance();
    echo "  ✓ Database connected\n";
} catch (\Throwable $e) {
    echo "  ✗ Database FAILED: " . $e->getMessage() . "\n";
    exit(1);
}

// 2. Check pending queue items
echo "\n--- Queue Status ---\n";
$stmt = $db->query("SELECT status, COUNT(*) as cnt FROM invoice_processing_queue GROUP BY status");
$rows = $stmt->fetchAll();
if (empty($rows)) {
    echo "  (empty — no items in queue at all)\n";
} else {
    foreach ($rows as $r) {
        echo "  {$r['status']}: {$r['cnt']}\n";
    }
}

// 3. Check batch statuses
echo "\n--- Batch Status ---\n";
$stmt = $db->query("SELECT status, COUNT(*) as cnt FROM invoice_batches GROUP BY status");
$rows = $stmt->fetchAll();
if (empty($rows)) {
    echo "  (empty — no batches)\n";
} else {
    foreach ($rows as $r) {
        echo "  {$r['status']}: {$r['cnt']}\n";
    }
}

// 4. Check for stuck items (processing but no worker)
echo "\n--- Stuck Items (processing for >5 minutes) ---\n";
$stmt = $db->query("
    SELECT q.id, q.batch_id, q.status, q.image_path, q.created_at, q.error_message
    FROM invoice_processing_queue q
    WHERE q.status IN ('pending', 'processing')
    ORDER BY q.created_at DESC
    LIMIT 10
");
$stuck = $stmt->fetchAll();
if (empty($stuck)) {
    echo "  (none — all clear)\n";
} else {
    foreach ($stuck as $s) {
        $exists = file_exists($s['image_path']) ? '✓ file exists' : '✗ FILE MISSING';
        echo "  ID={$s['id']} | Status={$s['status']} | $exists\n";
        echo "    Path: {$s['image_path']}\n";
        if ($s['error_message']) echo "    Error: {$s['error_message']}\n";
    }
}

// 5. Check lock file
echo "\n--- Lock File ---\n";
$lockFile = STORAGE_PATH . '/logs/process_batches.lock';
if (file_exists($lockFile)) {
    $age = time() - filemtime($lockFile);
    $content = trim(file_get_contents($lockFile));
    echo "  ⚠ Lock file EXISTS (age: {$age}s, content: $content)\n";
    if ($age > 300) {
        echo "  → This lock is STALE. Removing...\n";
        @unlink($lockFile);
        echo "  ✓ Removed.\n";
    }
} else {
    echo "  ✓ No lock file (good)\n";
}

// 6. Check key files
echo "\n--- Key Files ---\n";
$files = [
    'InvoiceProcessor' => APP_PATH . '/Services/InvoiceProcessor.php',
    'AI' => APP_PATH . '/Core/AI.php',
    'process_batches' => APP_PATH . '/cron/process_batches.php',
    'worker.log' => STORAGE_PATH . '/logs/worker.log',
];
foreach ($files as $name => $path) {
    if (file_exists($path)) {
        echo "  ✓ $name: $path (" . filesize($path) . " bytes)\n";
    } else {
        echo "  ✗ $name: MISSING — $path\n";
    }
}

// 7. Check Gemini API key
echo "\n--- Configuration ---\n";
$apiKey = env('GEMINI_API_KEY');
echo "  GEMINI_API_KEY: " . ($apiKey ? "✓ Set (" . strlen($apiKey) . " chars)" : "✗ MISSING!") . "\n";
echo "  APP_DEBUG: " . env('APP_DEBUG', 'false') . "\n";
echo "  fastcgi_finish_request: " . (function_exists('fastcgi_finish_request') ? '✓ Available' : '✗ Not available (CLI mode)') . "\n";

// 8. Show last lines of worker.log
echo "\n--- Last 20 lines of worker.log ---\n";
$workerLog = STORAGE_PATH . '/logs/worker.log';
if (file_exists($workerLog)) {
    $lines = file($workerLog);
    $last = array_slice($lines, -20);
    foreach ($last as $line) {
        echo "  " . rtrim($line) . "\n";
    }
} else {
    echo "  (worker.log does not exist yet)\n";
}

// 9. Try to reset any stuck 'processing' items back to 'pending'
echo "\n--- Fix Stuck Items? ---\n";
$stmt = $db->query("SELECT COUNT(*) FROM invoice_processing_queue WHERE status = 'processing'");
$stuckCount = (int)$stmt->fetchColumn();
if ($stuckCount > 0) {
    echo "  Found $stuckCount items stuck in 'processing' state.\n";
    $db->query("UPDATE invoice_processing_queue SET status = 'pending' WHERE status = 'processing'");
    echo "  ✓ Reset them to 'pending' so they can be reprocessed.\n";
} else {
    echo "  ✓ No stuck items.\n";
}

echo "\n=== Diagnostics Complete ===\n";
echo "Next step: Run 'php app/cron/process_batches.php' to process pending items.\n";
