#!/usr/bin/env python3
"""Restaure index.php depuis index_v1.php + correctif conflit déplacement inline."""
import os
import re
import sys

HERE = os.path.dirname(os.path.abspath(__file__))
SRC = os.path.join(os.path.dirname(os.path.dirname(HERE)), 'index_v1.php')
DST = os.path.join(HERE, 'index.php')

if not os.path.isfile(SRC):
    print(f'Source introuvable: {SRC}', file=sys.stderr)
    sys.exit(1)

with open(SRC, 'r', encoding='utf-8', errors='replace') as f:
    content = f.read()

HELPERS = r"""

// ── Déplacement : dialogue Remplacer / Renommer / Annuler (conflit de nom) ──
window.__xcloudDragSource = '';

function _xcloudNormMoveUrl(u) {
    return String(u || '').replace(/\/+/g, '/').replace(/\/$/, '');
}

async function _xcloudPostMoveRequest(source, target, onConflict, renameTo) {
    const fd = new FormData();
    fd.append('source', source);
    fd.append('target', target);
    fd.append('on_conflict', onConflict || 'abort');
    if (renameTo) fd.append('rename_to', renameTo);
    const res = await fetch('server.php?action=move', { method: 'POST', body: fd, credentials: 'same-origin' });
    return res.json();
}

function _xcloudResolveMoveSourceFromDom(source) {
    if (!source) return source;
    const base = _xcloudNormMoveUrl(source).split('/').pop();
    if (!base) return source;
    let found = '';
    document.querySelectorAll('[data-url],[data-path]').forEach(function(el) {
        const u = el.getAttribute('data-url') || el.getAttribute('data-path') || '';
        const b = _xcloudNormMoveUrl(u).split('/').pop();
        if (b === base) found = u;
    });
    return found || source;
}

function _xcloudEnsureMoveConflictModal() {
    let el = document.getElementById('xcloud-move-conflict-modal');
    if (el) return el;
    el = document.createElement('div');
    el.id = 'xcloud-move-conflict-modal';
    el.innerHTML =
        '<div class="xcloud-move-conflict-box" role="dialog" aria-modal="true">' +
        '  <button type="button" class="xcloud-move-conflict-close" aria-label="Fermer">&times;</button>' +
        '  <h4 class="xcloud-move-conflict-title"></h4>' +
        '  <p class="xcloud-move-conflict-msg"></p>' +
        '  <label class="xcloud-move-conflict-lbl">Nouveau nom</label>' +
        '  <input type="text" class="xcloud-move-conflict-input" autocomplete="off" spellcheck="false">' +
        '  <div class="xcloud-move-conflict-actions">' +
        '    <button type="button" class="xcloud-move-conflict-btn xcloud-move-conflict-cancel">Annuler</button>' +
        '    <button type="button" class="xcloud-move-conflict-btn xcloud-move-conflict-replace">Remplacer</button>' +
        '    <button type="button" class="xcloud-move-conflict-btn xcloud-move-conflict-rename xcloud-move-conflict-primary">Renommer et placer</button>' +
        '  </div>' +
        '</div>';
    el.style.cssText = 'display:none;position:fixed;inset:0;z-index:99500;align-items:center;justify-content:center;padding:20px;background:rgba(0,0,0,0.72);backdrop-filter:blur(6px);';
    const box = el.querySelector('.xcloud-move-conflict-box');
    if (box) box.style.cssText = 'position:relative;width:min(420px,94vw);background:#111;border:1px solid #e53935;border-radius:12px;padding:20px 22px;box-shadow:0 20px 50px rgba(0,0,0,0.75);color:#fff;font-family:inherit;';
    el.querySelectorAll('.xcloud-move-conflict-close').forEach(function(btn) {
        btn.style.cssText = 'position:absolute;top:10px;right:12px;background:none;border:none;color:#888;font-size:1.4rem;cursor:pointer;';
    });
    el.querySelectorAll('.xcloud-move-conflict-title').forEach(function(t) {
        t.style.cssText = 'margin:0 0 10px;font-size:0.95rem;font-weight:800;color:#ff6b6b;';
    });
    el.querySelectorAll('.xcloud-move-conflict-msg').forEach(function(p) {
        p.style.cssText = 'margin:0 0 14px;font-size:0.82rem;line-height:1.45;color:#ccc;';
    });
    el.querySelectorAll('.xcloud-move-conflict-lbl').forEach(function(l) {
        l.style.cssText = 'display:block;font-size:0.68rem;text-transform:uppercase;letter-spacing:0.6px;color:#888;margin-bottom:6px;';
    });
    el.querySelectorAll('.xcloud-move-conflict-input').forEach(function(inp) {
        inp.style.cssText = 'width:100%;box-sizing:border-box;padding:10px 12px;margin-bottom:16px;background:#000;border:1px solid #333;border-radius:6px;color:#fff;font-size:0.88rem;';
    });
    el.querySelectorAll('.xcloud-move-conflict-actions').forEach(function(a) {
        a.style.cssText = 'display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;';
    });
    el.querySelectorAll('.xcloud-move-conflict-btn').forEach(function(b) {
        b.style.cssText = 'padding:8px 14px;border-radius:6px;border:1px solid #444;background:#1a1a1a;color:#ddd;font-size:0.78rem;font-weight:700;cursor:pointer;font-family:inherit;';
    });
    el.querySelectorAll('.xcloud-move-conflict-primary').forEach(function(b) {
        b.style.cssText += 'background:#e53935;border-color:#e53935;color:#000;';
    });
    document.body.appendChild(el);
    return el;
}

function _xcloudShowMoveConflictDialog(conflictName, suggestedName) {
    return new Promise(function(resolve) {
        const modal = _xcloudEnsureMoveConflictModal();
        const title = modal.querySelector('.xcloud-move-conflict-title');
        const msg = modal.querySelector('.xcloud-move-conflict-msg');
        const input = modal.querySelector('.xcloud-move-conflict-input');
        const btnCancel = modal.querySelector('.xcloud-move-conflict-cancel');
        const btnReplace = modal.querySelector('.xcloud-move-conflict-replace');
        const btnRename = modal.querySelector('.xcloud-move-conflict-rename');
        const btnClose = modal.querySelector('.xcloud-move-conflict-close');
        if (title) title.textContent = 'Nom déjà utilisé';
        if (msg) {
            msg.textContent = 'Un élément « ' + conflictName + ' » existe déjà dans ce dossier. Remplacer l\'existant ou choisir un autre nom ?';
        }
        if (input) input.value = suggestedName || conflictName || '';
        function close(result) {
            modal.style.display = 'none';
            btnCancel && btnCancel.removeEventListener('click', onCancel);
            btnReplace && btnReplace.removeEventListener('click', onReplace);
            btnRename && btnRename.removeEventListener('click', onRename);
            btnClose && btnClose.removeEventListener('click', onCancel);
            resolve(result);
        }
        function onCancel() { close(null); }
        function onReplace() { close({ mode: 'replace' }); }
        function onRename() {
            const v = input ? String(input.value || '').trim() : '';
            if (!v) { if (typeof showToast === 'function') showToast('Indiquez un nom', 'error'); return; }
            close({ mode: 'rename', renameTo: v });
        }
        btnCancel && btnCancel.addEventListener('click', onCancel);
        btnReplace && btnReplace.addEventListener('click', onReplace);
        btnRename && btnRename.addEventListener('click', onRename);
        btnClose && btnClose.addEventListener('click', onCancel);
        modal.style.display = 'flex';
        if (input) { input.focus(); input.select(); }
    });
}

async function _xcloudPerformMoveWithConflict(source, target) {
    if (!source || !target) return { success: false, error: 'Données manquantes' };
    let src = String(source);
    const tgt = normalizeFolderPath(String(target));
    if (window.__xcloudDragSource && _xcloudNormMoveUrl(window.__xcloudDragSource) !== _xcloudNormMoveUrl(src)) {
        src = window.__xcloudDragSource;
    }
    let d = await _xcloudPostMoveRequest(src, tgt, 'abort');
    if (d && d.code === 'source_not_found') {
        const resolved = _xcloudResolveMoveSourceFromDom(src);
        if (resolved && resolved !== src) {
            src = resolved;
            d = await _xcloudPostMoveRequest(src, tgt, 'abort');
        }
    }
    while (d && d.code === 'name_conflict') {
        const choice = await _xcloudShowMoveConflictDialog(d.conflict_name || '', d.suggested_name || '');
        if (!choice) return { success: false, cancelled: true };
        if (choice.mode === 'replace') {
            d = await _xcloudPostMoveRequest(src, tgt, 'replace');
        } else if (choice.mode === 'rename') {
            d = await _xcloudPostMoveRequest(src, tgt, 'rename', choice.renameTo);
        }
    }
    if (d && d.code === 'source_not_found') {
        if (typeof _invalidateAllFolderCaches === 'function') _invalidateAllFolderCaches();
        if (typeof showToast === 'function') showToast('Élément introuvable — actualisez la page', 'error');
    }
    return d || { success: false };
}

document.addEventListener('dragstart', function(e) {
    try {
        const card = e.target && e.target.closest ? e.target.closest('[data-url],[data-path]') : null;
        if (!card) return;
        const url = card.getAttribute('data-url') || card.getAttribute('data-path') || '';
        if (!url) return;
        window.__xcloudDragSource = url;
        try {
            e.dataTransfer.setData('text/plain', url);
            e.dataTransfer.setData('application/x-xcloud-url', url);
        } catch (dtErr) {}
    } catch (err) {}
}, true);

document.addEventListener('dragend', function() {
    window.__xcloudDragSource = '';
}, true);

"""

