import { englishPage } from "./language"

// Instantiate the WebAssembly module with 32MB of memory.
const wasm = require('./resizer.wasm', {memory: new WebAssembly.Memory({initial: 1024})})
const resizer = wasm.exports

async function handleRequest(request) {
    let {pathname, host} = new URL(request.url.toLowerCase())
    if (pathname.endsWith('/'))  pathname = pathname.substring(0, pathname.length - 1)

    if (pathname === '/wasm-resizer.html') {
        let page = englishPage(request) ? HOMEPAGE_EN : HOMEPAGE
        page = page.replace('$[{host}]', host)
        return new Response(page, {headers: {"Content-Type": "text/html; charset=utf-8"}})
    } else {
        return handleResize(request)
    }
}

async function handleResize(request) {
    const requestJSON = await request.json()
    if (!requestJSON.url) {
      return new Response('Please enter the image URL!')
    }
    const width = parseInt(requestJSON.width)
    if (isNaN(width) || width <= 0) {
      return new Response('Please enter a valid width!')
    }

    const headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
                     'Accept': '*/*'}
    let response = await fetch(requestJSON.url, {cdnProxy: false, headers})

    // Check if the response is an image. If not, we'll just return it.
    let type = response.headers.get("Content-Type") || ""
    if (!type.startsWith("image/")) {
        return new Response('The response is not an image!')
    }

    // OK, we're going to resize. First, read the image data into memory.
    let bytes = new Uint8Array(await response.arrayBuffer())

    // Call our WebAssembly module's init() function to allocate space for the image.
    let ptr = resizer.init(bytes.byteLength)

    // Copy the image into WebAssembly memory.
    const memoryBytes = new Uint8Array(wasm.env.memory.buffer)
    memoryBytes.set(bytes, ptr)

    // Call our WebAssembly module's resize() function to perform the resize.
    let newSize = resizer.resize(bytes.byteLength, width)

    if (newSize == 0) {
        return new Response(`Resizing failed!`);
    }

    // Extract the result bytes from WebAssembly memory.
    let resultBytes = memoryBytes.slice(ptr, ptr + newSize)

    // Create a new response with the image bytes. Our resizer module always
    // outputs JPEG regardless of input type, so change the header.
    return new Response(resultBytes.buffer, {headers: {"Content-Type": "image/jpeg"}})
}



const HOMEPAGE_EN = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Resize Image</title>
    <style>
        body {
            background-color: #f3f3f3;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            font-family: Arial, sans-serif;
        }

        .container {
            border: 1px solid #ccc;
            padding: 20px;
            background-color: #fff;
        }

        .input-container {
            margin-bottom: 20px;
        }

        .input-container label {
            display: block;
            margin-bottom: 5px;
        }

        .input-container input {
            width: 420px;
            padding: 5px;
            font-size: 14px;
        }

        .button {
            background-color: #0088cc;
            color: #fff;
            padding: 10px;
            border: none;
            cursor: pointer;
            border-radius: 4px;
            font-size: 14px;
        }

        .image-container {
            margin-top: 20px;
        }

        .image-container img {
            max-width: 100%;
            height: auto;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="input-container">
            <label for="imageUrl">Original Image URL (Our nodes may not be able to access it)</label>
            <input type="text" id="imageUrl" value="http://$[{host}]/ECA-test/pet-shop-website-template/img/about.jpg">
        </div>
        <div class="input-container">
            <label for="imageWidth">Resized Width (Must be less than the original width)</label>
            <input type="text" id="imageWidth" value="365">
        </div>
        <button class="button" onclick="adjustImageSize()">Resize</button>
        <div class="image-container" id="resultContainer"></div>
    </div>

    <script>
        function adjustImageSize() {
            var resultContainer = document.getElementById("resultContainer");
            resultContainer.innerHTML = "";
            
            var imageUrl = document.getElementById("imageUrl").value;
            var imageWidth = document.getElementById("imageWidth").value;
            var data = {
                url: imageUrl,
                width: imageWidth
            };

            fetch("/wasm-resizer", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify(data)
            })
            .then(response => {
                if (response.headers.has("content-type") && response.headers.get("content-type").startsWith("image/")) {
                    return response.blob();
                } else {
                    return response.text();
                }
            })
            .then(result => {
                if (result instanceof Blob) {
                    var url = URL.createObjectURL(result);
                    var image = document.createElement("img");
                    image.src = url;
    
                    var resultContainer = document.getElementById("resultContainer");
                    resultContainer.innerHTML = "";
                    resultContainer.appendChild(image);
                } else {
                    var resultContainer = document.getElementById("resultContainer");
                    resultContainer.innerHTML = result;
                }
            })
            .catch(error => {
                alert(error);
            });
        }
    </script>
</body>
</html>
`
                    
addEventListener("fetch", event => {
    return event.respondWith(handleRequest(event.request))
})