<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';

if (!admin_is_authenticated()) {
    admin_redirect('/admin/?route=login');
}

if (!function_exists('admin_theme_tree_build')) {
    function admin_theme_tree_build(array $entries): array
    {
        $tree = [];

        foreach ($entries as $entry) {
            $path = str_replace('\\', '/', (string) ($entry['path'] ?? ''));
            if ($path === '') {
                continue;
            }

            $segments = explode('/', $path);
            $cursor = &$tree;

            foreach ($segments as $index => $segment) {
                if (!isset($cursor[$segment])) {
                    $cursor[$segment] = [
                        'name' => $segment,
                        'path' => implode('/', array_slice($segments, 0, $index + 1)),
                        'type' => $index === count($segments) - 1 ? (string) ($entry['type'] ?? 'file') : 'dir',
                        'children' => [],
                    ];
                }

                if ($index === count($segments) - 1) {
                    $cursor[$segment]['type'] = (string) ($entry['type'] ?? 'file');
                    if (isset($entry['size'])) {
                        $cursor[$segment]['size'] = (int) $entry['size'];
                    }
                    if (isset($entry['mtime'])) {
                        $cursor[$segment]['mtime'] = (int) $entry['mtime'];
                    }
                }

                $cursor = &$cursor[$segment]['children'];
            }

            unset($cursor);
        }

        ksort($tree);

        return $tree;
    }
}

if (!function_exists('admin_theme_tree_sort')) {
    function admin_theme_tree_sort(array &$nodes): void
    {
        uasort($nodes, static function (array $left, array $right): int {
            $leftType = (string) ($left['type'] ?? 'file');
            $rightType = (string) ($right['type'] ?? 'file');
            if ($leftType !== $rightType) {
                return $leftType === 'dir' ? -1 : 1;
            }

            return strcmp((string) ($left['name'] ?? ''), (string) ($right['name'] ?? ''));
        });

        foreach ($nodes as &$node) {
            if (!empty($node['children']) && is_array($node['children'])) {
                admin_theme_tree_sort($node['children']);
            }
        }
        unset($node);
    }
}

if (!function_exists('admin_theme_tree_render')) {
    function admin_theme_tree_render(array $nodes, string $selectedFile): void
    {
        if ($nodes === []) {
            return;
        }

        echo '<ul class="tree-level">';
        foreach ($nodes as $node) {
            $nodeType = (string) ($node['type'] ?? 'file');
            $nodePath = (string) ($node['path'] ?? '');
            $nodeName = (string) ($node['name'] ?? $nodePath);

            echo '<li class="tree-node tree-node-' . admin_escape($nodeType) . '">';

            if ($nodeType === 'dir') {
                $isOpen = $selectedFile !== '' && ($selectedFile === $nodePath || str_starts_with($selectedFile, $nodePath . '/'));
                echo '<details ' . ($isOpen ? 'open' : '') . '>';
                echo '<summary>' . admin_escape($nodeName) . '</summary>';
                admin_theme_tree_render($node['children'] ?? [], $selectedFile);
                echo '</details>';
            } else {
                $activeClass = $selectedFile === $nodePath ? ' active' : '';
                echo '<a class="tree-file' . $activeClass . '" href="/admin/theme-editor.php?file=' . rawurlencode($nodePath) . '">' . admin_escape($nodeName) . '</a>';
            }

            echo '</li>';
        }
        echo '</ul>';
    }
}

$state = admin_refresh_state();
$config = $state['config'];
$activeTheme = admin_active_theme($config);
$themeDir = admin_theme_dir($config);
$themeEntries = admin_theme_entries($config);
$themeFiles = admin_theme_files($config);
$tree = admin_theme_tree_build($themeEntries);
admin_theme_tree_sort($tree);

$defaultFile = in_array('functions.php', $themeFiles, true) ? 'functions.php' : ($themeFiles[0] ?? '');
$currentFile = str_replace('\\', '/', trim((string) ($_GET['file'] ?? $defaultFile)));
if (!in_array($currentFile, $themeFiles, true)) {
    $currentFile = $defaultFile;
}