needle = 'async function executeMove(targetUrl) {'
if '_xcloudPerformMoveWithConflict' not in content:
    pos = content.find(needle)
    if pos == -1:
        print("Point d'insertion executeMove introuvable.", file=sys.stderr)
        sys.exit(1)
    content = content[:pos] + HELPERS + '\n' + content[pos:]

replacements = [
    (
        """        try {
            const fd = new FormData();
            fd.append('source', url);
            fd.append('target', targetUrl);
            const res = await fetch('server.php?action=move', {method:'POST', body: fd});
            const data = await res.json();
            if (data.success) {""",
        """        try {
            const data = await _xcloudPerformMoveWithConflict(url, targetUrl);
            if (data.success) {""",
    ),
    (
        "            } else fail++;\n        } catch (e) { fail++; }\n    }\n    showToast(`Transfert:",
        "            } else if (!data.cancelled) fail++;\n        } catch (e) { fail++; }\n    }\n    showToast(`Transfert:",
    ),
    (
        """    showToast('Déplacement...', 'info');
    const tgtFolder = normalizeFolderPath(targetFolderUrl);
    const fd = new FormData();
    fd.append('source', sourceUrl);
    fd.append('target', tgtFolder);
    try {
        const res = await fetch('server.php?action=move', { method: 'POST', body: fd });
        const data = await res.json();
        if (data.success) {""",
        """    showToast('Déplacement...', 'info');
    const tgtFolder = normalizeFolderPath(targetFolderUrl);
    try {
        const data = await _xcloudPerformMoveWithConflict(sourceUrl, tgtFolder);
        if (data.success) {""",
    ),
    (
        "        } else showToast(zServerErr(data, 'Erreur'), 'error');\n    } catch(e) { showToast('Erreur serveur', 'error'); }\n}\n\nfunction initRootDropZone()",
        "        } else if (!data.cancelled) showToast(zServerErr(data, 'Erreur'), 'error');\n    } catch(e) { showToast('Erreur serveur', 'error'); }\n}\n\nfunction initRootDropZone()",
    ),
    (
        """    el.addEventListener('dragstart', e => {
        draggedItem = url;
        e.dataTransfer.setData('text/plain', url);
        el.style.opacity = '0.4';
    });
    el.addEventListener('dragend', () => { draggedItem = null; el.style.opacity = '1'; });
}""",
        """    el.addEventListener('dragstart', e => {
        draggedItem = url;
        window.__xcloudDragSource = url;
        e.dataTransfer.setData('text/plain', url);
        el.style.opacity = '0.4';
    });
    el.addEventListener('dragend', () => { draggedItem = null; window.__xcloudDragSource = ''; el.style.opacity = '1'; });
}""",
    ),
]

