<?php

declare(strict_types=1);

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

use App\Framework\QrCode\ErrorCorrection\ReedSolomonEncoder;
use App\Framework\QrCode\ValueObjects\EncodingMode;
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
use App\Framework\QrCode\ValueObjects\QrCodeVersion;

// Test data encoding step by step
$data = "HELLO";
$version = QrCodeVersion::fromNumber(1);
$errorLevel = ErrorCorrectionLevel::M;
$encodingMode = EncodingMode::BYTE;

echo "=== QR Code Data Encoding Debug ===\n";
echo "Data: '{$data}' (" . strlen($data) . " characters)\n";
echo "Version: {$version->getVersionNumber()}\n";
echo "Error Level: {$errorLevel->value}\n\n";

// Get EC info
$ecInfo = ReedSolomonEncoder::getECInfo(
    $version->getVersionNumber(),
    $errorLevel->value
);

echo "EC Info:\n";
echo "  Total codewords: {$ecInfo['totalCodewords']}\n";
echo "  Data codewords: {$ecInfo['dataCodewords']}\n";
echo "  EC codewords: {$ecInfo['ecCodewords']}\n";
echo "  Required bits: " . ($ecInfo['dataCodewords'] * 8) . "\n\n";

// Step-by-step encoding
$bits = '';

// 1. Mode indicator (4 bits) - Byte mode = 0100
$modeBits = $encodingMode->getModeBits();
$bits .= $modeBits;
echo "Step 1 - Mode indicator: {$modeBits} (4 bits)\n";
echo "  Bits so far: {$bits} (" . strlen($bits) . " bits)\n\n";

// 2. Character count (8 bits for version 1-9 byte mode)
$charCountBits = $encodingMode->getCharacterCountBits($version);
$dataLength = strlen($data);
$countBinary = str_pad(decbin($dataLength), $charCountBits, '0', STR_PAD_LEFT);
$bits .= $countBinary;
echo "Step 2 - Character count: {$dataLength}\n";
echo "  Binary: {$countBinary} ({$charCountBits} bits)\n";
echo "  Bits so far: {$bits} (" . strlen($bits) . " bits)\n\n";

// 3. Data bytes
echo "Step 3 - Data bytes:\n";
for ($i = 0; $i < $dataLength; $i++) {
    $char = $data[$i];
    $byte = ord($char);
    $byteBinary = str_pad(decbin($byte), 8, '0', STR_PAD_LEFT);
    $bits .= $byteBinary;
    echo "  '{$char}' (ASCII {$byte}): {$byteBinary}\n";
}
echo "  Bits so far: " . strlen($bits) . " bits\n\n";

// 4. Terminator
$requiredBits = $ecInfo['dataCodewords'] * 8;
$bitsBeforeTerminator = strlen($bits);
$terminatorLength = min(4, max(0, $requiredBits - strlen($bits)));
$bits .= str_repeat('0', $terminatorLength);
echo "Step 4 - Terminator:\n";
echo "  Required bits: {$requiredBits}\n";
echo "  Bits before terminator: {$bitsBeforeTerminator}\n";
echo "  Space remaining: " . ($requiredBits - $bitsBeforeTerminator) . " bits\n";
echo "  Terminator length: {$terminatorLength} bits\n";
echo "  Bits so far: " . strlen($bits) . " bits\n\n";

// 5. Pad to multiple of 8
$remainder = strlen($bits) % 8;
if ($remainder !== 0) {
    $paddingBits = 8 - $remainder;
    $bits .= str_repeat('0', $paddingBits);
    echo "Step 5 - Pad to byte boundary:\n";
    echo "  Remainder: {$remainder}\n";
    echo "  Added {$paddingBits} padding bits\n";
    echo "  Bits so far: " . strlen($bits) . " bits\n\n";
} else {
    echo "Step 5 - Already on byte boundary\n\n";
}

// 6. Add pad codewords
$padBytes = ['11101100', '00010001'];
$padIndex = 0;
$bitsBeforePadBytes = strlen($bits);
$padBytesAdded = 0;

echo "Step 6 - Add pad codewords:\n";
echo "  Required bits: {$requiredBits}\n";
echo "  Current bits: {$bitsBeforePadBytes}\n";
echo "  Bits needed: " . ($requiredBits - $bitsBeforePadBytes) . "\n\n";

while (strlen($bits) < $requiredBits) {
    $padByte = $padBytes[$padIndex % 2];
    $bits .= $padByte;
    $padBytesAdded++;
    echo "  Pad byte {$padBytesAdded}: {$padByte} (0x" . dechex(bindec($padByte)) . ")\n";
    $padIndex++;
}

echo "  Total pad bytes added: {$padBytesAdded}\n";
echo "  Final bits: " . strlen($bits) . " bits\n\n";

// 7. Convert to codewords
$codewords = [];
for ($i = 0; $i < strlen($bits); $i += 8) {
    $byte = substr($bits, $i, 8);
    $codewords[] = bindec($byte);
}

echo "Step 7 - Convert to codewords:\n";
echo "  Total codewords: " . count($codewords) . "\n";
echo "  Expected: {$ecInfo['dataCodewords']}\n\n";

echo "Codewords (hex):\n";
for ($i = 0; $i < count($codewords); $i++) {
    $hex = str_pad(dechex($codewords[$i]), 2, '0', STR_PAD_LEFT);
    $binary = str_pad(decbin($codewords[$i]), 8, '0', STR_PAD_LEFT);
    echo sprintf("  [%2d] 0x%s  %s  (%d)\n", $i, $hex, $binary, $codewords[$i]);
}

echo "\n=== Result ===\n";
echo "Generated: " . count($codewords) . " data codewords\n";
echo "Expected: {$ecInfo['dataCodewords']} data codewords\n";

if (count($codewords) === $ecInfo['dataCodewords']) {
    echo "✅ CORRECT!\n";
} else {
    echo "❌ MISMATCH!\n";
}
