<?php
/**
 * Fix mojibake in app.js by reversing double-encoding.
 * 
 * The encoding chain was:
 *   Original Thai text (UTF-8 bytes) 
 *   → interpreted as ISO-8859-1/Latin1 (each byte becomes a codepoint)
 *   → re-encoded to UTF-8
 * 
 * To fix: for each character in the file, if its codepoint is 0x00-0xFF,
 * map it back to the raw byte value. Then check if the resulting bytes
 * form valid UTF-8. If yes, use the fixed version. If no, keep original.
 * 
 * We process the file in "runs" - sequences of characters where ALL codepoints
 * are <= 0xFF (potential double-encoded sequences).
 */

// First, restore from backup
copy('app_backup.js', 'app.js');
echo "Restored app.js from backup\n";

$content = file_get_contents('app.js');

// Strategy: Process character by character. 
// Build up a "candidate" buffer of characters with codepoints <= 0xFF.
// When we hit a character with codepoint > 0xFF OR end of candidate sequence,
// try to decode the candidate buffer.

$output = '';
$candidate = ''; // UTF-8 encoded candidate text
$candidateBytes = ''; // Raw bytes after reversing the encoding
$fixCount = 0;
$len = mb_strlen($content, 'UTF-8');

for ($i = 0; $i < $len; $i++) {
    $char = mb_substr($content, $i, 1, 'UTF-8');
    $cp = mb_ord($char, 'UTF-8');
    
    if ($cp <= 0xFF && $cp >= 0x80) {
        // This character has a codepoint in Latin1 extended range (0x80-0xFF)
        // It's potentially a double-encoded byte
        $candidate .= $char;
        $candidateBytes .= chr($cp);
    } else {
        // Flush candidate if we have one
        if ($candidateBytes !== '') {
            // Try to interpret candidateBytes as UTF-8
            if (mb_check_encoding($candidateBytes, 'UTF-8')) {
                // Valid UTF-8! Check if it contains Thai
                $decoded = mb_convert_encoding($candidateBytes, 'UTF-8', 'UTF-8');
                $hasThai = preg_match('/[\x{0E00}-\x{0E7F}]/u', $decoded);
                $hasTypographic = preg_match('/[\x{2000}-\x{206F}]/u', $decoded);
                if ($hasThai || $hasTypographic) {
                    $output .= $decoded;
                    $fixCount += mb_strlen($candidate, 'UTF-8');
                } else {
                    $output .= $candidate; // Keep original
                }
            } else {
                $output .= $candidate; // Keep original, not valid UTF-8
            }
            $candidate = '';
            $candidateBytes = '';
        }
        $output .= $char;
    }
}

// Flush final candidate
if ($candidateBytes !== '') {
    if (mb_check_encoding($candidateBytes, 'UTF-8')) {
        $decoded = mb_convert_encoding($candidateBytes, 'UTF-8', 'UTF-8');
        $hasThai = preg_match('/[\x{0E00}-\x{0E7F}]/u', $decoded);
        if ($hasThai) {
            $output .= $decoded;
            $fixCount += mb_strlen($candidate, 'UTF-8');
        } else {
            $output .= $candidate;
        }
    } else {
        $output .= $candidate;
    }
}

file_put_contents('app.js', $output);
echo "Fixed $fixCount double-encoded character positions\n";

// Verify by checking a few key lines
$verifyLines = file('app.js');
echo "\n=== Verification ===\n";
$checkLines = [12, 15, 16, 17, 32];
foreach ($checkLines as $ln) {
    echo "Line $ln: " . trim($verifyLines[$ln - 1]) . "\n";
}
