<?php
/* JSON Editor — fixed: removed nested forms, JS-submit for list actions, robust save */
declare(strict_types=1);
ini_set('display_errors','1');
error_reporting(E_ALL);

$dir = __DIR__;
$files = array_values(array_filter(scandir($dir), fn($f) => is_file($dir.'/'.$f) && preg_match('/\.json$/i',$f)));
$messages = [];

function h($v): string { return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
function make_input_name(array $path): string {
    if (!$path) return '';
    $name = array_shift($path);
    foreach ($path as $p) $name .= '[' . $p . ']';
    return $name;
}

/* -------------------- Templates (exact as you provided) -------------------- */
$template_main = <<<JSON
{
  "current": "001000",
  "site": "https://primavera-foundation.am/",
  "bot_webapp": "https://t.me/primavera_events_bot?startapp",
  "partner": "primavera",
  "logo": "events/primavera/img/logo-blue.png",
  "css": "events/primavera/style.css",
  "main": { "id": "001000", "name": "primavera", "date": "0000_00_00" },
  "bg": { "image": "events/primavera/bg_v1.jpg", "opacity": "100%" },
  "langs": { "EN": "Eng", "AM": "Arm", "RU": "Rus" },
  "contacts": {
    "title": { "EN": "Support", "AM": "Աջակցություն", "RU": "Помощь" },
    "logo": "events/primavera/img/support_orange.svg",
    "details": { "EN": "If you need some help ...", "AM": "Եթե օգնության կարիք ունեք:..", "RU": "Если вам нужна помощь ..." },
    "telegram": { "title": "@PrimaveraFoundation", "link": "https://t.me/PrimaveraFoundation" },
    "email": { "title": "hello@primavera-foundation.am", "link": "mailto:hello@primavera-foundation.am" }
  },
  "events": { "title": { "EN": "COME & JOIN US!", "AM": "ՄԻԱՑԵՔ ՄԵԶ", "RU": "ПРИСОЕДИНЯЙТЕСЬ К НАМ!" }, "details": "", "list": [ { "id": "001001", "name": "2025_Chamber_Music_School_Gala_Concert", "date": "2025_05_09" }, { "id": "001002", "name": "The_Evening_of_Music_Poetry", "date": "2025_06_10" }, { "id": "001003", "name": "The_Evening_of_Music_Poetry", "date": "2025_05_08" } ] },
  "projects": {
    "title": { "EN": "CHOOSE YOUR PROJECT & MAKE IT COME TRUE!", "AM": "ԸՆՏՐԵՔ ՁԵՐ ՆԱԽԱԳԻԾԸ ԵՎ ԴԱՐՁՐԵՔ ԱՅՆ ԻՐԱԿԱՆՈՒԹՅՈՒՆ:", "RU": "ВЫБЕРИТЕ ЛИЧНЫЙ ПРОЕКТ И ОСУЩЕСТВИТЕ ЕГО!" },
    "details": { "EN": "OR CHOOSE YOUR CORPORATE PARTNERSHIP - GET IN TOUCH TODAY TO MAKE VOICE OF ARMENIAN ARTISTS STRONGER!", "AM":"...", "RU":"..." },
    "list": [ { "id": "001003", "name": "Dedicate_a_release_by_armenian_artist", "date": "" }, { "id": "001004", "name": "Patronof_a_teaching_toolkit_in_Armenia", "date": "" }, { "id": "001005", "name": "Become_a_patron_of_a_video_tutorial", "date": "" } ]
  },
  "crypto": { "title": { "EN": "Donate by Cryptocurency", "AM": "Նվիրաբերեք...", "RU":"..." }, "details": "", "options": { "btc":"...", "eth":"...", "bnb":"...", "trx":"..." } },
  "buttons": { "_example": { "title": "Button title" }, "home": { "title": { "EN":"About Us" }, "class": ".home" } }
}
JSON;

$template_home = <<<JSON
{
  "type": "home",
  "title": "Primavera Foundation",
  "date": "",
  "place": "Office Address",
  "place_link": "Office link",
  "bg": "events/primavera/bg_v1.jpg",
  "logo": "events/primavera/img/logo-blue.png",
  "likes": { "title": "Votes here", "details": { "1": { "name": "aaa", "likes": 0 }, "2": { "name": "bbb", "likes": 0 }, "3": { "name": "ccc", "likes": 0 } } },
  "short": { "title": { "EN": "Primavera Charitable Foundation", "AM": "Պրիմավերա...", "RU": "..." }, "details": { "EN":"...", "AM":"...", "RU":"..."} },
  "full": { "title": { "EN":"<img...>", "AM":"...", "RU":"..." }, "details": { "EN":"...", "AM":"...", "RU":"..." } },
  "detailed": "about",
  "buttons": { "struct": { "row1": ["events","about"], "row2": ["donate","share"] } }
}
JSON;

$template_event = <<<JSON
{
  "type":"event",
  "title":{"EN":"2nd Yerevan Chamber Music School — Graduation Concert","AM":"...","RU":"..."},
  "date":"09.05.2025","time":"19-00","like":false,
  "place":{"EN":"Arno Babajanyan Concert Hall | Abovyan st. 2","AM":"...","RU":"..."},
  "place_link":"https://babajanyanhall.org/en/the-hall/","bg":"events/primavera/bg_v3.jpg","logo":"events/primavera/img/logo-black.png",
  "cost":{"EN":"Free Entrance","AM":"ՄՈՒՏՔ ԱՆՎՃԱՐ","RU":"Вход свободный"},
  "short":{"title":"","details":{"EN":"...","AM":"...","RU":"..."}},
  "full":{"title":{"EN":"..."},"details":{"EN":"..."}},
  "detailed":"event",
  "buttons": {"struct":{"row1":["home","event"],"row2":["donate","share"]}}
}
JSON;

$template_project = <<<JSON
{
 "type":"project",
 "title":{"EN":"Dedicate a release by Armenian artist...","AM":"...","RU":"..."},
 "tglike":"https://t.me/primavera_am/100",
 "date":{"EN":"Annual Program","AM":"Ամենամյա ծրագիր","RU":"Ежегодная программа"},
 "bg":"events/primavera/bg_v3.jpg","logo":"events/primavera/img/logo-black.png",
 "short":{"title":{"EN":"RECORDINGS...","AM":"...","RU":"..."},"details":{"EN":"...","AM":"...","RU":"..."}},
 "full":{"title":{"EN":"..."},"details":{"EN":"..."}},
 "detailed":"event",
 "buttons":{"struct":{"row1":["home","event"],"row2":["donate","share"]}}
}
JSON;

$templates = [
    'main' => json_decode($template_main, true),
    'home' => json_decode($template_home, true),
    'event' => json_decode($template_event, true),
    'project' => json_decode($template_project, true),
];

/* ----------------------------- helpers ----------------------------- */
function isAssocArray(array $a): bool {
    if ($a === []) return false;
    return array_keys($a) !== range(0, count($a)-1);
}
function deepMergeTemplate(array $tpl, array $data): array {
    foreach ($data as $k => $v) {
        if (array_key_exists($k, $tpl) && is_array($tpl[$k]) && is_array($v)) $tpl[$k] = deepMergeTemplate($tpl[$k], $v);
        else $tpl[$k] = $v;
    }
    return $tpl;
}
function isIdList(array $arr): bool {
    if (!$arr || !isset($arr[0]) || !is_array($arr[0])) return false;
    $hasId = 0; $check = min(count($arr),5);
    for ($i=0;$i<$check;$i++) if (is_array($arr[$i]) && array_key_exists('id',$arr[$i])) $hasId++;
    return $hasId>0;
}
function nextIdLike(array $arr): string {
    $max = 0; $len = 3;
    foreach ($arr as $item) {
        if (!is_array($item) || !isset($item['id'])) continue;
        $id = (string)$item['id']; $len = max($len, strlen($id));
        if (preg_match('/(\d+)/',$id,$m)) { $num = intval($m[1]); if ($num>$max) $max=$num; $len = max($len, strlen($m[1])); }
    }
    return str_pad((string)($max+1), $len, '0', STR_PAD_LEFT);
}

/* Robust save: write tmp + rename, capture errors */
function saveJson(string $path, array $data, array &$messages): bool {
    $dir = dirname($path);
    if (!is_dir($dir)) { $messages[] = "<span style='color:red'>Directory does not exist: ".h($dir)."</span>"; return false; }
    if (!is_writable($dir) && !(file_exists($path) && is_writable($path))) { $messages[] = "<span style='color:red'>Directory not writable: ".h($dir)."</span>"; return false; }

    $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    if ($json === false) { $messages[] = "<span style='color:red'>JSON encode failed: ".h(json_last_error_msg())."</span>"; return false; }

    $tmp = tempnam($dir, 'jsontmp_');
    if ($tmp === false) { $messages[] = "<span style='color:red'>Failed to create temp file in: ".h($dir)."</span>"; return false; }

    $lastErr = null;
    set_error_handler(function($errno,$errstr) use (&$lastErr){ $lastErr = $errstr; return true; });

    $written = @file_put_contents($tmp, $json, LOCK_EX);

    restore_error_handler();

    if ($written === false) { @unlink($tmp); $messages[] = "<span style='color:red'>Failed to write temp file: ".h($tmp)." (".h($lastErr?:'unknown').")</span>"; return false; }

    @chmod($tmp, 0666);

    if (!@rename($tmp, $path)) {
        if (!@copy($tmp, $path)) { $err = error_get_last(); @unlink($tmp); $messages[] = "<span style='color:red'>Failed to move temp to target: ".h($path)." (".h($err['message']??'unknown').")</span>"; return false; }
        @unlink($tmp);
    }

    @chmod($path, 0666);
    clearstatcache(true,$path);
    $messages[] = "<span style='color:green'>Saved: ".h($path)." (".(int)@filesize($path)." bytes)</span>";
    return true;
}

/* --------------------------- Load selected file --------------------------- */
$selectedFile = isset($_GET['file']) ? basename($_GET['file']) : '';
$currentData = [];
$loadedType = null;

if ($selectedFile && is_file($dir.'/'.$selectedFile)) {
    $raw = file_get_contents($dir.'/'.$selectedFile);
    $decoded = json_decode($raw, true);
    if (is_array($decoded)) {
        $currentData = $decoded;
        $loadedType = $decoded['type'] ?? null;
        if ($loadedType && isset($templates[$loadedType])) $currentData = deepMergeTemplate($templates[$loadedType], $decoded);
    } else {
        $messages[] = "<span style='color:red'>Failed to parse JSON: ".h($selectedFile)."</span>";
    }
}

/* --------------------------- POST actions --------------------------- */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!empty($_POST['file'])) $selectedFile = basename($_POST['file']);
    $action = $_POST['action'] ?? '';

    if ($action === 'save') {
        $filename = trim((string)($_POST['filename'] ?? ''));
        if ($filename === '') { $messages[] = "<span style='color:red'>Filename required</span>"; }
        else {
            $filepath = $dir.'/'.preg_replace('/[\/\\\\]+/','',$filename).'.json';
            $data = $_POST;
            unset($data['action'],$data['filename'],$data['file']);
            $boolify = function(&$v) use (&$boolify) { if (is_array($v)){ foreach ($v as &$x) $boolify($x);} else { if ($v === '1') $v = true; if($v === '0') $v = false; } };
            $boolify($data);
            if (saveJson($filepath, $data, $messages)) { $selectedFile = basename($filepath); $currentData = $data; $files = array_values(array_filter(scandir($dir), fn($f)=>is_file($dir.'/'.$f)&&preg_match('/\.json$/i',$f))); }
        }
    }

    if ($action === 'create_from_template') {
        $tplName = $_POST['tpl'] ?? '';
        $filename = trim((string)($_POST['new_filename'] ?? ''));
        if (!$tplName || !isset($templates[$tplName])) $messages[] = "<span style='color:red'>Template not selected</span>";
        elseif ($filename === '') $messages[] = "<span style='color:red'>Filename required</span>";
        else {
            $filepath = $dir.'/'.preg_replace('/[\/\\\\]+/','',$filename).'.json';
            $data = $templates[$tplName];
            if (saveJson($filepath, $data, $messages)) { $selectedFile = basename($filepath); $currentData = $data; $files = array_values(array_filter(scandir($dir), fn($f)=>is_file($dir.'/'.$f)&&preg_match('/\.json$/i',$f))); }
        }
    }

    if ($action === 'add_item' && $selectedFile) {
        $path = trim((string)($_POST['path'] ?? ''));
        if ($path !== '' && $currentData) {
            $parts = explode('.',$path);
            $ref =& $currentData;
            foreach ($parts as $p) { if (!isset($ref[$p]) || !is_array($ref[$p])) $ref[$p] = []; $ref =& $ref[$p]; }
            if (is_array($ref)) {
                if (isIdList($ref)) {
                    $newId = trim((string)($_POST['new_id'] ?? '')) ?: nextIdLike($ref);
                    $keys = isset($ref[0]) && is_array($ref[0]) ? array_keys($ref[0]) : ['id','name','date'];
                    $new = []; foreach ($keys as $k) $new[$k] = ($k==='id')?$newId:"";
                    $ref[] = $new;
                } else $ref[] = "";
                $filepath = $dir.'/'.$selectedFile;
                saveJson($filepath, $currentData, $messages);
            }
        }
    }

    if ($action === 'delete_item' && $selectedFile) {
        $path = trim((string)($_POST['path'] ?? ''));
        $id = $_POST['del_id'] ?? '';
        $idx = $_POST['del_idx'] ?? '';
        if ($path !== '' && $currentData) {
            $parts = explode('.',$path);
            $ref =& $currentData;
            foreach ($parts as $p) { if (!isset($ref[$p]) || !is_array($ref[$p])) { $ref = null; break; } $ref =& $ref[$p]; }
            if (is_array($ref)) {
                if ($id !== '') {
                    foreach ($ref as $i => $item) { if (is_array($item) && isset($item['id']) && (string)$item['id'] === (string)$id) { array_splice($ref,$i,1); break; } }
                } elseif ($idx !== '' && ctype_digit((string)$idx)) { $i = (int)$idx; if (isset($ref[$i])) array_splice($ref,$i,1); }
                $filepath = $dir.'/'.$selectedFile;
                saveJson($filepath, $currentData, $messages);
            }
        }
    }

    if ($action === 'delete_file') {
        $target = basename($_POST['file'] ?? $selectedFile);
        if ($target) {
            $full = $dir.'/'.$target;
            if (is_file($full)) {
                if (@unlink($full)) { $messages[] = "<span style='color:red'>Deleted: ".h($full)."</span>"; if ($selectedFile === $target){ $selectedFile=''; $currentData=[]; } $files = array_values(array_filter(scandir($dir), fn($f)=>is_file($dir.'/'.$f)&&preg_match('/\.json$/i',$f))); }
                else $messages[] = "<span style='color:red'>Failed to delete: ".h($full)."</span>";
            } else $messages[] = "<span style='color:red'>File not found: ".h($full)."</span>";
        } else $messages[] = "<span style='color:red'>No file specified for deletion</span>";
    }
}

