<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type");

/**
 * Universal Upload & Compression Handler
 * Enforces size limits and processes images to reduce file size.
 */

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    die(json_encode(["success" => false, "message" => "Invalid request method."]));
}

// --- CONFIGURATION ---
$MAX_IMAGE_SIZE = 5 * 1024 * 1024; // 5MB
$MAX_DOC_SIZE = 5 * 1024 * 1024;  // 10MB

if (isset($_FILES["file"])) {
    $file = $_FILES["file"];
    $type = isset($_POST['type']) ? $_POST['type'] : 'image';
    $fileSize = $file["size"];
    $extension = strtolower(pathinfo($file["name"], PATHINFO_EXTENSION));

    // 1. Check for basic PHP upload errors (e.g., file too big for php.ini settings)
    if ($file['error'] !== UPLOAD_ERR_OK) {
        $errorMsg = "Upload failed.";
        switch ($file['error']) {
            case UPLOAD_ERR_INI_SIZE:
                $errorMsg = "File exceeds server upload_max_filesize directive.";
                break;
            case UPLOAD_ERR_FORM_SIZE:
                $errorMsg = "File exceeds MAX_FILE_SIZE specified in HTML form.";
                break;
            case UPLOAD_ERR_PARTIAL:
                $errorMsg = "File was only partially uploaded.";
                break;
            case UPLOAD_ERR_NO_FILE:
                $errorMsg = "No file was uploaded.";
                break;
        }
        die(json_encode(["success" => false, "message" => $errorMsg]));
    }

    // 2. Validate Size based on intended type
    if ($type === 'image') {
        if ($fileSize > $MAX_IMAGE_SIZE) {
            die(json_encode(["success" => false, "message" => "Image is too large. Maximum allowed size is 5MB."]));
        }
        $target_dir = "../assets/imgs/";
    } else {
        if ($fileSize > $MAX_DOC_SIZE) {
            die(json_encode(["success" => false, "message" => "Document is too large. Maximum allowed size is 10MB."]));
        }
        $target_dir = "../assets/docx/";
    }

    // 3. Ensure directory exists
    if (!file_exists($target_dir)) {
        mkdir($target_dir, 0777, true);
    }

    $fileName = time() . "_" . bin2hex(random_bytes(4)) . "." . $extension;
    $target_path = $target_dir . $fileName;

    // Allowed extensions
    $imageExtensions = ["jpg", "jpeg", "png", "webp"];
    $docExtensions = ["pdf", "doc", "docx", "xls", "xlsx"];

    // --- CASE A: DOCUMENTS ---
    if ($type === 'document') {
        if (!in_array($extension, $docExtensions)) {
            die(json_encode(["success" => false, "message" => "Invalid document format. Allowed: PDF, DOC, XLS."]));
        }
        if (move_uploaded_file($file["tmp_name"], $target_path)) {
            echo json_encode([
                "success" => true,
                "url" => "/assets/docx/" . $fileName,
                "size" => round($fileSize / 1024 / 1024, 2) . " MB"
            ]);
        }
        exit;
    }

    // --- CASE B: IMAGES (With Compression) ---
    if ($type === 'image') {
        if (!in_array($extension, $imageExtensions)) {
            die(json_encode(["success" => false, "message" => "Invalid image format. Allowed: JPG, PNG, WEBP."]));
        }

        $source_path = $file["tmp_name"];
        $optimized = compressAndResizeImage($source_path, $target_path, $extension);

        if ($optimized) {
            $newSize = filesize($target_path);
            echo json_encode([
                "success" => true,
                "message" => "Image optimized and uploaded.",
                "url" => "/assets/imgs/" . $fileName,
                "original_size" => round($fileSize / 1024, 2) . " KB",
                "compressed_size" => round($newSize / 1024, 2) . " KB"
            ]);
        } else {
            echo json_encode(["success" => false, "message" => "Image optimization failed."]);
        }
    }
} else {
    echo json_encode(["success" => false, "message" => "No file detected in request."]);
}

/**
 * Image Compression Engine
 * Resizes to 1920px max-width and applies 75% quality compression.
 */
function compressAndResizeImage($source, $destination, $ext)
{
    list($width, $height) = getimagesize($source);

    $max_width = 1920;
    $new_width = $width;
    $new_height = $height;

    if ($width > $max_width) {
        $new_width = $max_width;
        $new_height = floor($height * ($max_width / $width));
    }

    switch ($ext) {
        case 'jpeg':
        case 'jpg':
            $image = imagecreatefromjpeg($source);
            break;
        case 'png':
            $image = imagecreatefrompng($source);
            break;
        case 'webp':
            $image = imagecreatefromwebp($source);
            break;
        default:
            return false;
    }

    $canvas = imagecreatetruecolor($new_width, $new_height);

    if ($ext == 'png' || $ext == 'webp') {
        imagealphablending($canvas, false);
        imagesavealpha($canvas, true);
        $transparent = imagecolorallocatealpha($canvas, 255, 255, 255, 127);
        imagefill($canvas, 0, 0, $transparent);
    }

    imagecopyresampled($canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

    $success = false;
    switch ($ext) {
        case 'jpeg':
        case 'jpg':
            $success = imagejpeg($canvas, $destination, 75);
            break;
        case 'png':
            $success = imagepng($canvas, $destination, 7);
            break;
        case 'webp':
            $success = imagewebp($canvas, $destination, 75);
            break;
    }

    imagedestroy($image);
    imagedestroy($canvas);
    return $success;
}
