<!DOCTYPE html>
<html lang="id">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Felixx Project</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #121212;
            color: #FFFFFF;
            transition: background-color 0.5s, color 0.5s;
            -webkit-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

        ::-moz-selection {
            color: white;
            background: #333;
        }

        ::selection {
            color: white;
            background: #333;
        }

        .container {
            max-width: 800px;
            margin: 40px auto;
            padding: 20px;
            background-color: #1E1E1E;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
            transition: all ease-in-out 0.5s;
            border-radius: 12px;
        }

        h2 {
            text-align: center;
            margin-bottom: 20px;
        }

        ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }

        li {
            display: block;
            padding: 10px 15px;
            border-radius: 8px;
            margin-bottom: 10px;
            transition: background-color 0.3s, transform 0.3s;
            cursor: pointer;
            position: relative;
        }

        li:hover {
            background-color: rgba(255, 255, 255, 0.1);
            transform: scale(1.02);
        }

        .icon {
            margin-right: 10px;
        }

        .file-content {
            display: none;
            background-color: #000;
            color: #FFF;
            padding: 15px;
            border-radius: 6px;
            margin-top: 10px;
            font-family: 'Courier New', Courier, monospace;
            position: relative;
            overflow-x: auto;
            white-space: pre;
            flex-direction: column;
        }

        .file-content pre {
            white-space: pre-wrap;
            word-wrap: break-word;
            overflow-x: auto;
        }

        .file-content.show {
            display: block;
            animation: fadeIn 0.5s ease-in-out;
        }

        .file-content.typing {
            white-space: pre-wrap;
            overflow: hidden;
        }

        .file-content .buttons {
            display: flex;
            justify-content: flex-start;
            gap: 10px;
            margin-top: 10px;
        }

        .file-content.typing::after {
            content: '';
            animation: typing 1s steps(10) infinite;
        }

        .file-content .copy-btn,
        .file-content .view-raw-btn,
        .file-content .preview-btn,
        .file-content .download-btn,
        .back-btn {
            padding: 5px 15px;
            background: #007AFF;
            color: #FFF;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
            margin: 5px;
        }

        .file-content .view-raw-btn {
            right: 80px;
        }

        .file-content .preview-btn {
            right: 150px;
        }

        .file-content .copy-btn:hover,
        .file-content .view-raw-btn:hover,
        .file-content .preview-btn:hover,
        .download-btn:hover,
        .back-btn:hover {
            background-color: #005BBB;
        }

        .folder-container {
            margin-left: 20px;
            padding-left: 10px;
            border-left: 2px solid rgba(255, 255, 255, 0.2);
            margin-bottom: 20px;
        }

        .folder>ul {
            margin-top: 10px;
        }

        .folder>.icon {
            transition: transform 0.3s;
        }

        .folder.open>.icon {
            transform: rotate(90deg);
        }

        .highlight {
            background: #282C34;
            color: #61AFEF;
        }

        body.dark-mode {
            background-color: #121212;
            color: #FFFFFF;
        }

        body.dark-mode .container {
            background-color: #1E1E1E;
        }

        body.light-mode {
            background-color: #F5F5F5;
            color: #000000;
        }

        body.light-mode .container {
            background-color: #FFFFFF;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }

        body.light-mode li:hover {
            background-color: rgba(0, 0, 0, 0.05);
        }

        .loading-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.6);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 9999;
            visibility: hidden;
            opacity: 0;
            transition: visibility 0s, opacity 0.3s ease-in-out;
        }

        .loading-overlay.show {
            visibility: visible;
            opacity: 1;
        }

        .spinner {
            border: 4px solid rgba(255, 255, 255, 0.2);
            border-top: 4px solid #fff;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
        }

        .circles {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
            z-index: -1;
        }

        .circles li {
            position: absolute;
            display: block;
            list-style: none;
            width: 20px;
            height: 20px;
            background: rgba(255, 255, 255, 0.2);
            animation: animate 25s linear infinite;
            bottom: -150px;

        }

        .circles li:nth-child(1) {
            left: 25%;
            width: 80px;
            height: 80px;
            animation-delay: 0s;
        }


        .circles li:nth-child(2) {
            left: 10%;
            width: 20px;
            height: 20px;
            animation-delay: 2s;
            animation-duration: 12s;
        }

        .circles li:nth-child(3) {
            left: 70%;
            width: 20px;
            height: 20px;
            animation-delay: 4s;
        }

        .circles li:nth-child(4) {
            left: 40%;
            width: 60px;
            height: 60px;
            animation-delay: 0s;
            animation-duration: 18s;
        }

        .circles li:nth-child(5) {
            left: 65%;
            width: 20px;
            height: 20px;
            animation-delay: 0s;
        }

        .circles li:nth-child(6) {
            left: 75%;
            width: 110px;
            height: 110px;
            animation-delay: 3s;
        }

        .circles li:nth-child(7) {
            left: 35%;
            width: 150px;
            height: 150px;
            animation-delay: 7s;
        }

        .circles li:nth-child(8) {
            left: 50%;
            width: 25px;
            height: 25px;
            animation-delay: 15s;
            animation-duration: 45s;
        }

        .circles li:nth-child(9) {
            left: 20%;
            width: 15px;
            height: 15px;
            animation-delay: 2s;
            animation-duration: 35s;
        }

        .circles li:nth-child(10) {
            left: 85%;
            width: 150px;
            height: 150px;
            animation-delay: 0s;
            animation-duration: 11s;
        }

        @keyframes spin {
            0% {
                transform: rotate(0deg);
            }

            100% {
                transform: rotate(360deg);
            }
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: scaleY(0.9);
            }

            to {
                opacity: 1;
                transform: scaleY(1);
            }
        }

        @keyframes typing {
            0% {
                border-right: 2px solid transparent;
            }

            50% {
                border-right: 2px solid white;
            }

            100% {
                border-right: 2px solid transparent;
            }
        }

        @keyframes rotateBorder {
            0% {
                border-image: linear-gradient(0deg, black, white) 1;
            }

            50% {
                border-image: linear-gradient(180deg, black, white) 1;
            }

            100% {
                border-image: linear-gradient(360deg, black, white) 1;
            }
        }

        .dark-mode-toggle {
            position: absolute;
            top: 20px;
            right: 20px;
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            transition: transform 0.3s;
        }

        .logo {
            position: relative;
            left: 50%;
            transform: translate(-50%, 0);
        }

        .area {
            width: 100%;
            height: 100%;
        }

        .file-info {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .date {
            color: gray;
            margin-left: auto;
        }

        #raw {
            display: flex;
            justify-content: center;
            align-items: center;
        }

        @keyframes animate {

            0% {
                transform: translateY(0) rotate(0deg);
                opacity: 1;
                border-radius: 0;
            }

            100% {
                transform: translateY(-1000px) rotate(720deg);
                opacity: 0;
                border-radius: 50%;
            }

        }
    </style>
