<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upload Large File - File-to-Link Bot</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <script>
        // Anti-Debug Protection
        (function(){
            function preventDevTools() {
                // Detect DevTools
                const devtools = {
                    isOpen: false,
                    orientation: undefined
                };

                const threshold = 160;

                // Detect DevTools by window size
                const emitEvent = (isOpen, orientation) => {
                    window.dispatchEvent(new CustomEvent('devtoolschange', {
                        detail: {
                            isOpen,
                            orientation
                        }
                    }));
                };

                setInterval(() => {
                    const widthThreshold = window.outerWidth - window.innerWidth > threshold;
                    const heightThreshold = window.outerHeight - window.innerHeight > threshold;
                    const orientation = widthThreshold ? 'vertical' : 'horizontal';

                    if (
                        !(heightThreshold && widthThreshold) &&
                        ((window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized) || widthThreshold || heightThreshold)
                    ) {
                        if (!devtools.isOpen || devtools.orientation !== orientation) {
                            emitEvent(true, orientation);
                        }
                        devtools.isOpen = true;
                        devtools.orientation = orientation;
                    } else {
                        if (devtools.isOpen) {
                            emitEvent(false, undefined);
                        }
                        devtools.isOpen = false;
                        devtools.orientation = undefined;
                    }
                }, 500);

                // Prevent right-click
                document.addEventListener('contextmenu', e => e.preventDefault());

                // Prevent keyboard shortcuts
                document.addEventListener('keydown', function(e) {
                    // Prevent: Ctrl + Shift + I, Ctrl + Shift + J, Ctrl + U
                    if (
                        e.ctrlKey && e.shiftKey && (e.keyCode === 73 || e.keyCode === 74) ||
                        e.ctrlKey && e.keyCode === 85
                    ) {
                        e.preventDefault();
                    }
                });

                // Prevent copy
                document.addEventListener('copy', function(e) {
                    e.preventDefault();
                });

                // Clear console
                console.clear();
                console.debug = console.log = console.info = console.error = console.warn = function() {};
            }

            // Run protection
            preventDevTools();
        })();

        // Security token generation
        function generateSecurityToken() {
            const timestamp = Date.now();
            const random = Math.random().toString(36).substring(7);
            return btoa(`${timestamp}:${random}`);
        }

        // Add auth token and security headers to all API requests
        const authToken = "{{ auth_token }}";
        
        function securedFetch(url, options = {}) {
            const securityToken = generateSecurityToken();
            const headers = {
                ...options.headers,
                'X-Custom-Auth': authToken,
                'X-Security-Timestamp': Date.now().toString(),
                'X-Request-ID': crypto.randomUUID()
            };

            return fetch(url, {
                ...options,
                headers
            });
        }
    </script>
