<?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";
                }
            }


            function extractPassportData($rawText)
            {
                $data = [];
                $lines = explode("\n", trim($rawText));
                $lineCount = count($lines);
                $foundPlaceOfIssueLabel = false;
                $dateMatches = [];

                for ($i = 0; $i < $lineCount; $i++) {
                    $line = trim($lines[$i]);

                    // Passport Number
                    if (!isset($data['Passport Number'])) {

                        // Passport number printed on passport (NOT MRZ)
                        if (
                            preg_match('/^[A-Z]{2}[0-9]{6}$/', $line) ||
                            preg_match('/^[A-Z][0-9]{7}$/', $line)
                        ) {

                            $data['Passport Number'] = trim($line);

                        }

                    }
                    // MRZ line for name
                    if (!isset($data['Surname']) && strpos($line, 'P<') === 0) {
                        $parts = explode('<<', substr($line, 2));
                        if (count($parts) >= 2) {
                            $surnameRaw = $parts[0];
                            $surname = substr($surnameRaw, 3);
                            $surname = str_replace('<', ' ', $surname);
                            $givenNames = str_replace('<', ' ', $parts[1]);
                            $data['Surname'] = trim($surname);
                            $data['Given Names'] = trim($givenNames);
                        }

                        // Nationality fallback from MRZ (e.g. IND)
                        if (!isset($data['Nationality'])) {

                            $isoCode = strtoupper(substr($line, 2, 3));

                            $isoCode = str_replace("1", "I", $isoCode);
                            $isoCode = str_replace("0", "O", $isoCode);

                            if (ctype_alpha($isoCode)) {
                                $country = [
                                    "IND" => "INDIAN",
                                    "PAK" => "PAKISTANI",
                                    "BGD" => "BANGLADESHI",
                                    "NPL" => "NEPALI",
                                    "LKA" => "SRI LANKAN"
                                ];

                                $data['Nationality'] = $country[$isoCode] ?? $isoCode;
                            }
                        }
                    }

                    // Capture all dates
                    if (preg_match_all('/\d{2}\/\d{2}\/\d{4}/', $line, $matches)) {
                        $dateMatches = array_merge($dateMatches, $matches[0]);
                    }


                    // Place of Birth
                    if (
                        stripos($line, 'PLACE OF BIRTH') !== false ||
                        stripos($line, 'OF BIRTH') !== false
                    ) {

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

                            $place = strtoupper(trim($lines[$i + 1]));

                            if (
                                $place != "" &&
                                strpos($place, "SEX") === false &&
                                strpos($place, "PLACE") === false &&
                                !preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $place)
                            ) {

                                $data["Place of Birth"] = $place;

                            }
                        }
                    }

                    // Place of Issue
                    if (!$foundPlaceOfIssueLabel) {
                        if (preg_match('/PLACE OF ISSUE[:\s]*([A-Z\s]+)/i', $line, $match)) {
                            $data['Place of Issue'] = strtoupper(trim($match[1]));
                        } elseif (stripos($line, 'PLACE OF ISSUE') !== false || stripos($line, 'जारी करने का स्थान') !== false) {
                            $foundPlaceOfIssueLabel = true;
                            continue;
                        }
                    } elseif ($foundPlaceOfIssueLabel && !empty($line)) {
                        if (!preg_match('/\d{2}\/\d{2}\/\d{4}/', $line) && strlen($line) > 1 && !in_array(strtoupper($line), ['M', 'F', 'MALE', 'FEMALE'])) {
                            $data['Place of Issue'] = strtoupper(trim($line));
                            $foundPlaceOfIssueLabel = false;
                        }
                    }


                    // Sex
                    if (!isset($data['Sex'])) {
                        if (stripos($line, 'Sex') !== false || stripos($line, 'Gender') !== false) {
                            if (preg_match('/\b(M|F|MALE|FEMALE)\b/i', $line, $match)) {
                                $data['Sex'] = strtoupper($match[1]);
                            } elseif (isset($lines[$i + 1]) && preg_match('/\b(M|F|MALE|FEMALE)\b/i', $lines[$i + 1], $match)) {
                                $data['Sex'] = strtoupper($match[1]);
                            }
                        } elseif (preg_match('/^\s*(M|F)\s*$/i', $line, $match)) {
                            $data['Sex'] = strtoupper($match[1]);
                        }
                    }
                }

                // Dates
                function convertDate($date)
                {
                    $p = explode('/', $date);

                    if (count($p) == 3) {
                        return $p[2] . "-" . $p[1] . "-" . $p[0];
                    }

                    return "";
                }

                if (isset($dateMatches[0])) {
                    $data['Date of Birth'] = convertDate($dateMatches[0]);
                }

                if (isset($dateMatches[1])) {
                    $data['Date of Issue'] = convertDate($dateMatches[1]);
                }

                if (isset($dateMatches[2])) {
                    $data['Date of Expiry'] = convertDate($dateMatches[2]);
                }

                // Passport Number Fix
                if (!empty($data['Passport Number'])) {

                    foreach ($lines as $l) {

                        if (preg_match('/^[A-Z]{2}[0-9]{6}$/', trim($l))) {

                            $data['Passport Number'] = trim($l);

                            break;
                        }

                        if (preg_match('/^[A-Z][0-9]{7}$/', trim($l))) {

                            $data['Passport Number'] = trim($l);

                            break;
                        }
                    }

                }

                // Default fallback
                if (!isset($data['Nationality'])) {
                    $data['Nationality'] = 'UNKNOWN';
                }

                /*--------------------------------------------------
                    FIX ISSUE DATE
                --------------------------------------------------*/

                if (!empty($data["Date of Expiry"])) {

                    $fix = false;

                    if (empty($data["Date of Issue"])) {

                        $fix = true;

                    } else {

                        $issue = strtotime($data["Date of Issue"]);
                        $expiry = strtotime($data["Date of Expiry"]);

                        $years = ($expiry - $issue) / (365.25 * 24 * 60 * 60);

                        if ($issue >= $expiry || $years < 4 || $years > 11) {
                            $fix = true;
                        }
                    }

                    if ($fix) {

                        $d = new DateTime($data["Date of Expiry"]);
                        $d->modify("-10 years");
                        $d->modify("+1 day");

                        $data["Date of Issue"] = $d->format("Y-m-d");

                    }
                }


                $fields = [
                    "Passport Number",
                    "Surname",
                    "Given Names",
                    "Nationality",
                    "Sex",
                    "Date of Birth",
                    "Date of Issue",
                    "Date of Expiry",
                    "Place of Birth",
                    "Place of Issue"
                ];

                foreach ($fields as $f) {
                    if (!isset($data[$f])) {
                        $data[$f] = "";
                    }
                }

                $data["_meta"] = [
                    "confidence" => 100,
                    "mrz_found" => true,
                    "ocr_found" => true
                ];


                /*-----------------------------------
    Passport No From MRZ
-----------------------------------*/

                foreach ($lines as $l) {

                    $l = trim($l);

                    // MRZ second line always starts with passport number
                    if (preg_match('/^[A-Z]{1,2}[0-9]{6,7}</', $l)) {

                        $data["Passport Number"] = substr($l, 0, strpos($l, "<"));

                        break;
                    }

                }




                // echo "<pre>";
                // print_r($lines);
                // exit;

                return $data;
            }


            $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.";
?>