</head>

<body>
    <button class="dark-mode-toggle" id="darkModeToggle"></button>
    <ul class="circles">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
    </ul>
    <div class="container">
        <img class="logo" src="//src.felixxx.my.id/Felixxx.png" width="100px">
        <h2>Felixx Project</h2>
        <hr>
        <div id="loadingOverlay" class="loading-overlay">
            <div class="spinner"></div>
        </div>
        <ul id="fileList"></ul>
    </div>

    <script>
        const darkModeToggle = document.getElementById('darkModeToggle');
        const body = document.body;

        const theme = localStorage.getItem('theme') || 'dark';
        body.className = theme + '-mode';
        darkModeToggle.textContent = theme === 'dark' ? '🌙' : '🌞';
        darkModeToggle.addEventListener('click', () => {
            const newTheme = body.className === 'dark-mode' ? 'light' : 'dark';
            body.className = newTheme + '-mode';
            localStorage.setItem('theme', newTheme);
            darkModeToggle.textContent = newTheme === 'dark' ? '🌙' : '🌞';
        });

        const urlParams = new URLSearchParams(window.location.search);
        const fileParam = urlParams.get('file');
        const loadingOverlay = document.getElementById('loadingOverlay');

        async function fetchFiles(path = 'Felixx', parentElement = null) {
            loadingOverlay.classList.add('show');
            try {
                const response = await fetch(`https://felixxx.site/fileDirectory/files?path=${path}`);
                const files = await response.json();
                const fileList = parentElement || document.getElementById('fileList');

                if (!parentElement) fileList.innerHTML = '';

                files.forEach(file => {
                    const li = document.createElement('li');
                    li.className = file.isDirectory ? 'folder' : 'file';
                    li.innerHTML = `<div class="file-info"><span class="icon">${file.isDirectory ? '📂' : '📄'}</span><span class="fileName">${file.name}</span><span class="date">${formatDate(file.uploadedAt)}</span></div>`;
                    function formatDate(timestamp) {
                        const now = new Date();
                        const date = new Date(timestamp * 1000);

                        if (isNaN(date.getTime())) {
                            return "Invalid timestamp";
                        }

                        const diffInMilliseconds = now - date;
                        const diffInDays = Math.floor(diffInMilliseconds / (1000 * 60 * 60 * 24));

                        if (diffInDays > 3) {
                            const day = String(date.getDate()).padStart(2, '0');
                            const month = String(date.getMonth() + 1).padStart(2, '0');
                            const year = date.getFullYear();
                            return `${day}/${month}/${year}`;
                        } else if (diffInDays === 1) {
                            return "1 day ago";
                        } else if (diffInDays < 1) {
                            const hours = Math.floor(diffInMilliseconds / (1000 * 60 * 60));
                            return `${hours} hours ago`;
                        } else {
                            return `${diffInDays} days ago`;
                        }
                    }

                    if (file.isDirectory) {
                        li.addEventListener('click', async (e) => {
                            e.stopPropagation();
                            li.classList.toggle('open');

                            let folderContainer = li.querySelector('.folder-container');
                            if (folderContainer) {
                                folderContainer.style.display = folderContainer.style.display === 'none' ? 'block' : 'none';
                            } else {
                                folderContainer = document.createElement('div');
                                folderContainer.className = 'folder-container';

                                const ul = document.createElement('ul');
                                folderContainer.appendChild(ul);
                                li.appendChild(folderContainer);

                                await fetchFiles(file.path, ul);
                            }
                        });

                    } else {
                        li.addEventListener('click', async (e) => {
                            e.stopPropagation();
                            const existingContent = li.querySelector('.file-content');
                            if (existingContent) {
                                existingContent.classList.toggle('show');
                                return;
                            }

                            const content = document.createElement('div');
                            content.className = 'file-content typing';

                            const response = await fetch(`https://felixxx.site/fileDirectory/view-file?file=${file.path}`);
                            const data = await response.json();

                            const pre = document.createElement('pre');
                            let idx = 0;

                            const typeAnimation = setInterval(() => {
                                try {
                                    if (idx < data.content.length) {
                                        pre.textContent += data.content[idx];
                                        idx++;
                                    } else {
                                        clearInterval(typeAnimation);
                                        content.classList.remove('typing');
                                    }
                                } catch (error) {
                                    console.error(error);
                                    const copyBtn = document.createElement('button');
                                    copyBtn.textContent = 'Salin';
                                    copyBtn.className = 'copy-btn';
                                    copyBtn.onclick = (event) => {
                                        event.stopPropagation();
                                        copyBtn.textContent = "Berhasil!"
                                        navigator.clipboard.writeText(data.content);
                                        setTimeout(() => {
                                            copyBtn.textContent = 'Salin';
                                        }, 1000);
                                    };

                                    const viewRawBtn = document.createElement('button');
                                    viewRawBtn.textContent = 'Lihat Raw';
                                    viewRawBtn.className = 'view-raw-btn';
                                    viewRawBtn.onclick = (event) => {
                                        event.stopPropagation();
                                        window.location.href = `/?file=${file.path}&raw=true`;
                                    };

                                    const downloadBtn = document.createElement('button');
                                    downloadBtn.textContent = 'Unduh File';
                                    downloadBtn.className = 'download-btn';
                                    downloadBtn.onclick = () => {
                                        window.location.href = `https://felixxx.site/fileDirectory/download?file=${encodeURIComponent(file.path)}`;
                                    };
                                    li.appendChild(content);
                                    content.classList.add('show');
                                    clearInterval(typeAnimation);
                                }
                            }, 0);

                            const fileExt = file.name.split('.').pop().toLowerCase();
                            if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'tiff', 'heif', 'svg', 'raw', 'ico', 'indd', 'ai', 'eps']
                                .includes(fileExt)) {
                                const imgElement = document.createElement('img');
                                imgElement.src = `https://felixxx.site/fileDirectory/download?file=${encodeURIComponent(file.path)}`;
                                imgElement.alt = file.name;
                                imgElement.style.maxWidth = '100%';
                                imgElement.style.borderRadius = '6px';
                                content.appendChild(imgElement);

                            } else if (['mp3', 'wav', 'ogg', 'flac', 'aac', 'wma', 'alac', 'm4a', 'aiff', 'opus', 'ape']
                                .includes(fileExt)) {
                                const audioElement = document.createElement('audio');
                                audioElement.src = `https://felixxx.site/fileDirectory/download?file=${encodeURIComponent(file.path)}`;
                                audioElement.controls = true;
                                audioElement.style.width = '100%';
                                audioElement.style.borderRadius = '5px';
                                audioElement.style.marginTop = '20px';
                                audioElement.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)';
                                audioElement.style.transition = 'transform 0.3s ease-in-out';

                                const audioContainer = document.createElement('div');
                                audioContainer.style.position = 'relative';
                                audioContainer.style.marginBottom = '20px';
                                audioContainer.appendChild(audioElement);

                                content.appendChild(audioContainer);

                            } else if (['mp4', 'm4v', 'mov', 'avi', 'wmv', 'flv', 'mkv'].includes(fileExt)) {

                            } else {
                                content.appendChild(pre);
                            }

                            const copyBtn = document.createElement('button');
                            copyBtn.textContent = 'Salin';
                            copyBtn.className = 'copy-btn';
                            copyBtn.onclick = (event) => {
                                event.stopPropagation();
                                copyBtn.textContent = "Berhasil!"
                                navigator.clipboard.writeText(data.content);
                                setTimeout(() => {
                                    copyBtn.textContent = 'Salin';
                                }, 1000);
                            };

                            const viewRawBtn = document.createElement('button');
                            viewRawBtn.textContent = 'Lihat Raw';
                            viewRawBtn.className = 'view-raw-btn';
                            viewRawBtn.onclick = (event) => {
                                event.stopPropagation();
                                window.location.href = `/?file=${file.path}&raw=true`;
                            };
                            const downloadBtn = document.createElement('button');
                            downloadBtn.textContent = 'Unduh File';
                            downloadBtn.className = 'download-btn';
                            downloadBtn.onclick = () => {
                                window.location.href = `https://felixxx.site/fileDirectory/download?file=${encodeURIComponent(file.path)}`;
                            };

                            if (file.name.endsWith('.html') || file.name.endsWith('.php')) {
                                const previewBtn = document.createElement('button');
                                previewBtn.textContent = 'Pratinjau';
                                previewBtn.className = 'preview-btn';
                                previewBtn.onclick = () => {
                                    window.location.href = `/?file=${file.path}&raw=false`;
                                };
                                content.appendChild(previewBtn);
                            }

                            content.appendChild(pre);
                            content.appendChild(copyBtn);
                            content.appendChild(viewRawBtn);
                            content.appendChild(downloadBtn);

                            li.appendChild(content);
                            content.classList.add('show');
                        });
                    }
                    fileList.appendChild(li);
                });
            } finally {
                loadingOverlay.classList.remove('show');
            }
        }

        if (fileParam) {
            (async () => {
                const response = await fetch(`https://felixxx.site/fileDirectory/view-file?file=${fileParam}&raw=${urlParams.get('raw')}`);
                const data = await response.json();

                const container = document.createElement('div');
                container.className = 'container';
                container.id = 'raw'
                if (urlParams.get('raw') === 'false') {
                    const backButton = document.createElement('button');
                    backButton.textContent = 'Kembali';
                    backButton.className = 'back-btn'

                    backButton.onmouseenter = () => {
                        backButton.style.backgroundColor = '#005BB5';
                    };
                    backButton.onmouseleave = () => {
                        backButton.style.backgroundColor = '#007AFF';
                    };

                    backButton.onclick = () => {
                        window.location.href = '/';
                    };
                    container.appendChild(backButton);

                    const iframe = document.createElement('iframe');
                    iframe.srcdoc = data.content;
                    iframe.width = '100%';
                    iframe.height = '600px';
                    container.appendChild(iframe);
                } else {
                    const url = new URL(window.location.href);
                    const filePath = url.searchParams.get("file");
                    const fileName = filePath ? filePath.split('/').pop() : '';
                    const fileExt = fileName.split('.').pop().toLowerCase();

                    if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'tiff', 'heif', 'svg', 'raw', 'ico', 'indd', 'ai', 'eps']
                        .includes(fileExt)) {
                        const imgElement = document.createElement('img');
                        imgElement.src = `https://felixxx.site/fileDirectory/download?file=${encodeURIComponent(filePath)}`;
                        imgElement.alt = fileName;
                        imgElement.style.maxWidth = '100%';
                        imgElement.style.borderRadius = '6px';
                        container.appendChild(imgElement);


                    } else if (['mp3', 'wav', 'ogg', 'flac', 'aac', 'wma', 'alac', 'm4a', 'aiff', 'opus', 'ape']
                        .includes(fileExt)) {
                        const audioElement = document.createElement('audio');
                        audioElement.src = `https://felixxx.site/fileDirectory/download?file=${encodeURIComponent(filePath)}`;
                        audioElement.controls = true;
                        audioElement.style.width = '100%';
                        audioElement.style.borderRadius = '5px';
                        audioElement.style.marginTop = '20px';
                        audioElement.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)';
                        audioElement.style.transition = 'transform 0.3s ease-in-out';

                        const audioContainer = document.createElement('div');
                        audioContainer.style.position = 'relative';
                        audioContainer.style.marginBottom = '20px';
                        audioContainer.appendChild(audioElement);

                        container.appendChild(audioContainer);

                    } else if (['mp4', 'm4v', 'mov', 'avi', 'wmv', 'flv', 'mkv'].includes(fileExt)) {
                        const videoElement = document.createElement('video');
                        videoElement.src = `https://felixxx.site/fileDirectory/download?file=${encodeURIComponent(filePath)}`;
                        videoElement.controls = true;
                        videoElement.style.width = '100%';
                        videoElement.style.borderRadius = '5px';
                        videoElement.style.marginTop = '20px';
                        videoElement.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)';
                        videoElement.style.transition = 'transform 0.3s ease-in-out';

                        const videoContainer = document.createElement('div');
                        videoContainer.style.position = 'relative';
                        videoContainer.style.marginBottom = '20px';
                        videoContainer.appendChild(videoElement);

                        container.appendChild(videoContainer);
                    } else {
                        const pre = document.createElement('pre');
                        pre.textContent = 'File tidak dikenali. Tidak dapat diproses.';
                        pre.style.backgroundColor = '#000';
                        pre.style.color = '#FFF';
                        pre.style.padding = '20px';
                        pre.style.borderRadius = '6px';
                        pre.style.fontFamily = 'Courier New, Courier, monospace';
                        pre.style.whiteSpace = 'pre-wrap';
                        pre.style.wordWrap = 'break-word';
                        container.appendChild(pre);
                    }
                }
                document.body.appendChild(container);
            })();
        } else {
            fetchFiles();
        }
    </script>
</body>

</html>