<!DOCTYPE html>
<html>
<head>
    <title>EXE Update Publisher</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 20px;
            background-color: #f0f0f0;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input[type="text"], input[type="file"], textarea {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
        }
        button:hover {
            background-color: #45a049;
        }
        button.reset {
            background-color: #f44336;
        }
        button.reset:hover {
            background-color: #da190b;
        }
        .version-info {
            background-color: #f8f9fa;
            padding: 10px;
            border-radius: 4px;
            margin-bottom: 15px;
        }
        #log {
            margin-top: 20px;
            padding: 10px;
            background-color: #f8f9fa;
            border-radius: 4px;
            max-height: 200px;
            overflow-y: auto;
        }
        .progress {
            width: 100%;
            height: 20px;
            background-color: #f0f0f0;
            border-radius: 4px;
            margin-top: 10px;
        }
        .progress-bar {
            width: 0%;
            height: 100%;
            background-color: #4CAF50;
            border-radius: 4px;
            transition: width 0.3s ease-in-out;
        }
        .path-input {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
        }
        .path-input input {
            flex: 1;
        }
        .file-list {
            max-height: 200px;
            overflow-y: auto;
            border: 1px solid #ddd;
            padding: 10px;
            margin-top: 10px;
            background: #f8f9fa;
            border-radius: 4px;
        }
        .file-item {
            padding: 4px;
            border-bottom: 1px solid #eee;
        }
        .file-item:last-child {
            border-bottom: none;
        }
        .python-file {
            color: #2980b9;
        }
        .json-file {
            color: #27ae60;
        }
        .version-badge {
            background: #e74c3c;
            color: white;
            padding: 2px 6px;
            border-radius: 3px;
            font-size: 0.8em;
            margin-left: 10px;
        }
        .file-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .file-item.error {
            color: #e74c3c;
        }
        .python-file:before {
            content: '🐍';
            margin-right: 5px;
        }
        .json-file:before {
            content: '📄';
            margin-right: 5px;
        }
        .version-warning {
            background: #fff3cd;
            border: 1px solid #ffeeba;
            color: #856404;
            padding: 10px;
            margin: 10px 0;
            border-radius: 4px;
            display: none;
        }
        .version-safe {
            background: #d4edda;
            border: 1px solid #c3e6cb;
            color: #155724;
            padding: 10px;
            margin: 10px 0;
            border-radius: 4px;
            display: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>EXE Update Publisher</h1>
        
        <div class="version-info">
            <h3>Current Version Information</h3>
            <div id="githubVersion">Loading...</div>
            <div id="localVersion">Loading local version...</div>
        </div>

        <div class="form-group">
            <label for="baseCodePath">Base Code Directory:</label>
            <div class="path-input">
                <input type="text" id="baseCodePath" readonly placeholder="Select base code directory" />
                <button onclick="selectBaseDirectory()">Browse</button>
            </div>
            <div id="baseCodeFiles" class="file-list"></div>
        </div>

        <div class="form-group">
            <label for="exeFile">Select EXE File:</label>
            <input type="file" id="exeFile" accept=".exe" onchange="handleFileSelect()" />
        </div>

        <div class="form-group">
            <label for="version">Version:</label>
            <div style="display: flex; align-items: center;">
                <input type="text" id="version" readonly style="margin-right: 10px;" value="Select an EXE file" />
                <span id="versionInfo" style="color: #27ae60;"></span>
            </div>
        </div>

        <div class="form-group">
            <label for="changelog">Changelog:</label>
            <textarea id="changelog" rows="4"></textarea>
        </div>

        <div class="form-group">
            <button onclick="publishUpdate()">Publish Update</button>
            <button class="reset" onclick="resetRepository()">Reset Repository to 1.0.1</button>
            <button onclick="checkCurrentVersion()">Check Current Version</button>
            <button class="reset" onclick="resetBaseCode()">Reset Base Code</button>
        </div>

        <div class="form-group">
            <div id="versionWarning" class="version-warning"></div>
            <div id="versionSafe" class="version-safe"></div>
        </div>

        <div class="progress">
            <div class="progress-bar" id="progressBar"></div>
        </div>

        <div id="log"></div>
    </div>

    <script>
        const REPO_OWNER = 'khanfar';
        const REPO_NAME = 'khanfar-sys-updates';
        const BRANCH = 'main';
        // Store token securely in code instead of GUI
        const token = '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';

        async function validateToken() {
            try {
                const response = await axios.get('https://api.github.com/user', {
                    headers: { Authorization: `token ${token}` }
                });
                log('GitHub authentication successful');
                return true;
            } catch (error) {
                log('GitHub authentication failed', 'ERROR');
                return false;
            }
        }

        function log(message, level = "INFO") {
            const logDiv = document.getElementById('log');
            const timestamp = new Date().toLocaleTimeString();
            const logEntry = document.createElement('div');
            logEntry.style.color = level === "ERROR" ? "red" : level === "WARNING" ? "orange" : "black";
            logEntry.textContent = `[${timestamp}] ${level}: ${message}`;
            logDiv.insertBefore(logEntry, logDiv.firstChild);
        }

        function updateProgress(percent) {
            document.getElementById('progressBar').style.width = `${percent}%`;
        }

        async function calculateHash(file) {
            return new Promise((resolve) => {
                const reader = new FileReader();
                reader.onload = async (e) => {
                    const arrayBuffer = e.target.result;
                    const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
                    const hashArray = Array.from(new Uint8Array(hashBuffer));
                    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
                    resolve(hashHex);
                };
                reader.readAsArrayBuffer(file);
            });
        }

        async function checkCurrentVersion() {
            try {
                const response = await fetch('https://khanfar.github.io/khanfar-sys-updates/version.json?' + new Date().getTime());
                const versionInfo = await response.json();
                
                document.getElementById('githubVersion').textContent = versionInfo.version;
                log('Version information retrieved successfully');

                // Get local version first
                let localVersion = '1.0.1'; // default
                try {
                    const baseCodePath = document.getElementById('baseCodePath').value;
                    if (baseCodePath) {
                        const handle = await window.showDirectoryPicker({
                            startIn: baseCodePath
                        });
                        const fileHandle = await handle.getFileHandle('version.json');
                        const file = await fileHandle.getFile();
                        const content = await file.text();
                        const localVersionData = JSON.parse(content);
                        localVersion = localVersionData.version;
                        document.getElementById('localVersion').textContent = localVersion;
                    }
                } catch (error) {
                    log('Error loading local version: ' + error.message, 'WARNING');
                    document.getElementById('localVersion').textContent = 'Not found';
                }

                // Set next version
                const nextVersion = getNextVersion(versionInfo.version);
                document.getElementById('version').value = nextVersion;
                document.getElementById('versionInfo').textContent = `(Current GitHub: ${versionInfo.version})`;
                
                // Check version balance
                await checkVersionBalance();

            } catch (error) {
                log('Error checking version: ' + error.message, 'ERROR');
                document.getElementById('githubVersion').textContent = 'Error';
                document.getElementById('version').value = '1.0.2';
                document.getElementById('versionInfo').textContent = '(Starting from 1.0.1)';
            }
        }

        async function handleFileSelect() {
            const fileInput = document.getElementById('exeFile');
            if (!fileInput.files.length) {
                log('No file selected');
                return;
            }
            log('EXE file selected: ' + fileInput.files[0].name);
            await checkVersionBalance();
        }

        async function resetBaseCode() {
            try {
                const baseCodePath = document.getElementById('baseCodePath').value;
                if (!baseCodePath) {
                    throw new Error('Please select a base code directory first');
                }

                const versionJson = {
                    version: "1.0.1",
                    date: new Date().toISOString()
                };

                // Use FileSystem API to write file
                const handle = await window.showDirectoryPicker();
                const fileHandle = await handle.getFileHandle('version.json', { create: true });
                const writable = await fileHandle.createWritable();
                await writable.write(JSON.stringify(versionJson, null, 2));
                await writable.close();

                document.getElementById('localVersion').textContent = '1.0.1';
                log('Successfully reset base code version to 1.0.1');
                checkCurrentVersion();
            } catch (error) {
                log('Error resetting base code: ' + error.message, 'ERROR');
            }
        }

        async function resetRepository() {
            if (!await validateToken()) return;

            try {
                log('Starting repository reset...');
                
                // Step 1: Delete uploaded files
                log('Step 1: Deleting uploaded files...');
                const response = await axios.get(`https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/`, {
                    headers: { Authorization: `token ${token}` }
                });

                // Keep all HTML files and version.json, delete everything else
                for (const file of response.data) {
                    const isHtml = file.name.toLowerCase().endsWith('.html');
                    if (!isHtml && file.name !== 'version.json') {
                        log(`Deleting file: ${file.name}`);
                        await axios.delete(
                            `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/${file.name}`,
                            {
                                headers: { Authorization: `token ${token}` },
                                data: {
                                    message: `Delete ${file.name}`,
                                    sha: file.sha,
                                    branch: BRANCH
                                }
                            }
                        );
                    } else {
                        log(`Keeping file: ${file.name}`);
                    }
                }
                
                // Step 2: Reset version.json
                log('Step 2: Resetting version.json to 1.0.1...');
                const versionContent = {
                    version: "1.0.1",
                    update_server: "https://khanfar.github.io/khanfar-sys-updates",
                    update_interface: "https://khanfar.github.io/khanfar-sys-updates/lg3_lfs.html",
                    files: [],
                    changelog: "",
                    requires_restart: false,
                    min_version: "1.0.0",
                    publish_date: new Date().toISOString()
                };

                // Update version.json in repository
                const currentSha = await getCurrentFileSha('version.json');
                await updateFile('version.json', JSON.stringify(versionContent, null, 4), currentSha);
                
                // Wait a moment for GitHub to update
                log('Waiting for GitHub to update...');
                await new Promise(resolve => setTimeout(resolve, 2000));
                
                log('Repository successfully reset to version 1.0.1');
                checkCurrentVersion();
            } catch (error) {
                log('Error during repository reset: ' + error.message, 'ERROR');
            }
        }

        async function getCurrentFileSha(path) {
            try {
                const response = await axios.get(`https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/${path}`, {
                    headers: { Authorization: `token ${token}` }
                });
                return response.data.sha;
            } catch (error) {
                if (error.response && error.response.status === 404) {
                    return null;
                }
                throw error;
            }
        }

        async function updateFile(path, content, sha = null) {
            const payload = {
                message: `Update ${path}`,
                content: btoa(content),
                branch: BRANCH
            };
            
            if (sha) {
                payload.sha = sha;
            }

            await axios.put(
                `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/${path}`,
                payload,
                { headers: { Authorization: `token ${token}` } }
            );
        }

        async function blobToBase64(blob) {
            return new Promise((resolve) => {
                const reader = new FileReader();
                reader.onloadend = () => resolve(reader.result.split(',')[1]);
                reader.readAsDataURL(blob);
            });
        }

        async function uploadChunk(chunk, filename, index, totalChunks, branchName) {
            const base64Content = await blobToBase64(chunk);
            const path = `${filename}.part${index}`;
            
            try {
                await axios.put(
                    `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/${path}`,
                    {
                        message: `Upload ${filename} part ${index}/${totalChunks}`,
                        content: base64Content,
                        branch: branchName
                    },
                    { headers: { Authorization: `token ${token}` } }
                );
                return true;
            } catch (error) {
                log(`Error uploading chunk ${index}: ${error.message}`, 'ERROR');
                return false;
            }
        }

        async function updateVersionJson(versionInfo, branchName) {
            try {
                const content = JSON.stringify(versionInfo, null, 4);
                const base64Content = btoa(content);
                
                await axios.put(
                    `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/version.json`,
                    {
                        message: `Update version.json to ${versionInfo.version}`,
                        content: base64Content,
                        branch: branchName
                    },
                    { headers: { Authorization: `token ${token}` } }
                );
                return true;
            } catch (error) {
                log('Error updating version.json: ' + error.message, 'ERROR');
                return false;
            }
        }

        async function createPullRequest(branchName, version, changelog) {
            try {
                const response = await axios.post(
                    `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/pulls`,
                    {
                        title: `Update to version ${version}`,
                        body: changelog,
                        head: branchName,
                        base: 'main'
                    },
                    { headers: { Authorization: `token ${token}` } }
                );
                return response.data.number;
            } catch (error) {
                log('Error creating pull request: ' + error.message, 'ERROR');
                return null;
            }
        }

        async function deleteUploadedFiles() {
            if (!await validateToken()) return;

            try {
                log('Fetching repository contents...');
                const response = await axios.get(`https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/`, {
                    headers: { Authorization: `token ${token}` }
                });

                // Keep lg3_lfs.html and version.json, delete everything else
                for (const file of response.data) {
                    if (file.name !== 'lg3_lfs.html' && file.name !== 'version.json' && file.name !== 'index.html') {
                        log(`Deleting file: ${file.name}`);
                        await axios.delete(
                            `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/${file.name}`,
                            {
                                headers: { Authorization: `token ${token}` },
                                data: {
                                    message: `Delete ${file.name}`,
                                    sha: file.sha,
                                    branch: BRANCH
                                }
                            }
                        );
                    }
                }

                log('Successfully deleted uploaded files');
                checkCurrentVersion();
            } catch (error) {
                log('Error deleting files: ' + error.message, 'ERROR');
            }
        }

        function compareVersions(version1, version2) {
            const v1parts = version1.split('.').map(Number);
            const v2parts = version2.split('.').map(Number);
            
            for (let i = 0; i < 3; i++) {
                if (v1parts[i] > v2parts[i]) return 1;
                if (v1parts[i] < v2parts[i]) return -1;
            }
            return 0;
        }

        function getNextVersion(currentVersion) {
            const parts = currentVersion.split('.');
            if (parts.length !== 3) return '1.0.1';
            
            // Increment the last number
            const major = parseInt(parts[0]);
            const minor = parseInt(parts[1]);
            let patch = parseInt(parts[2]);
            
            patch++;
            return `${major}.${minor}.${patch}`;
        }

        async function checkVersionBalance() {
            try {
                // Get all versions
                const githubVersion = document.getElementById('githubVersion').textContent;
                const localVersion = document.getElementById('localVersion').textContent;
                const currentInputVersion = document.getElementById('version').value;
                
                const warningDiv = document.getElementById('versionWarning');
                const safeDiv = document.getElementById('versionSafe');
                warningDiv.style.display = 'none';
                safeDiv.style.display = 'none';

                if (githubVersion === 'Error' || githubVersion === 'Loading...') {
                    throw new Error('Cannot check versions - GitHub version not available');
                }

                let warnings = [];
                let suggestions = [];

                // Compare versions
                const localToGithub = compareVersions(localVersion, githubVersion);
                const inputToGithub = compareVersions(currentInputVersion, githubVersion);
                const inputToLocal = compareVersions(currentInputVersion, localVersion);

                // Check for risky scenarios
                if (localToGithub > 0) {
                    warnings.push(`Local version (${localVersion}) is newer than GitHub (${githubVersion})`);
                    suggestions.push(`Consider updating GitHub to version ${localVersion} first`);
                }

                if (inputToGithub < 0) {
                    warnings.push(`Selected version (${currentInputVersion}) is older than GitHub (${githubVersion})`);
                    suggestions.push(`Use version ${getNextVersion(githubVersion)} or higher`);
                }

                if (inputToLocal < 0) {
                    warnings.push(`Selected version (${currentInputVersion}) is older than local (${localVersion})`);
                    suggestions.push(`Use version ${getNextVersion(localVersion)} or higher`);
                }

                // Show warnings or safe message
                if (warnings.length > 0) {
                    warningDiv.innerHTML = `
                        <strong>⚠️ Version Warnings:</strong><br>
                        ${warnings.join('<br>')}<br>
                        <strong>Suggestions:</strong><br>
                        ${suggestions.join('<br>')}
                    `;
                    warningDiv.style.display = 'block';
                    
                    // Automatically correct version if needed
                    const suggestedVersion = getNextVersion(Math.max(githubVersion, localVersion));
                    document.getElementById('version').value = suggestedVersion;
                    log(`Automatically corrected version to ${suggestedVersion} to maintain version balance`);
                } else {
                    safeDiv.innerHTML = `
                        <strong>✅ Version Check Passed:</strong><br>
                        GitHub: ${githubVersion}<br>
                        Local: ${localVersion}<br>
                        Next Version: ${currentInputVersion}
                    `;
                    safeDiv.style.display = 'block';
                }
            } catch (error) {
                log('Error checking version balance: ' + error.message, 'ERROR');
            }
        }

        async function selectBaseDirectory() {
            try {
                // Use the File System Access API for directory selection
                const dirHandle = await window.showDirectoryPicker({
                    mode: 'read'
                });
                
                const path = dirHandle.name;
                document.getElementById('baseCodePath').value = path;
                
                // Update file list
                const fileList = document.getElementById('baseCodeFiles');
                fileList.innerHTML = '<div class="file-item">Loading files...</div>';
                
                try {
                    // List all files in directory
                    const files = [];
                    for await (const entry of dirHandle.values()) {
                        if (entry.kind === 'file' && 
                            (entry.name.endsWith('.py') || entry.name.endsWith('.json'))) {
                            files.push(entry);
                        }
                    }

                    // Display files
                    if (files.length === 0) {
                        fileList.innerHTML = '<div class="file-item">No Python or JSON files found</div>';
                    } else {
                        fileList.innerHTML = '';
                        for (const file of files) {
                            const fileDiv = document.createElement('div');
                            fileDiv.className = `file-item ${file.name.endsWith('.py') ? 'python-file' : 'json-file'}`;
                            fileDiv.textContent = file.name;
                            
                            if (file.name === 'version.json') {
                                fileDiv.innerHTML += ' <span class="version-badge">Version File</span>';
                                // Read version.json content
                                const fileHandle = await dirHandle.getFileHandle('version.json');
                                const fileData = await fileHandle.getFile();
                                const content = await fileData.text();
                                const versionData = JSON.parse(content);
                                document.getElementById('localVersion').textContent = versionData.version;
                                log(`Found version.json: ${versionData.version}`);
                                await checkVersionBalance();
                            }
                            
                            fileList.appendChild(fileDiv);
                        }

                        if (!files.some(f => f.name === 'version.json')) {
                            log('No version.json found in selected directory', 'WARNING');
                            document.getElementById('localVersion').textContent = 'Not found';
                            await checkVersionBalance();
                        }
                    }
                    
                    log(`Selected base code directory: ${path}`);
                } catch (error) {
                    fileList.innerHTML = '<div class="file-item error">Error reading directory contents</div>';
                    log('Error reading directory: ' + error.message, 'ERROR');
                }
            } catch (error) {
                if (error.name === 'AbortError') {
                    // User cancelled the selection
                    return;
                }
                log('Error selecting directory: ' + error.message, 'ERROR');
            }
        }

        // Initialize version check on page load
        window.onload = function() {
            checkCurrentVersion();
            const fileList = document.getElementById('baseCodeFiles');
            fileList.innerHTML = '<div class="file-item">Please select a directory</div>';
            
            // Initialize version input
            const versionInput = document.getElementById('version');
            versionInput.value = 'Select an EXE file';
            document.getElementById('versionInfo').textContent = '';
        };
    </script>
</body>
</html>
