<?php

declare(strict_types=1);

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\QrCode\QrCodeGenerator;
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
use App\Framework\QrCode\ValueObjects\QrCodeConfig;
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
use App\Framework\QrCode\ValueObjects\EncodingMode;

echo "=== Visual QR Code Matrix Analysis ===\n\n";

$data = "HELLO WORLD";
$config = new QrCodeConfig(
    version: QrCodeVersion::fromNumber(1),
    errorCorrectionLevel: ErrorCorrectionLevel::M,
    encodingMode: EncodingMode::BYTE
);

$matrix = QrCodeGenerator::generate($data, $config);
$size = $matrix->getSize();

echo "Data: '{$data}'\n";
echo "Size: {$size}x{$size}\n\n";

// Ausgabe als copy-pasteable Matrix für Online-Decoder
echo "=== Matrix für Online QR Decoder (https://zxing.org/w/decode) ===\n\n";

// Top border
for ($i = 0; $i < $size + 8; $i++) echo "░░";
echo "\n";

for ($i = 0; $i < 4; $i++) {
    for ($j = 0; $j < $size + 8; $j++) echo "░░";
    echo "\n";
}

for ($row = 0; $row < $size; $row++) {
    echo "░░░░░░░░"; // Left quiet zone (4 modules)
    for ($col = 0; $col < $size; $col++) {
        echo $matrix->getModuleAt($row, $col)->isDark() ? '██' : '░░';
    }
    echo "░░░░░░░░\n"; // Right quiet zone (4 modules)
}

for ($i = 0; $i < 4; $i++) {
    for ($j = 0; $j < $size + 8; $j++) echo "░░";
    echo "\n";
}

// Bottom border
for ($i = 0; $i < $size + 8; $i++) echo "░░";
echo "\n\n";

// Prüfe spezifische kritische Punkte
echo "=== Kritische Strukturen ===\n\n";

// 1. Finder Pattern Check (Top-Left)
echo "Top-Left Finder Pattern (0-6, 0-6):\n";
for ($row = 0; $row < 7; $row++) {
    for ($col = 0; $col < 7; $col++) {
        echo $matrix->getModuleAt($row, $col)->isDark() ? '██' : '░░';
    }
    echo "\n";
}
echo "\n";

// Expected pattern
echo "Expected Finder Pattern:\n";
$expected = [
    "███████████████",
    "██░░░░░░░░░░██",
    "██░░██████░░██",
    "██░░██████░░██",
    "██░░██████░░██",
    "██░░░░░░░░░░██",
    "███████████████",
];
foreach ($expected as $line) {
    echo $line . "\n";
}
echo "\n";

// 2. Separator Check (Row 7, columns 0-7)
echo "Separator (Row 7, cols 0-7): ";
for ($col = 0; $col < 8; $col++) {
    echo $matrix->getModuleAt(7, $col)->isDark() ? '1' : '0';
}
echo " (should be 00000000)\n\n";

// 3. Format Information (Row 8)
echo "Format Information (Row 8, critical positions):\n";
$formatCols = [0, 1, 2, 3, 4, 5, 7, 8, 20, 19, 18, 17, 16, 15, 14];
$formatBits = '';
foreach ($formatCols as $col) {
    $bit = $matrix->getModuleAt(8, $col)->isDark() ? '1' : '0';
    $formatBits .= $bit;
    echo "Col {$col}: {$bit}\n";
}
echo "\nCombined: {$formatBits}\n";
echo "Expected for Mask 7, Level M: 100101010100000\n";
echo ($formatBits === '100101010100000' ? "✅ MATCH" : "❌ MISMATCH") . "\n\n";

// 4. Timing Pattern
echo "Timing Pattern Check:\n";
echo "Row 6: ";
for ($col = 8; $col < 13; $col++) {
    echo $matrix->getModuleAt(6, $col)->isDark() ? '1' : '0';
}
echo " (should be 10101)\n";

echo "Col 6: ";
for ($row = 8; $row < 13; $row++) {
    echo $matrix->getModuleAt($row, 6)->isDark() ? '1' : '0';
}
echo " (should be 10101)\n\n";

// 5. Dark Module
echo "Dark Module (13, 8): ";
echo $matrix->getModuleAt(13, 8)->isDark() ? '✅ Dark' : '❌ Light';
echo "\n\n";

// Gebe die ersten 20 Data-Bits aus (nach unmask)
echo "=== First 20 Data Bits (unmasked) ===\n";

function applyMask(int $row, int $col, int $mask): bool
{
    return match ($mask) {
        7 => ((($row + $col) % 2) + (($row * $col) % 3)) % 2 === 0,
        default => false
    };
}

function isOccupied(int $row, int $col, int $size): bool
{
    if (
        ($row <= 8 && $col <= 8) ||
        ($row <= 7 && $col >= $size - 8) ||
        ($row >= $size - 8 && $col <= 7)
    ) {
        return true;
    }
    if ($row === 6 || $col === 6) return true;
    if ($row === 13 && $col === 8) return true;
    if ($row === 8 || $col === 8) return true;
    return false;
}

$dataBits = '';
$count = 0;

for ($col = $size - 1; $col >= 1 && $count < 20; $col -= 2) {
    if ($col === 6) $col--;

    $upward = ((int)(($size - 1 - $col) / 2) % 2) === 0;

    for ($i = 0; $i < $size && $count < 20; $i++) {
        $row = $upward ? ($size - 1 - $i) : $i;

        for ($c = 0; $c < 2 && $count < 20; $c++) {
            $currentCol = $col - $c;

            if (isOccupied($row, $currentCol, $size)) continue;

            $module = $matrix->getModuleAt($row, $currentCol);
            $bit = $module->isDark() ? 1 : 0;

            if (applyMask($row, $currentCol, 7)) {
                $bit = $bit === 1 ? 0 : 1;
            }

            $dataBits .= $bit;
            $count++;

            echo sprintf("Bit %2d at (%2d,%2d): %d\n", $count, $row, $currentCol, $bit);
        }
    }
}

echo "\nFirst 20 bits: {$dataBits}\n";
echo "Expected:      01000000101101001000 (Mode + CharCount start)\n";
echo "Breakdown:\n";
echo "  0100       - Byte mode\n";
echo "  00001011   - Character count (11)\n";
echo "  01001000   - 'H' (start)\n";