/* ------------------------------ Render funcs ------------------------------ */
function renderField($key, $value, $namePath) {
    $label = h($key);
    if (is_array($value)) {
        $assoc = isAssocArray($value);
        echo "<fieldset class='box'><legend>{$label}</legend>";
        if (!$assoc) {
            $isIdList = isIdList($value);
            $path = implode('.', $namePath);
            // deterministic id for input
            $nid = 'nid_'.substr(md5($path),0,8);
            echo "<div class='list-actions'>";
            if ($isIdList) {
                echo "<input class='input small' id='".h($nid)."' placeholder='ID (auto if empty)'>";
                echo "<button type='button' class='btn add' data-action='add_item' data-path='".h($path)."' data-file='".h($_GET['file'] ?? '')."' data-newidinput='".h($nid)."'>+ Add by ID</button>";
            } else {
                echo "<button type='button' class='btn add' data-action='add_item' data-path='".h($path)."' data-file='".h($_GET['file'] ?? '')."'>+ Add item</button>";
            }
            echo "</div>";
            foreach ($value as $idx => $item) {
                echo "<div class='list-item'>";
                if ($isIdList && is_array($item) && isset($item['id'])) {
                    $idStr = (string)$item['id'];
                    echo "<button type='button' class='btn danger' data-action='delete_item' data-path='".h($path)."' data-file='".h($_GET['file'] ?? '')."' data-delid='".h($idStr)."' data-confirm='Delete item with id ".h($idStr)."?'>Delete #".h($idStr)."</button>";
                } else {
                    echo "<button type='button' class='btn danger' data-action='delete_item' data-path='".h($path)."' data-file='".h($_GET['file'] ?? '')."' data-delidx='".((int)$idx)."' data-confirm='Delete item #".h($idx)."?'>Delete #".h($idx)."</button>";
                }
                renderAny($item, array_merge($namePath, [$idx]));
                echo "</div>";
            }
        } else {
            foreach ($value as $k => $v) renderField((string)$k, $v, array_merge($namePath, [$k]));
        }
        echo "</fieldset>"; return;
    }

    echo "<label class='lbl'>{$label}</label>";
    if (is_bool($value)) {
        $name = make_input_name($namePath);
        $nameAttr = h($name);
        $checked = $value ? 'checked' : '';
        echo "<input type='hidden' name='{$nameAttr}' value='0'>";
        echo "<input type='checkbox' class='chk' name='{$nameAttr}' value='1' {$checked}>";
    } else {
        $name = make_input_name($namePath);
        $val = (string)$value; $rows = (strlen($val)>120 || strpos($val,"\n")!==false || strpos($val,'<')!==false) ? 8 : 3;
        $nameAttr = h($name);
        echo "<textarea name='{$nameAttr}' rows='{$rows}' class='ta'>".h($val)."</textarea>";
    }
}

