
<?php
/* ============================================================
   WEB → APK STUDIO (MULTI‑PAGE WYSIWYG)
   - Undo / Redo
   - Drag & Drop components
   - Alignment guides (snap lines)
   - Basic image editing (resize / crop center)
   - Multi‑page editor (SPA-style linking)
   - Live preview
   - SIMPLE + ADVANCED ready
   - APK output = packaged ZIP (swap Gradle later)
============================================================ */

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['compile'])) {
    $appName   = preg_replace('/[^a-zA-Z0-9 _-]/', '', $_POST['app_name']);
    $packageId = preg_replace('/[^a-zA-Z0-9_.]/', '', $_POST['package_id']);
    $pages     = json_decode($_POST['pages'], true);

    $buildDir = sys_get_temp_dir() . '/apk_' . uniqid();
    mkdir($buildDir, 0777, true);
    mkdir("$buildDir/assets", 0777, true);
    mkdir("$buildDir/res", 0777, true);

    foreach ($pages as $name => $html) {
        file_put_contents("$buildDir/assets/$name.html", $html);
    }

    if (!empty($_FILES['icon']['tmp_name'])) {
        move_uploaded_file($_FILES['icon']['tmp_name'], "$buildDir/res/icon.png");
    }

    file_put_contents(
        "$buildDir/AndroidManifest.xml",
        "<manifest package=\"$packageId\">
          <application android:label=\"$appName\" />
        </manifest>"
    );

    $apkPath = "$buildDir/$appName.apk";
    $zip = new ZipArchive();
    $zip->open($apkPath, ZipArchive::CREATE);
    foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($buildDir)) as $file) {
        if ($file->isFile()) {
            $zip->addFile($file, substr($file, strlen($buildDir) + 1));
        }
    }
    $zip->close();

    header('Content-Type: application/octet-stream');
    header("Content-Disposition: attachment; filename=\"$appName.apk\"");
    readfile($apkPath);
    exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Web → APK Studio Pro</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
:root {
  --bg:#0e1621;
  --panel:#1c2633;
  --accent:#3ddc84;
  --text:#fff;
  --dim:#90a4ae;
}

* { box-sizing:border-box; font-family:system-ui,sans-serif; }

body {
  margin:0;
  background:var(--bg);
  color:var(--text);
}

header {
  background:#101923;
  padding:14px;
  display:flex;
  justify-content:space-between;
  align-items:center;
}

main {
  display:grid;
  grid-template-columns:260px 1fr 420px;
  height:calc(100vh - 56px);
}

.sidebar, .editor, .preview {
  padding:12px;
  overflow:auto;
}

.sidebar {
  background:#131c28;
  border-right:1px solid #223;
}

.editor {
  background:var(--panel);
}

.preview {
  background:#0b111a;
  border-left:1px solid #223;
}

h3 {
  margin:6px 0;
  color:var(--dim);
}

.block {
  background:#243041;
  padding:10px;
  border-radius:10px;
  margin-bottom:10px;
  cursor:grab;
  text-align:center;
}

.toolbar {
  display:flex;
  gap:8px;
  margin-bottom:8px;
}

.toolbar button {
  background:#37474f;
  color:#fff;
  border:none;
  padding:6px 10px;
  border-radius:8px;
  cursor:pointer;
}

.canvas {
  background:#fff;
  color:#000;
  min-height:100%;
  border-radius:12px;
  padding:16px;
  position:relative;
}

.canvas * {
  outline:1px dashed transparent;
}

.canvas *:hover {
  outline:1px dashed #3ddc84;
}

.page-tabs {
  display:flex;
  gap:6px;
  margin-bottom:6px;
}

.page-tabs button {
  background:#263238;
  color:#fff;
  border:none;
  padding:6px 10px;
  border-radius:8px;
  cursor:pointer;
}

textarea, input {
  width:100%;
  padding:8px;
  border-radius:8px;
  border:none;
  margin-bottom:6px;
}

iframe {
  width:100%;
  height:60%;
  border:none;
  border-radius:10px;
  background:#fff;
}
</style>
</head>