</head>
<body class="bg-gray-50 min-h-screen">
    <div class="container mx-auto px-4 py-8 max-w-3xl">
        <div class="bg-white rounded-lg shadow-lg p-6 md:p-8">
            <div class="text-center mb-8">
                <h1 class="text-2xl font-bold text-gray-900 mb-2">Large File Upload</h1>
                <p class="text-gray-600">Maximum file size: {{ human_readable_size(max_size) }}</p>
                <div class="mt-4 p-4 bg-blue-50 rounded-lg">
                    <p class="text-blue-800 font-medium mb-2">⚡ Important Information:</p>
                    <ul class="text-sm text-blue-700 space-y-1">
                        <li>• This upload link will expire in <span id="countdown" class="font-semibold"></span> if not used</li>
                        <li>• Once you start uploading, take as much time as you need</li>
                        <li>• The upload process will continue even after the link expires</li>
                        <li>• Large files may take longer to upload depending on your internet speed</li>
                    </ul>
                </div>
            </div>

            <div class="mb-8">
                <div id="dropzone" class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center cursor-pointer hover:border-blue-500 transition-colors">
                    <i class="fas fa-cloud-upload-alt text-4xl text-gray-400 mb-4"></i>
                    <p class="text-gray-600 mb-2">Drag and drop your file here</p>
                    <p class="text-sm text-gray-500">or</p>
                    <button type="button" id="browse-btn" class="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
                        Browse Files
                    </button>
                </div>
            </div>

            <form id="upload-form" class="hidden">
                <input type="file" id="file-input" class="hidden">
            </form>

            <div id="upload-progress" class="hidden">
                <div class="mb-2 flex justify-between text-sm text-gray-600">
                    <span id="progress-text">Uploading...</span>
                    <span id="progress-percentage">0%</span>
                </div>
                <div class="w-full bg-gray-200 rounded-full h-2.5">
                    <div id="progress-bar" class="bg-blue-600 h-2.5 rounded-full w-0 transition-all duration-300"></div>
                </div>
            </div>

            <div id="upload-error" class="hidden mt-4 p-4 bg-red-100 text-red-700 rounded-lg"></div>
            <div id="upload-success" class="hidden mt-4 p-4 bg-green-100 text-green-700 rounded-lg"></div>
        </div>
    </div>

    <script>
        const maxSize = "{{ max_size|safe }}";
        // Helper function to format bytes
        function formatBytes(bytes) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }

        // Helper function to generate random string
        function generateRandomString(length) {
            const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
            let result = '';
            for (let i = 0; i < length; i++) {
                result += chars.charAt(Math.floor(Math.random() * chars.length));
            }
            return result;
        }

        // Countdown timer
        function updateCountdown() {
            const now = new Date().getTime();
            const expiresAt = new Date("{{ expires_at }}").getTime();
            const distance = expiresAt - now;

            if (distance < 0) {
                document.getElementById('countdown').textContent = 'EXPIRED';
                document.getElementById('dropzone').classList.add('opacity-50', 'pointer-events-none');
                return;
            }

            const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            const seconds = Math.floor((distance % (1000 * 60)) / 1000);
            document.getElementById('countdown').textContent = `${minutes}m ${seconds}s`;
        }

        setInterval(updateCountdown, 1000);
        updateCountdown();

        // File upload handling
        const dropzone = document.getElementById('dropzone');
        const fileInput = document.getElementById('file-input');
        const uploadForm = document.getElementById('upload-form');
        const browseBtn = document.getElementById('browse-btn');
        const progressBar = document.getElementById('progress-bar');
        const progressText = document.getElementById('progress-text');
        const progressPercentage = document.getElementById('progress-percentage');
        const uploadProgress = document.getElementById('upload-progress');
        const uploadError = document.getElementById('upload-error');
        const uploadSuccess = document.getElementById('upload-success');

        dropzone.addEventListener('dragover', (e) => {
            e.preventDefault();
            dropzone.classList.add('border-blue-500');
        });

        dropzone.addEventListener('dragleave', () => {
            dropzone.classList.remove('border-blue-500');
        });

        dropzone.addEventListener('drop', (e) => {
            e.preventDefault();
            dropzone.classList.remove('border-blue-500');
            handleFile(e.dataTransfer.files[0]);
        });

        browseBtn.addEventListener('click', () => {
            fileInput.click();
        });

        fileInput.addEventListener('change', (e) => {
            handleFile(e.target.files[0]);
        });

        function handleFile(file) {
            if (!file) return;
            if (file.size > maxSize) {
                showError(`File size (${formatBytes(file.size)}) exceeds the maximum allowed size ({{ human_readable_size(max_size) }})`);
                return;
            }

            uploadToS3(file);
        }

        function showError(message) {
            uploadError.textContent = message;
            uploadError.classList.remove('hidden');
            uploadSuccess.classList.add('hidden');
            uploadProgress.classList.add('hidden');
        }

        async function uploadToS3(file) {
            try {
                uploadError.classList.add('hidden');
                uploadSuccess.classList.add('hidden');
                uploadProgress.classList.remove('hidden');
                dropzone.classList.add('opacity-50', 'pointer-events-none');

                const date = new Date().toISOString().slice(0, 10);
                const random = generateRandomString(8);
                const key = `uploads/{{ token }}/${date}-${random}-${file.name}`;

                // Get policy and signature from server using secured fetch
                const policyResponse = await securedFetch('/api/generate-upload-policy', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        key: key,
                        contentType: file.type || 'application/octet-stream'
                    })
                });

                if (!policyResponse.ok) {
                    throw new Error('Failed to generate upload policy');
                }

                const policyData = await policyResponse.json();

                // Create the form data
                const formData = new FormData();
                formData.append('key', policyData.key);
                formData.append('acl', 'public-read');
                formData.append('Content-Type', file.type || 'application/octet-stream');
                formData.append('x-amz-algorithm', policyData['x-amz-algorithm']);
                formData.append('x-amz-credential', policyData['x-amz-credential']);
                formData.append('x-amz-date', policyData['x-amz-date']);
                formData.append('Policy', policyData.policy);
                formData.append('x-amz-signature', policyData.signature);
                formData.append('success_action_status', '201');
                formData.append('file', file);

                // Upload directly to DO Spaces
                const xhr = new XMLHttpRequest();
                xhr.open('POST', `https://{{ bucket }}.{{ endpoint }}`);

                xhr.upload.addEventListener('progress', (e) => {
                    if (e.lengthComputable) {
                        const percent = Math.round((e.loaded / e.total) * 100);
                        progressBar.style.width = percent + '%';
                        progressPercentage.textContent = percent + '%';
                        progressText.textContent = `Uploading (${formatBytes(e.loaded)} / ${formatBytes(e.total)})`;
                    }
                });

                xhr.onload = async () => {
                    if (xhr.status === 201) {
                        // Notify server of successful upload
                        const finalizeResponse = await securedFetch('/api/finalize-upload', {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                            },
                            body: JSON.stringify({
                                token: '{{ token }}',
                                filename: file.name,
                                size: file.size,
                                object_name: policyData.key
                            })
                        });

                        if (!finalizeResponse.ok) {
                            throw new Error('Failed to finalize upload');
                        }

                        const result = await finalizeResponse.json();
                        
                        uploadSuccess.innerHTML = `
                            <p class="font-semibold mb-2">Upload successful!</p>
                            <p class="mb-1">Direct Link: <a href="${result.direct_link}" class="text-blue-600 hover:underline" target="_blank">${result.direct_link}</a></p>
                            <p>Web Link: <a href="${result.web_link}" class="text-blue-600 hover:underline" target="_blank">${result.web_link}</a></p>
                        `;
                        uploadSuccess.classList.remove('hidden');
                        uploadProgress.classList.add('hidden');
                    } else {
                        throw new Error(`Upload failed with status: ${xhr.status}`);
                    }
                };

                xhr.onerror = () => {
                    throw new Error('Network error occurred');
                };

                xhr.send(formData);

            } catch (error) {
                console.error('Upload error:', error);
                showError(error.message || 'Upload failed. Please try again.');
                dropzone.classList.remove('opacity-50', 'pointer-events-none');
            }
        }

        // Initialize protection measures
        document.addEventListener('DOMContentLoaded', function() {
            // Detect and prevent debugging attempts
            if (window.devtools.isOpen) {
                document.body.innerHTML = '<h1>Debugging not allowed</h1>';
            }

            // Additional security measures
            window.addEventListener('devtoolschange', function(e) {
                if (e.detail.isOpen) {
                    document.body.innerHTML = '<h1>Debugging not allowed</h1>';
                }
            });
        });
    </script>
</body>
</html>