function renderAny($value, $namePath) {
    if (is_array($value)) {
        $assoc = isAssocArray($value);
        $legend = h((string)end($namePath));
        echo "<fieldset class='box nested'><legend>{$legend}</legend>";
        if ($assoc) {
            foreach ($value as $k => $v) renderField((string)$k, $v, array_merge($namePath, [$k]));
        } else {
            $path = implode('.', $namePath);
            $isIdList = isIdList($value);
            $nid = 'nid_'.substr(md5($path),0,8);
            echo "<div class='list-actions'>";
            if ($isIdList) {
                echo "<input class='input small' id='".h($nid)."' placeholder='ID (auto if empty)'>";
                echo "<button type='button' class='btn add' data-action='add_item' data-path='".h($path)."' data-newidinput='".h($nid)."'>+ Add by ID</button>";
            } else {
                echo "<button type='button' class='btn add' data-action='add_item' data-path='".h($path)."'>+ Add item</button>";
            }
            echo "</div>";
            foreach ($value as $idx => $item) {
                echo "<div class='list-item'>";
                if ($isIdList && is_array($item) && isset($item['id'])) {
                    echo "<button type='button' class='btn danger' data-action='delete_item' data-path='".h($path)."' data-delid='".h((string)$item['id'])."' data-confirm='Delete item with id ".h((string)$item['id'])."?'>Delete #".h((string)$item['id'])."</button>";
                } else {
                    echo "<button type='button' class='btn danger' data-action='delete_item' data-path='".h($path)."' data-delidx='".((int)$idx)."' data-confirm='Delete item #".h($idx)."?'>Delete #".h($idx)."</button>";
                }
                renderAny($item, array_merge($namePath, [$idx]));
                echo "</div>";
            }
        }
        echo "</fieldset>";
    } else {
        $label = h((string)end($namePath));
        $name = make_input_name($namePath);
        $val = (string)$value; $rows = (strlen($val)>120 || strpos($val,"\n")!==false || strpos($val,'<')!==false) ? 8 : 3;
        echo "<label class='lbl'>{$label}</label>";
        echo "<textarea name='".h($name)."' rows='{$rows}' class='ta'>".h($val)."</textarea>";
    }
}

