<?php
declare(strict_types=1);

$uploadDir   = __DIR__ . '/uploads/';
$tempDir     = __DIR__ . '/uploads/tmp/';
$maxFileSize = 6 * 1024 * 1024; // سقف محافظه‌کارانه

foreach ([$uploadDir, $tempDir] as $dir) {
    if (!is_dir($dir) && !mkdir($dir, 0775, true)) {
        http_response_code(500);
        exit('DIR_FAIL');
    }
}

$deviceId    = preg_replace('/[^a-zA-Z0-9_-]/', '_', $_GET['device_id'] ?? '');
$chunkIndex  = (int)($_GET['chunk_index'] ?? -1);
$totalChunks = (int)($_GET['total_chunks'] ?? 0);
$chunkSize   = (int)($_GET['chunk_size'] ?? 0);
$fileSize    = (int)($_GET['file_size'] ?? 0);
$isFinal     = (int)($_GET['final'] ?? 0) === 1;

if ($deviceId === '' || $chunkIndex < 0 || $totalChunks <= 0 || $fileSize <= 0) {
    http_response_code(400);
    exit('PARAM_FAIL');
}

if ($fileSize > $maxFileSize || $chunkSize <= 0 || $chunkSize > $maxFileSize) {
    http_response_code(400);
    exit('SIZE_FAIL');
}

$contentLength = (int)($_SERVER['CONTENT_LENGTH'] ?? 0);
$raw = file_get_contents('php://input');

if ($raw === false || $contentLength !== strlen($raw) || $contentLength !== $chunkSize) {
    http_response_code(400);
    exit('READ_FAIL');
}

$sessionDir = $tempDir . $deviceId . '_' . md5((string)$fileSize) . '/';
if (!is_dir($sessionDir) && !mkdir($sessionDir, 0775, true)) {
    http_response_code(500);
    exit('TMP_FAIL');
}

$chunkPath = $sessionDir . sprintf('chunk_%05d.bin', $chunkIndex);
if (file_exists($chunkPath)) {
    http_response_code(409);
    exit('DUP_CHUNK');
}

if (file_put_contents($chunkPath, $raw, LOCK_EX) === false) {
    http_response_code(500);
    exit('WRITE_FAIL');
}

$receivedChunks = glob($sessionDir . 'chunk_*.bin');
if ($isFinal) {
    if (count($receivedChunks) !== $totalChunks) {
        http_response_code(409);
        exit('CHUNK_MISMATCH');
    }

    $outputName = sprintf('IMG_%s_%s.jpg', $deviceId, date('Ymd_His'));
    $outputPath = $uploadDir . $outputName;
    $fp = fopen($outputPath, 'wb');

    if (!$fp) {
        http_response_code(500);
        exit('OPEN_FAIL');
    }

    for ($i = 0; $i < $totalChunks; $i++) {
        $path = $sessionDir . sprintf('chunk_%05d.bin', $i);
        if (!file_exists($path)) {
            fclose($fp);
            http_response_code(409);
            exit('MISSING_CHUNK');
        }
        $data = file_get_contents($path);
        fwrite($fp, $data);
    }
    fclose($fp);

    // پاکسازی
    array_map('unlink', glob($sessionDir . 'chunk_*.bin'));
    rmdir($sessionDir);

    http_response_code(200);
    echo $outputName;
    exit;
}

http_response_code(202);
echo 'CHUNK_OK';
