<?php
ini_set('max_execution_time', 300);
ini_set('memory_limit', '512M');

// Azure credentials
$endpoint = "https://shaikhocr.cognitiveservices.azure.com/vision/v3.2/read/analyze";
$subscription_key = "3nsmBKQOMz3KnJvalYrpoVWUObvdgqYSOnO0bovRjoDkx6xmXVy4JQQJ99BEACYeBjFXJ3w3AAAFACOGNiLO";

// Check upload
if (!isset($_FILES['image']) || $_FILES['image']['error'] != UPLOAD_ERR_OK) {
    http_response_code(400);
    echo "No file uploaded or upload error.";
    exit;
}

$file_path = $_FILES['image']['tmp_name'];
$file_data = file_get_contents($file_path);

// Manually detect content type based on file extension (instead of mime_content_type)
$ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
switch ($ext) {
    case 'pdf':
        $content_type = 'application/pdf';
        break;
    case 'jpg':
    case 'jpeg':
        $content_type = 'image/jpeg';
        break;
    case 'png':
        $content_type = 'image/png';
        break;
    default:
        $content_type = '';
        break;
}

// Validate file type
$allowed_types = ['application/pdf', 'image/jpeg', 'image/png'];
if (!in_array($content_type, $allowed_types)) {
    http_response_code(415);
    echo "Unsupported file type: $content_type";
    exit;
}

// Send to Azure Read API
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_POST, true);
$headers = [
    "Ocp-Apim-Subscription-Key: $subscription_key",
    "Content-Type: $content_type"
];

// PDFs require a custom header to work reliably
if ($content_type === 'application/pdf') {
    $headers[] = "Content-Length: " . strlen($file_data);
}

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $file_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);

$response = curl_exec($ch);
if (curl_errno($ch)) {
    http_response_code(500);
    echo "Curl error: " . curl_error($ch);
    exit;
}
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);

curl_close($ch);

// Extract polling URL
if (!preg_match('/Operation-Location:\s*(.+)/i', $header, $matches)) {
    http_response_code(500);
    echo "Failed to get Operation-Location header.";
    echo "\nHeaders:\n" . $header;
    exit;
}
$operation_url = trim($matches[1]);