/* ------------------------------ HTML/UI ------------------------------- */
?>
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>JSON Editor — fixed</title>
<style>
body { font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial; margin:16px; }
.wrap { display:grid; grid-template-columns:280px 1fr; gap:16px; }
.sidebar, .main { border:1px solid #ddd; border-radius:10px; padding:12px; }
.box { border:1px solid #ccc; padding:10px; border-radius:8px; margin:10px 0; }
.box.nested { border-style:dashed; }
.lbl { display:block; font-weight:600; margin:8px 0 4px; }
.ta { width:100%; box-sizing:border-box; padding:8px; font-family: monospace; }
.btn { padding:6px 10px; border-radius:8px; border:1px solid #ccc; background:#f8f8f8; cursor:pointer; }
.btn.save { background:#e8f5e9; border-color:#a5d6a7; }
.btn.add { background:#e3f2fd; border-color:#90caf9; }
.btn.danger { background:#ffebee; border-color:#ef9a9a; }
.input { padding:6px 8px; width:100%; box-sizing:border-box; }
.input.small { width:160px; }
.list-item { border:1px solid #eee; padding:8px; margin:8px 0; border-radius:8px; }
.list-actions { margin:8px 0; }
.msgs p{margin:6px 0;}
.badge { font-size:12px; background:#eef; border-radius:6px; padding:2px 6px; border:1px solid #99c; text-decoration:none;}
</style>


<style>
    body {
        font-family: Arial, sans-serif;
        background: #f1f1f1;
        margin: 0;
        padding: 20px;
    }
    h3 {
        margin-top: 30px;
        color: #111;
    }
    ul {
        padding-left: 20px;
    }
    a {
        text-decoration: none;
        color: #007bff;
        font-weight: bold;
    }
    a:hover {
        text-decoration: underline;
    }
    form {
        background: #fff;
        padding: 20px;
        border-radius: 12px;
        border: 2px solid #ccc;
        box-shadow: 0 4px 10px rgba(0,0,0,0.1);
    }
    fieldset {
        margin: 20px 0;
        padding: 15px;
        border-radius: 10px;
        border: 2px solid #666;
        background: #fafafa;
    }
    fieldset legend {
        font-weight: bold;
        padding: 0 10px;
        color: #333;
    }
    label {
        font-weight: 600;
        display: block;
        margin-top: 10px;
    }
    textarea, input[type="text"], input[type="password"] {
        width: 100%;
        padding: 8px 12px;
        margin-top: 5px;
        border-radius: 6px;
        border: 2px solid #888;
        font-family: monospace;
        background: #fff;
        resize: vertical;
    }
    textarea {
        min-height: 70px;
    }
   .btn {
    display: inline-block;
    padding: 8px 14px;   /* одинаковый размер */
    margin: 4px 2px;
    border-radius: 6px;
    border: none;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    transition: background 0.2s ease, transform 0.1s ease;
    min-width: 80px;     /* все кнопки одинаковой ширины */
    text-align: center;
}

/* одинаковое поведение при наведении */
.btn:hover {
    transform: scale(1.05);
}

/* варианты кнопок */
.btn.save {
    background: #28a745;
    color: #fff;
}
.btn.save:hover {
    background: #218838;
}

.btn.add {
    background: #007bff;
    color: #fff;
}
.btn.add:hover {
    background: #0069d9;
}

.btn.delete {
    background: #dc3545;
    color: #fff;
}
.btn.delete:hover {
    background: #c82333;
}

.btn.open {
    background: #6c757d;
    color: #fff;
}
.btn.open:hover {
    background: #5a6268;
}



.badge, .btn-badge {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.2s ease, transform 0.1s ease;
}

/* open */
.badge {
    background: #6c757d;
    color: #fff;
}
.badge:hover {
    background: #5a6268;
}

/* delete */
.btn-badge {
    background: #dc3545;
    color: #fff;
    border: none;
}
.btn-badge:hover {
    background: #c82333;
}







    /* 🎨 Яркие блоки */
    .block {
        border: 3px solid #007bff;
        padding: 20px;
        margin-bottom: 20px;
        border-radius: 12px;
        background: #e9f3ff;
        position: relative;
    }
    .block > legend {
        color: #007bff;
        font-size: 16px;
    }
    .block .btn.delete {
        position: absolute;
        top: 12px;
        right: 12px;
    }

    /* 📦 Специальное выделение для box */
    .box {
        border: 3px dashed #ff9800;
        background: #fff3e0;
        padding: 15px;
        margin: 15px 0;
        border-radius: 10px;
    }
    .box legend {
        color: #e65100;
    }
</style>





</head>
<body>

<div class="wrap">
  <div class="sidebar">
    <h3>Existing files</h3>
    <ul style="list-style:none;padding-left:0;margin:0">
      <?php foreach ($files as $f): ?>
        <li style="display:flex;justify-content:space-between;align-items:center;padding:6px 0;border-bottom:1px dashed #eee">
          <a href="?file=<?=urlencode($f)?>"><?=h($f)?></a>
          <div>
            <a class="badge" href="?file=<?=urlencode($f)?>">open</a>

	<a class="badge delete" href="#"
               onclick="if(confirm('Delete <?=htmlspecialchars($f)?>?')){ 
                   const f=document.createElement('form'); 
                   f.method='post'; 
                   f.style.display='none'; 
                   f.innerHTML='<input type=hidden name=action value=delete_file><input type=hidden name=file value=<?=htmlspecialchars($f)?>>'; 
                   document.body.appendChild(f); 
                   f.submit(); 
               } return false;">Delete</a>
          </div>
        </li>
      <?php endforeach; ?>
    </ul>

    <h3 style="margin-top:12px">Create new</h3>
    <form method="post">
      <input type="hidden" name="action" value="create_from_template">
      <label class="lbl">Filename (without .json)</label>
      <input class="input" name="new_filename" required placeholder="e.g. 001000">
      <label class="lbl">Template</label>
      <select class="input" name="tpl" required>
        <option value="">— select —</option>
        <option value="main">main</option>
        <option value="home">home</option>
        <option value="event">event</option>
        <option value="project">project</option>
      </select>
      <div style="margin-top:8px"><button class="btn add" type="submit">Create</button></div>
    </form>
  </div>

  <div class="main">
    <h2><?= $selectedFile ? "Edit: ".h($selectedFile) : "No file selected" ?></h2>

    <div class="msgs">
      <?php foreach ($messages as $m) echo "<p>$m</p>"; ?>
    </div>

    <?php if ($selectedFile && $currentData): ?>
      <form method="post">
        <input type="hidden" name="action" value="save">
        <input type="hidden" name="file" value="<?=h($selectedFile)?>">
        <label class="lbl">File name (without .json)</label>
        <input class="input" name="filename" required value="<?=h((string)pathinfo($selectedFile, PATHINFO_FILENAME))?>">
        <?php
            foreach ($currentData as $k => $v) {
                renderField((string)$k, $v, [$k]);
            }
        ?>
        <div style="margin-top:12px">
          <button class="btn save" type="submit">Save JSON</button>
        </div>
      </form>
    <?php else: ?>
      <p>Select a file on the left or create new from template.</p>
    <?php endif; ?>
  </div>
</div>

<script>
// Delegated handler: buttons with data-action will create a small POST form and submit it.
// This avoids nested forms and ensures outer edit form isn't interfered with.
document.addEventListener('click', function(e) {
    var btn = e.target.closest('button[data-action]');
    if (!btn) return;
    e.preventDefault();

    var action = btn.dataset.action;
    var path = btn.dataset.path || '';
    var file = btn.dataset.file || (new URLSearchParams(location.search)).get('file') || '';
    var newidinput = btn.dataset.newidinput || '';
    var delid = btn.dataset.delid || '';
    var delidx = btn.dataset.delidx || '';
    var confirmMsg = btn.dataset.confirm || '';

    if (confirmMsg && !confirm(confirmMsg)) return;

    var form = document.createElement('form');
    form.method = 'post';
    form.style.display = 'none';

    var add = function(name, value){
        var i = document.createElement('input');
        i.type = 'hidden';
        i.name = name;
        i.value = value;
        form.appendChild(i);
    };

    add('action', action);
    if (path) add('path', path);
    if (file) add('file', file);
    if (newidinput) {
        var el = document.getElementById(newidinput);
        add('new_id', el ? el.value : '');
    }
    if (delid) add('del_id', delid);
    if (delidx) add('del_idx', delidx);

    document.body.appendChild(form);
    form.submit();
});
</script>
</body>
</html>