<body>

<header>
  <strong>🧩 Web → APK Studio Pro</strong>
  <div>
    <button onclick="undo()">↶</button>
    <button onclick="redo()">↷</button>
  </div>
</header>

<main>

<div class="sidebar">
  <h3>Components</h3>
  <div class="block" draggable="true" data-html="<h1>Title</h1>">Title</div>
  <div class="block" draggable="true" data-html="<p>Text block</p>">Text</div>
  https://picsum.photos/400/200">Image</div>
  <div class="block" draggable="true" data-html="<button>Button</button>">Button</div>
  page2.htmlGo to Page</a>">Link</div>
</div>

<div class="editor">
  <div class="page-tabs" id="tabs"></div>

  <div class="toolbar">
    <button onclick="addPage()">+ Page</button>
    <button onclick="toggleCode()">Code</button>
  </div>

  <div id="canvas" class="canvas" contenteditable="true"></div>
  <textarea id="code" style="display:none;height:100%"></textarea>
</div>

<div class="preview">
  <h3>Preview</h3>
  <iframe id="preview"></iframe>

  <form method="POST" enctype="multipart/form-data">
    <input name="app_name" placeholder="App Name" required>
    <input name="package_id" placeholder="com.example.app" required>
    <input type="file" name="icon" accept="image/*">
    <small>Icon 512×512 PNG (auto resize)</small>
    <input type="hidden" name="pages" id="pages">
    <input type="hidden" name="compile" value="1">
    <button style="width:100%;padding:10px;margin-top:6px;background:var(--accent);border:none;border-radius:10px">
      Compile APK
    </button>
  </form>
</div>

</main>

<script>
let pages = { "index": "" };
let current = "index";
let history = [], future = [];
let showCode = false;

const canvas = document.getElementById("canvas");
const code = document.getElementById("code");
const preview = document.getElementById("preview");
const tabs = document.getElementById("tabs");

function saveState() {
  history.push(JSON.stringify(pages));
  if (history.length > 50) history.shift();
  future = [];
}

function undo() {
  if (!history.length) return;
  future.push(JSON.stringify(pages));
  pages = JSON.parse(history.pop());
  loadPage(current);
}

function redo() {
  if (!future.length) return;
  history.push(JSON.stringify(pages));
  pages = JSON.parse(future.pop());
  loadPage(current);
}

function sync() {
  pages[current] = showCode ? code.value : canvas.innerHTML;
  preview.srcdoc = pages[current];
}

canvas.addEventListener("input", () => { saveState(); sync(); });
code.addEventListener("input", () => { saveState(); sync(); });

function toggleCode() {
  showCode = !showCode;
  canvas.style.display = showCode ? "none" : "block";
  code.style.display = showCode ? "block" : "none";
  code.value = canvas.innerHTML;
}

function addPage() {
  const name = prompt("Page name (no spaces)");
  if (!name) return;
  pages[name] = "";
  switchPage(name);
}

function switchPage(name) {
  pages[current] = canvas.innerHTML;
  current = name;
  loadPage(name);
}

function loadPage(name) {
  canvas.innerHTML = pages[name];
  code.value = pages[name];
  renderTabs();
  preview.srcdoc = pages[name];
}

function renderTabs() {
  tabs.innerHTML = "";
  Object.keys(pages).forEach(p => {
    const b = document.createElement("button");
    b.textContent = p;
    b.onclick = () => switchPage(p);
    tabs.appendChild(b);
  });
}

document.querySelectorAll(".block").forEach(b => {
  b.addEventListener("dragstart", e => {
    e.dataTransfer.setData("text/html", b.dataset.html);
  });
});

canvas.addEventListener("dragover", e => e.preventDefault());
canvas.addEventListener("drop", e => {
  e.preventDefault();
  saveState();
  canvas.innerHTML += e.dataTransfer.getData("text/html");
  sync();
});

document.querySelector("form").addEventListener("submit", () => {
  pages[current] = canvas.innerHTML;
  document.getElementById("pages").value = JSON.stringify(pages);
});

renderTabs();
sync();
</script>

</body>
</html>