// Poll for result
$max_retries = 15;
$retry_delay = 2;
for ($i = 0; $i < $max_retries; $i++) {
    sleep($retry_delay);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $operation_url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Ocp-Apim-Subscription-Key: $subscription_key"
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    curl_close($ch);

    $json = json_decode($result, true);
    if (isset($json['status'])) {
        if ($json['status'] === 'succeeded') {
            $text = "";
            foreach ($json['analyzeResult']['readResults'] as $page) {
                foreach ($page['lines'] as $line) {
                    $text .= $line['text'] . "\n";
                }
            }

            $text = str_replace("\r", "", $text);
            $text = preg_replace('/[ \t]+/', ' ', $text);

            $lines = array_filter(array_map('trim', explode("\n", $text)));
            $lines = array_values($lines);

            function extractPassportData($rawText)
            {
                $data = [];

                $lines = array_values(array_filter(array_map('trim', explode("\n", $rawText))));
                $lineCount = count($lines);

                /*=====================================================
                    MRZ PARSER (PRIMARY)
                =====================================================*/
                for ($i = 0; $i < $lineCount - 1; $i++) {

                    $mrz1 = strtoupper(trim($lines[$i]));
                    $mrz1 = preg_replace('/\s+/', '', $mrz1);

                    $mrz2 = strtoupper(trim($lines[$i + 1]));
                    $mrz2 = preg_replace('/\s+/', '', $mrz2);

                    if (preg_match('/^P</', $mrz1) && strlen($mrz2) >= 40) {

                        // Passport No
                        $data['Passport Number'] = preg_replace('/[^A-Z0-9]/', '', substr($mrz2, 0, 9));

                        // Nationality
                        $nat = substr($mrz2, 10, 3);

                        $country = [
                            "IND" => "INDIAN",
                            "PAK" => "PAKISTANI",
                            "BGD" => "BANGLADESHI",
                            "NPL" => "NEPALI",
                            "LKA" => "SRI LANKAN"
                        ];

                        $data['Nationality'] = $country[$nat] ?? $nat;

                        // DOB
                        $dob = substr($mrz2, 13, 6);

                        $yy = intval(substr($dob, 0, 2));
                        $year = ($yy > date('y')) ? "19$yy" : "20$yy";

                        $data['Date of Birth'] =
                            $year . "-" .
                            substr($dob, 2, 2) . "-" .
                            substr($dob, 4, 2);

                        // Gender
                        $data['Sex'] = substr($mrz2, 20, 1);

                        // Expiry
                        $exp = substr($mrz2, 21, 6);

                        $yy = intval(substr($exp, 0, 2));
                        $year = ($yy > date('y')) ? "19$yy" : "20$yy";

                        $data['Date of Expiry'] =
                            $year . "-" .
                            substr($exp, 2, 2) . "-" .
                            substr($exp, 4, 2);


                        /*=========================
                        ROBUST MRZ NAME PARSER
                        =========================*/

                        $name = substr($mrz1, 5);

                        // Remove spaces inserted by OCR
                        $name = preg_replace('/\s+/', '', $name);

                        // Replace ANY number of < with a single separator |
                        $name = preg_replace('/<+/', '|', $name);

                        // Remove duplicate separators
                        $name = preg_replace('/\|+/', '|', $name);

                        // Remove leading/trailing |
                        $name = trim($name, '|');

                        $parts = explode('|', $name);

                        $data['Surname'] = "";

                        $data['Given Names'] = "";

                        if (count($parts) > 0) {

                            $data['Surname'] = array_shift($parts);

                        }

                        if (count($parts) > 0) {

                            $data['Given Names'] = implode(" ", $parts);

                        }

                        break;
                    }
                }

                /*=====================================================
                        OCR PARSER (SECONDARY)
                =====================================================*/

                for ($i = 0; $i < $lineCount; $i++) {

                    $line = trim($lines[$i]);

                    if ($line == "")
                        continue;

                    /*---------------- Place of Birth ----------------*/

                    if (
                        stripos($line, 'Place of Birth') !== false ||
                        stripos($line, 'जन्म स्थान') !== false
                    ) {

                        if (isset($lines[$i + 1])) {

                            $birth = [];

                            for ($j = $i + 1; $j < $i + 4; $j++) {

                                if (!isset($lines[$j]))
                                    break;

                                if (
                                    stripos($lines[$j], "Place") !== false ||
                                    stripos($lines[$j], "Issue") !== false ||
                                    preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $lines[$j])
                                ) {
                                    break;
                                }

                                $birth[] = trim($lines[$j]);
                            }

                            $data['Place of Birth'] = strtoupper(
                                str_replace("/INDIAN", "", implode(" ", $birth))
                            );

                        }
                    }

                    /*---------------- Place of Issue ----------------*/

                    if (
                        stripos($line, 'Place of Issue') !== false ||
                        stripos($line, 'जारी करने का स्थान') !== false
                    ) {

                        if (isset($lines[$i + 1])) {

                            $issue = [];

                            for ($j = $i + 1; $j < $i + 3; $j++) {

                                if (!isset($lines[$j]))
                                    break;

                                if (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $lines[$j]))
                                    break;

                                $issue[] = trim($lines[$j]);
                            }

                            $data['Place of Issue'] = strtoupper(implode(" ", $issue));
                        }
                    }

                    /*---------------- Issue Date ----------------*/

                    if (preg_match('/(\d{2}\/\d{2}\/\d{4})/', $line, $m)) {

                        $data['Date of Issue'] = date(
                            'Y-m-d',
                            strtotime(str_replace('/', '-', $m[1]))
                        );

                    } else {

                        for ($j = $i + 1; $j < $i + 3; $j++) {

                            if (!isset($lines[$j]))
                                break;

                            if (preg_match('/(\d{2}\/\d{2}\/\d{4})/', $lines[$j], $m)) {

                                $data['Date of Issue'] = date(
                                    'Y-m-d',
                                    strtotime(str_replace('/', '-', $m[1]))
                                );

                                break;
                            }
                        }
                    }
                }

                /*=====================================================
                    FALLBACK DATE SCAN
                =====================================================*/

                if (!isset($data['Date of Issue'])) {

                    preg_match_all('/\d{2}\/\d{2}\/\d{4}/', $rawText, $dates);

                    if (isset($dates[0][1])) {

                        $data['Date of Issue'] = date(
                            'Y-m-d',
                            strtotime(str_replace('/', '-', $dates[0][1]))
                        );
                    }
                }

                return $data;
            }

            // echo "<pre>";
            // echo htmlspecialchars($text);
            // exit;
            $passportData = extractPassportData($text);
            header('Content-Type: application/json');
            echo json_encode($passportData, JSON_PRETTY_PRINT);
            exit;
        } elseif ($json['status'] === 'failed') {
            http_response_code(500);
            echo "OCR processing failed.";
            exit;
        }
    }
}

// Timeout
http_response_code(500);
echo "OCR processing timed out.";
?>