for old, new in replacements:
    if old in content:
        content = content.replace(old, new, 1)

content = re.sub(
    r'\s*<script[^>]*src=["\']assets/js/xcloud-move-conflict\.js["\'][^>]*></script>\s*',
    '\n',
    content,
    flags=re.I,
)

# Bootstrap auto-restore (identique au patch PHP)
bootstrap = """require_once 'config.php';

if (is_readable(__DIR__ . '/_xcloud_restore_index.php')) {
    $__idx = __DIR__ . '/index.php';
    $__needRestore = false;
    $__f = @fopen($__idx, 'rb');
    if ($__f) {
        $__sz = (int)(@filesize($__idx) ?: 0);
        if ($__sz < 2500000) {
            $__needRestore = true;
        } else {
            fseek($__f, max(0, $__sz - 512), SEEK_SET);
            $__tail = (string)fread($__f, 512);
            if (stripos($__tail, '</html>') === false) {
                $__needRestore = true;
            }
        }
        fclose($__f);
    }
    if ($__needRestore) {
        require __DIR__ . '/_xcloud_restore_index.php';
        exit;
    }
}

"""
if "xcloud_restore_index.php" not in content.split('safeReadJson')[0]:
    content = content.replace("require_once 'config.php';\n\nif (!function_exists('safeReadJson'))", bootstrap + "if (!function_exists('safeReadJson'))", 1)

with open(DST, 'w', encoding='utf-8', newline='\n') as f:
    f.write(content)

lines = content.count('\n') + 1
ok_end = bool(re.search(r'</body>\s*</html>\s*$', content))
print(f'OK — index.php restauré ({lines} lignes, fin HTML {"valide" if ok_end else "INVALIDE"})')
