<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Processor By Vine</title>
    <style>
        body {
            font-family: sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-color: #f4f4f4;
        }

        .container {
            background-color: #fff;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            text-align: center;
        }

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

        input[type="file"] {
            display: none;
        }

        label {
            background-color: #3498db;
            color: #fff;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
        }

        label:hover {
            background-color: #2980b9;
        }

        .progress-container {
            margin-bottom: 20px;
            display: none;
        }

        progress {
            width: 100%;
            height: 20px;
            border-radius: 5px;
        }

        #progressLabel {
            margin-left: 10px;
        }

        button {
            background-color: #2ecc71;
            color: #fff;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
            margin-bottom: 20px;
        }

        button:disabled {
            background-color: #bdc3c7;
            cursor: default;
        }

        button:hover:not(:disabled) {
            background-color: #27ae60;
        }

        #status {
            margin-top: 10px;
            font-size: 0.9em;
            color: #555;
        }

        .error {
            color: red;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Image Processor By Vine</h1>
        <div class="upload-container">
            <input type="file" id="zipFileInput" accept=".zip" />
            <label for="zipFileInput">Choose a ZIP File</label>
        </div>
        <div class="progress-container">
            <progress id="progressBar" value="0" max="100"></progress>
            <span id="progressLabel">0%</span>
        </div>
        <button id="processButton" disabled>Process ZIP</button>
        <div id="status"></div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>

    <script>
        const zipFileInput = document.getElementById('zipFileInput');
        const processButton = document.getElementById('processButton');
        const progressBar = document.getElementById('progressBar');
        const progressLabel = document.getElementById('progressLabel');
        const statusDiv = document.getElementById('status');
        const progressContainer = document.querySelector('.progress-container');

        let selectedZip = null;

        zipFileInput.addEventListener('change', (event) => {
            selectedZip = event.target.files[0];
            if (selectedZip) {
                processButton.disabled = false;
                statusDiv.textContent = `Selected: ${selectedZip.name}`;
            } else {
                processButton.disabled = true;
                statusDiv.textContent = '';
            }
        });

        processButton.addEventListener('click', async () => {
            if (!selectedZip) return;

            processButton.disabled = true;
            progressContainer.style.display = 'block';
            progressBar.value = 0;
            progressLabel.textContent = '0%';
            statusDiv.textContent = 'Processing...';

            try {
                const newZip = await processZip(selectedZip);
                const outputFilename = selectedZip.name.replace('.zip', '') + ' [CUT].zip';

                saveAs(newZip, outputFilename);

                statusDiv.textContent = 'Processing complete! File downloaded.';
            } catch (error) {
                statusDiv.innerHTML = `<span class="error">Error: ${error.message}</span>`;
                console.error(error);
            } finally {
                processButton.disabled = false;
                progressBar.value = 0;
                progressLabel.textContent = '0%';
            }
        });

        async function processZip(zipFile) {
            const zip = await JSZip.loadAsync(zipFile);
            const newZip = new JSZip();

            const imageFiles = Object.values(zip.files)
                .filter(file => !file.dir && file.name.match(/\.(jpg|jpeg|png|gif)$/i))
                .sort((a, b) => a.name.localeCompare(b.name));

            const totalImages = imageFiles.length;
            let processedImages = 0;
            let pageCounter = 1;

            for (const file of imageFiles) {
                try {
                    const imgData = await file.async('blob');
                    const img = await loadImage(imgData);

                    if (img.height > 5000) {
                        const cutImages = await cutImage(img);
                        let partCounter = 1;
                        for (const cutImg of cutImages) {
                            const newFilename = `Page ${pageCounter}_${partCounter}.jpg`;
                            newZip.file(newFilename, cutImg, { base64: true });
                            partCounter++;
                        }
                    } else {
                        const newFilename = `Page ${pageCounter}.jpg`;
                        newZip.file(newFilename, imgData, { base64: true });
                    }

                    pageCounter++;
                } catch (error) {
                    throw new Error(`Error processing image ${file.name}: ${error.message}`);
                } finally {
                    processedImages++;
                    const progress = Math.round((processedImages / totalImages) * 100);
                    progressBar.value = progress;
                    progressLabel.textContent = `${progress}%`;
                }
            }

            return newZip.generateAsync({ type: 'blob' });
        }

        async function loadImage(imgData) {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.onload = () => resolve(img);
                img.onerror = (error) => reject(new Error('Failed to load image'));
                img.src = URL.createObjectURL(imgData);
            });
        }

        async function cutImage(img) {
            return new Promise((resolve) => {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                const MAX_HEIGHT = 5000;
                const numParts = Math.ceil(img.height / MAX_HEIGHT);

                const cutImages = [];
                let startY = 0;

                for (let i = 0; i < numParts; i++) {
                    const partCanvas = document.createElement('canvas');
                    const partCtx = partCanvas.getContext('2d');

                    const partHeight = Math.min(MAX_HEIGHT, img.height - startY);
                    partCanvas.width = img.width;
                    partCanvas.height = partHeight;

                    partCtx.drawImage(
                        img,
                        0, startY, img.width, partHeight,
                        0, 0, img.width, partHeight
                    );

                    partCanvas.toBlob((blob) => {
                        cutImages.push(blob);
                        if (cutImages.length === numParts) {
                            resolve(cutImages);
                        }
                    }, 'image/jpeg', 0.95);

                    startY += partHeight;
                }
            });
        }
    </script>
</body>
</html>