$errors = [];
$notice = '';
$lintNotice = '';
$previewPath = '/' . ltrim(trim((string) ($_GET['preview'] ?? '/')), '/');
if ($previewPath === '//') {
    $previewPath = '/';
}
$reloadPreview = false;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $csrfToken = (string) ($_POST['csrf_token'] ?? '');
    if (!admin_verify_csrf($csrfToken)) {
        $errors[] = 'Security token mismatch. Please refresh and try again.';
    } else {
        $editorAction = strtolower(trim((string) ($_POST['editor_action'] ?? 'save')));

        if ($editorAction === 'save') {
            $requestedFile = str_replace('\\', '/', trim((string) ($_POST['theme_file'] ?? '')));
            $filePath = admin_resolve_theme_file($config, $requestedFile);
            $contents = (string) ($_POST['file_contents'] ?? '');

            if ($requestedFile === '') {
                $errors[] = 'No theme file was selected.';
            } elseif ($filePath === null) {
                $errors[] = 'That file cannot be edited here.';
            } elseif (!is_file($filePath) || !is_writable($filePath)) {
                $errors[] = 'The selected theme file is not writable.';
            } else {
                $extension = strtolower(pathinfo($requestedFile, PATHINFO_EXTENSION));
                if ($extension === 'php') {
                    $lintResult = admin_lint_php_code($contents);
                    if (!$lintResult['ok']) {
                        $errors[] = (string) $lintResult['message'];
                    } else {
                        $lintNotice = (string) $lintResult['message'];
                    }
                }

                if ($errors === []) {
                    admin_backup_theme_file($filePath, $themeDir);
                    if (file_put_contents($filePath, $contents, LOCK_EX) === false) {
                        $errors[] = 'Theme file could not be saved.';
                    } else {
                        $notice = 'Theme file saved successfully.';
                        $currentFile = $requestedFile;
                        $reloadPreview = true;
                    }
                } else {
                    $currentFile = $requestedFile;
                }
            }
        } elseif ($editorAction === 'create_file') {
            $newFile = str_replace('\\', '/', trim((string) ($_POST['new_file_path'] ?? '')));
            $newFilePath = admin_resolve_theme_file($config, $newFile, true);

            if ($newFile === '') {
                $errors[] = 'New file path is required.';
            } elseif ($newFilePath === null) {
                $errors[] = 'That file path is not allowed.';
            } elseif (is_file($newFilePath)) {
                $errors[] = 'That file already exists.';
            } elseif (file_put_contents($newFilePath, '', LOCK_EX) === false) {
                $errors[] = 'New file could not be created.';
            } else {
                $notice = 'New file created successfully.';
                $currentFile = $newFile;
            }
        } elseif ($editorAction === 'create_folder') {
            $newFolder = trim((string) ($_POST['new_folder_path'] ?? ''));
            $result = admin_create_theme_folder($config, $newFolder);
            if ($result['ok']) {
                $notice = (string) $result['message'];
            } else {
                $errors[] = (string) $result['message'];
            }
        } elseif ($editorAction === 'upload_file') {
            $result = admin_theme_upload_file($config, $_FILES['theme_upload'] ?? []);
            if ($result['ok']) {
                $notice = (string) $result['message'];
                $currentFile = (string) ($result['path'] ?? $currentFile);
                $reloadPreview = true;
            } else {
                $errors[] = (string) $result['message'];
            }
        } elseif ($editorAction === 'delete_file') {
            $deleteFile = str_replace('\\', '/', trim((string) ($_POST['theme_file'] ?? '')));
            $result = admin_delete_theme_file($config, $deleteFile);
            if ($result['ok']) {
                $notice = (string) $result['message'];
                $currentFile = $defaultFile;
                $reloadPreview = true;
            } else {
                $errors[] = (string) $result['message'];
            }
        }
    }

    $state = admin_refresh_state();
    $config = $state['config'];
    $activeTheme = admin_active_theme($config);
    $themeDir = admin_theme_dir($config);
    $themeEntries = admin_theme_entries($config);
    $themeFiles = admin_theme_files($config);
    $tree = admin_theme_tree_build($themeEntries);
    admin_theme_tree_sort($tree);
    $defaultFile = in_array('functions.php', $themeFiles, true) ? 'functions.php' : ($themeFiles[0] ?? '');
    if (!in_array($currentFile, $themeFiles, true)) {
        $currentFile = $defaultFile;
    }
}

$currentPath = $currentFile !== '' ? admin_resolve_theme_file($config, $currentFile) : null;
$currentContents = $currentPath !== null && is_file($currentPath)
    ? (string) file_get_contents($currentPath)
    : '';
$currentFileSize = $currentPath !== null && is_file($currentPath) ? (int) filesize($currentPath) : 0;
$currentFileModified = $currentPath !== null && is_file($currentPath) ? (int) filemtime($currentPath) : 0;
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?php echo admin_escape(admin_site_title($config)); ?> Theme Editor</title>
    <?php echo admin_shared_styles("
        .editor-layout { display:grid; grid-template-columns:320px minmax(0,1fr); gap:22px; align-items:start; }
        .panel { background:var(--panel); border:1px solid var(--line); border-radius:18px; padding:22px; box-shadow:0 16px 40px rgba(44,36,27,.08); margin-bottom:22px; }
        .editor-layout { display:grid; grid-template-columns:320px 1fr; gap:22px; align-items:start; }
        .tree-panel { padding:16px; border:1px solid var(--line); border-radius:16px; background:#fff; max-height:72vh; overflow:auto; }
        .tree-tools { display:grid; gap:12px; margin-bottom:16px; }
        .tree-tools form { display:grid; gap:8px; }
        .tree-tools input[type='text'] { width:100%; padding:10px 12px; border:1px solid var(--line); border-radius:10px; font:inherit; }
        .tree-level { list-style:none; margin:0; padding-left:16px; }
        .tree-node { margin:4px 0; }
        .tree-node details > summary { cursor:pointer; color:var(--text); padding:6px 8px; border-radius:8px; }
        .tree-node details > summary:hover { background:#f3eadb; }
        .tree-file { display:block; padding:7px 10px; border-radius:8px; color:var(--text); text-decoration:none; }
        .tree-file:hover, .tree-file.active { background:#efe3d1; }
        .editor-panel { display:grid; gap:14px; }
        .editor-workspace { display:grid; grid-template-columns:minmax(0, 1fr) minmax(320px, 42%); gap:16px; align-items:start; }
        .editor-toolbar { display:flex; justify-content:space-between; gap:16px; align-items:center; flex-wrap:wrap; }
        .btn { display:inline-flex; align-items:center; justify-content:center; border:0; border-radius:12px; padding:12px 18px; background:var(--accent); color:#fff; cursor:pointer; font:inherit; text-decoration:none; }
        .btn:hover { background:var(--accent-dark); }
        .btn.secondary { background:#e7dcc8; color:var(--text); }
        .btn.danger { background:#b91c1c; }
        .btn.danger:hover { background:#991b1b; }
        .code-shell { border:1px solid var(--editor-line); border-radius:18px; overflow:hidden; background:var(--editor); }
        .code-head { padding:12px 16px; background:#0b1220; color:#cbd5e1; border-bottom:1px solid var(--editor-line); }
        textarea { width:100%; min-height:68vh; border:0; padding:18px; font:14px/1.6 Consolas, Monaco, monospace; background:var(--editor); color:var(--editor-text); resize:vertical; outline:none; }
        .subtle { color:var(--muted); font-size:13px; }
        .warning { color:var(--warn); font-weight:600; }
        @media (max-width: 1380px) { .editor-workspace { grid-template-columns:1fr; } }
        @media (max-width: 1100px) { .editor-layout { grid-template-columns:1fr; } .tree-panel { max-height:none; } }
    "); ?>
</head>
<body>
    <div class="app">
        <?php admin_render_sidebar('theme-editor'); ?>
        <main class="content">
            <div class="page-header">
                <h1 class="page-title">Theme Editor</h1>
                <p class="page-subtitle">Active theme files ko mobile-friendly editor me manage karein, live preview ke saath.</p>
            </div>
            <div class="panel">
                <div class="meta">Active theme: <strong><?php echo admin_escape($activeTheme); ?></strong></div>
                <?php if ($notice !== ''): ?><div class="message success"><?php echo admin_escape($notice); ?></div><?php endif; ?>
                <?php if ($lintNotice !== ''): ?><div class="message success"><?php echo admin_escape($lintNotice); ?></div><?php endif; ?>
                <?php foreach ($errors as $error): ?><div class="message error"><?php echo admin_escape($error); ?></div><?php endforeach; ?>
                <div class="editor-layout">
                    <aside class="tree-panel">
                        <div class="tree-tools">
                            <form method="post" action="/admin/theme-editor.php<?php echo $currentFile !== '' ? '?file=' . rawurlencode($currentFile) : ''; ?>">
                                <input type="hidden" name="csrf_token" value="<?php echo admin_escape(admin_csrf_token()); ?>">
                                <input type="hidden" name="editor_action" value="create_file">
                                <input type="text" name="new_file_path" placeholder="New file path, e.g. assets/app.css">
                                <button class="btn secondary" type="submit">New File</button>
                            </form>
                            <form method="post" action="/admin/theme-editor.php<?php echo $currentFile !== '' ? '?file=' . rawurlencode($currentFile) : ''; ?>">
                                <input type="hidden" name="csrf_token" value="<?php echo admin_escape(admin_csrf_token()); ?>">
                                <input type="hidden" name="editor_action" value="create_folder">
                                <input type="text" name="new_folder_path" placeholder="New folder path, e.g. assets/css">
                                <button class="btn secondary" type="submit">New Folder</button>
                            </form>
                            <form method="post" enctype="multipart/form-data" action="/admin/theme-editor.php<?php echo $currentFile !== '' ? '?file=' . rawurlencode($currentFile) . '&preview=' . rawurlencode($previewPath) : ''; ?>">
                                <input type="hidden" name="csrf_token" value="<?php echo admin_escape(admin_csrf_token()); ?>">
                                <input type="hidden" name="editor_action" value="upload_file">
                                <div class="subtle">Images upload to <strong>/content/themes/<?php echo admin_escape($activeTheme); ?>/assets/images/</strong></div>
                                <input type="file" name="theme_upload" required>
                                <button class="btn secondary" type="submit">Upload File</button>
                            </form>
                            <input id="fileTreeSearch" type="text" placeholder="Search files">
                        </div>
                        <div id="themeFileTree"><?php admin_theme_tree_render($tree, $currentFile); ?></div>
                    </aside>
                    <section class="editor-panel">
                        <div class="editor-toolbar">
                            <div>
                                <div class="meta" style="margin-bottom:6px;">Editing: <strong><?php echo admin_escape($currentFile !== '' ? $currentFile : 'No file selected'); ?></strong></div>
                                <?php if ($currentPath !== null && is_file($currentPath)): ?>
                                    <div class="subtle">
                                        Size: <?php echo admin_escape((string) $currentFileSize); ?> bytes
                                        |
                                        Modified: <?php echo admin_escape(date('Y-m-d H:i:s', $currentFileModified)); ?>
                                        <?php if ($currentFileSize > 200000): ?>
                                            <span class="warning">| Large file</span>
                                        <?php endif; ?>
                                    </div>
                                <?php endif; ?>
                            </div>
                            <?php if ($currentFile !== ''): ?>
                                <form method="post" action="/admin/theme-editor.php?file=<?php echo rawurlencode($currentFile); ?>" onsubmit="return confirm('Delete this file?');">
                                    <input type="hidden" name="csrf_token" value="<?php echo admin_escape(admin_csrf_token()); ?>">
                                    <input type="hidden" name="editor_action" value="delete_file">
                                    <input type="hidden" name="theme_file" value="<?php echo admin_escape($currentFile); ?>">
                                    <button class="btn danger" type="submit">Delete File</button>
                                </form>
                            <?php endif; ?>
                        </div>
                        <div class="editor-workspace">
                            <?php if ($currentFile !== '' && $currentPath !== null): ?>
                                <form method="post" action="/admin/theme-editor.php?file=<?php echo rawurlencode($currentFile); ?>&preview=<?php echo rawurlencode($previewPath); ?>" id="themeEditorForm">
                                    <input type="hidden" name="csrf_token" value="<?php echo admin_escape(admin_csrf_token()); ?>">
                                    <input type="hidden" name="editor_action" value="save">
                                    <input type="hidden" name="theme_file" value="<?php echo admin_escape($currentFile); ?>">
                                    <div class="editor-toolbar" style="margin-bottom:12px;">
                                        <div style="display:flex; gap:10px; flex-wrap:wrap; align-items:center;">
                                            <input id="editorSearchInput" type="text" placeholder="Find in file" style="padding:10px 12px; border:1px solid var(--line); border-radius:10px; min-width:220px; background:#fff; color:var(--text); font:inherit;">
                                            <button class="btn secondary" type="button" id="editorFindNext">Next</button>
                                            <button class="btn secondary" type="button" id="editorFindPrev">Prev</button>
                                            <span class="subtle" id="editorSearchStatus">Ready</span>
                                        </div>
                                    </div>
                                    <div class="code-shell">
                                        <div class="code-head"><?php echo admin_escape($currentFile); ?></div>
                                        <textarea name="file_contents" id="themeEditorTextarea" spellcheck="false"><?php echo admin_escape($currentContents); ?></textarea>
                                    </div>
                                    <div style="margin-top:16px;">
                                        <button class="btn" type="submit">Save File</button>
                                    </div>
                                </form>
                            <?php else: ?>
                                <div class="panel" style="margin:0;">
                                    Select a theme file from the left sidebar to start editing.
                                </div>
                            <?php endif; ?>

                            <div class="panel" style="margin:0;">
                                <div class="editor-toolbar">
                                    <div>
                                        <div class="meta" style="margin-bottom:6px;">Live Preview</div>
                                        <div class="subtle">Route: <?php echo admin_escape($previewPath); ?></div>
                                    </div>
                                    <form method="get" action="/admin/theme-editor.php" style="display:flex; gap:10px; flex-wrap:wrap; align-items:center;">
                                        <?php if ($currentFile !== ''): ?><input type="hidden" name="file" value="<?php echo admin_escape($currentFile); ?>"><?php endif; ?>
                                        <input type="text" name="preview" value="<?php echo admin_escape($previewPath); ?>" style="padding:10px 12px; border:1px solid var(--line); border-radius:10px; min-width:220px; background:#fff; color:var(--text); font:inherit;">
                                        <button class="btn secondary" type="submit">Open Preview</button>
                                        <button class="btn secondary" type="button" id="reloadPreviewButton">Reload Preview</button>
                                    </form>
                                </div>
                                <div class="code-shell" style="margin-top:12px; background:#fff; border-color:var(--line);">
                                    <iframe id="themePreviewFrame" src="<?php echo admin_escape($previewPath); ?>" style="width:100%; min-height:520px; border:0; background:#fff;" loading="lazy"></iframe>
                                </div>
                            </div>
                        </div>
                    </section>
                </div>
            </div>
        </main>
    </div>
    <script>
    (function () {
        var fileSearch = document.getElementById('fileTreeSearch');
        var fileTree = document.getElementById('themeFileTree');
        if (fileSearch && fileTree) {
            fileSearch.addEventListener('input', function () {
                var term = fileSearch.value.toLowerCase();
                fileTree.querySelectorAll('.tree-file').forEach(function (link) {
                    var match = link.textContent.toLowerCase().indexOf(term) !== -1 || link.getAttribute('href').toLowerCase().indexOf(term) !== -1;
                    link.style.display = match ? '' : 'none';
                });
            });
        }

        var textarea = document.getElementById('themeEditorTextarea');
        var searchInput = document.getElementById('editorSearchInput');
        var status = document.getElementById('editorSearchStatus');
        var lastIndex = -1;

        function findInEditor(direction) {
            if (!textarea || !searchInput || !status) {
                return;
            }

            var needle = searchInput.value;
            if (!needle) {
                status.textContent = 'Enter search text';
                return;
            }

            var haystack = textarea.value;
            var start = direction > 0 ? textarea.selectionEnd : textarea.selectionStart - needle.length - 1;
            var index = direction > 0 ? haystack.indexOf(needle, Math.max(0, start)) : haystack.lastIndexOf(needle, Math.max(0, start));

            if (index === -1 && direction > 0) {
                index = haystack.indexOf(needle, 0);
            } else if (index === -1 && direction < 0) {
                index = haystack.lastIndexOf(needle);
            }

            if (index === -1) {
                status.textContent = 'No matches';
                return;
            }

            lastIndex = index;
            textarea.focus();
            textarea.setSelectionRange(index, index + needle.length);
            status.textContent = 'Match at ' + (index + 1);
        }

        var findNext = document.getElementById('editorFindNext');
        var findPrev = document.getElementById('editorFindPrev');
        if (findNext) {
            findNext.addEventListener('click', function () { findInEditor(1); });
        }
        if (findPrev) {
            findPrev.addEventListener('click', function () { findInEditor(-1); });
        }
        if (searchInput) {
            searchInput.addEventListener('keydown', function (event) {
                if (event.key === 'Enter') {
                    event.preventDefault();
                    findInEditor(event.shiftKey ? -1 : 1);
                }
            });
        }

        var previewFrame = document.getElementById('themePreviewFrame');
        var reloadButton = document.getElementById('reloadPreviewButton');
        var previewBase = <?php echo json_encode($previewPath, JSON_UNESCAPED_SLASHES); ?>;
        function reloadPreview() {
            if (!previewFrame) {
                return;
            }
            previewFrame.src = previewBase + (previewBase.indexOf('?') === -1 ? '?' : '&') + 'preview_refresh=' + Date.now();
        }
        if (reloadButton) {
            reloadButton.addEventListener('click', reloadPreview);
        }
        <?php if ($reloadPreview): ?>
        window.addEventListener('load', function () {
            reloadPreview();
        });
        <?php endif; ?>
    }());
    </script>
</body>
</html>
