"""
Nexa Language — WASM Mobile PWA Bridge (Phase 6 / v26)

Generates a complete Progressive Web App scaffold that runs Nexa code
in the browser via WebAssembly (Pyodide-backed initially, native WASM target later).

Usage:
    nexa new my-app --template pwa
    → generates nexa_pwa/ with index.html, service worker, manifest.json

Architecture:
    Browser → nexa.wasm (future) or Pyodide (now)
              ↓
           JS bridge ← nexa_pwa.js
              ↓
           Nexa runtime → runs .nexa code
"""
from __future__ import annotations
import os, json, shutil
from pathlib import Path

# ── PWA Template Files ────────────────────────────────────────────────────────

_HTML = """\
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="theme-color" content="#6c63ff">
  <title>{APP_NAME}</title>
  <link rel="manifest" href="manifest.json">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="app">
    <h1>{APP_NAME}</h1>
    <p id="status">Loading Nexa runtime…</p>
    <pre id="output"></pre>
    <textarea id="editor" placeholder="Write Nexa code here…" rows="10"></textarea>
    <button id="run-btn" disabled>▶ Run</button>
  </div>

  <!-- Pyodide WASM runtime (Nexa native WASM ships in v27) -->
  <script src="https://cdn.jsdelivr.net/pyodide/v0.25.0/full/pyodide.js"></script>
  <script src="nexa_pwa.js"></script>
  <script>
    document.addEventListener('DOMContentLoaded', () => {{
      NexaPWA.init('{APP_NAME}');
    }});
  </script>
  <link rel="apple-touch-icon" href="icon.png">
</body>
</html>
"""

_JS = """\
/* nexa_pwa.js — Nexa WASM PWA Bridge v26 */
const NexaPWA = (() => {
  let pyodide = null;
  let nexaRuntime = null;

  async function init(appName) {
    document.getElementById('status').textContent = 'Loading Pyodide…';
    try {
      pyodide = await loadPyodide();
      document.getElementById('status').textContent = 'Installing Nexa runtime…';

      // Install nexa_lang from PyPI (or local wheel)
      await pyodide.runPythonAsync(`
import micropip
try:
    await micropip.install('nexa-lang')
except Exception as e:
    pass  # dev mode — assume pre-loaded
`);

      nexaRuntime = await _loadNexaRuntime();
      document.getElementById('status').textContent = '✅ Nexa ' + appName + ' ready';
      document.getElementById('run-btn').disabled = false;
      document.getElementById('run-btn').addEventListener('click', runCode);
    } catch (err) {
      document.getElementById('status').textContent = '❌ Failed: ' + err.message;
      console.error(err);
    }
  }

  async function _loadNexaRuntime() {
    const code = `
import sys, io
from nexa_lang.lexer import Lexer
from nexa_lang.parser import Parser
from nexa_lang.interpreter import Interpreter

def nexa_eval(src):
    buf = io.StringIO()
    old = sys.stdout
    sys.stdout = buf
    try:
        tokens = Lexer(src).tokenize()
        ast = Parser(tokens).parse()
        interp = Interpreter()
        interp.run(ast)
    except Exception as e:
        return f'Error: {e}'
    finally:
        sys.stdout = old
    return buf.getvalue()
`;
    await pyodide.runPythonAsync(code);
    return pyodide.globals.get('nexa_eval');
  }

  async function runCode() {
    const src = document.getElementById('editor').value;
    document.getElementById('output').textContent = '⏳ Running…';
    try {
      const result = await pyodide.runPythonAsync(`nexa_eval(${JSON.stringify(src)})`);
      document.getElementById('output').textContent = result || '(no output)';
    } catch (err) {
      document.getElementById('output').textContent = '❌ ' + err.message;
    }
  }

  // Service Worker registration
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('sw.js')
        .then(reg => console.log('SW registered:', reg.scope))
        .catch(err => console.log('SW failed:', err));
    });
  }

  return { init, runCode };
})();
"""

_CSS = """\
/* Nexa PWA — Default Style */
:root {
  --primary: #6c63ff;
  --bg: #0e0e1a;
  --surface: #1a1a2e;
  --text: #e0e0f8;
  --accent: #ff6584;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, sans-serif;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

#app {
  width: min(600px, 95vw);
  padding: 2rem;
  background: var(--surface);
  border-radius: 1rem;
  box-shadow: 0 8px 32px rgba(108, 99, 255, 0.25);
}

h1 { color: var(--primary); margin-bottom: 1rem; font-size: 1.8rem; }

#status {
  font-size: 0.9rem;
  color: #aaa;
  margin-bottom: 1rem;
  min-height: 1.2em;
}

#editor {
  width: 100%;
  background: #0e0e1a;
  color: var(--text);
  border: 1px solid #333;
  border-radius: 0.5rem;
  padding: 0.75rem;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.95rem;
  resize: vertical;
  margin-bottom: 0.75rem;
}

#run-btn {
  background: var(--primary);
  color: white;
  border: none;
  border-radius: 0.5rem;
  padding: 0.6rem 1.5rem;
  font-size: 1rem;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.1s;
}
#run-btn:hover:not(:disabled) { opacity: 0.9; transform: translateY(-1px); }
#run-btn:disabled { opacity: 0.4; cursor: not-allowed; }

#output {
  margin-top: 1rem;
  background: #0e0e1a;
  border-radius: 0.5rem;
  padding: 0.75rem;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.9rem;
  min-height: 3rem;
  white-space: pre-wrap;
  color: #a8ff78;
}
"""

_SW = """\
/* sw.js — Nexa PWA Service Worker (offline support) */
const CACHE = 'nexa-pwa-v26';
const PRECACHE = ['./', './index.html', './style.css', './nexa_pwa.js', './manifest.json'];

self.addEventListener('install', e =>
  e.waitUntil(caches.open(CACHE).then(c => c.addAll(PRECACHE)))
);

self.addEventListener('fetch', e =>
  e.respondWith(
    caches.match(e.request).then(cached => cached || fetch(e.request))
  )
);
"""

_MANIFEST = {
    "name": "{APP_NAME}",
    "short_name": "{APP_NAME}",
    "start_url": "./",
    "display": "standalone",
    "background_color": "#0e0e1a",
    "theme_color": "#6c63ff",
    "icons": [
        {"src": "icon.png", "sizes": "192x192", "type": "image/png"},
        {"src": "icon.png", "sizes": "512x512", "type": "image/png"},
    ],
}

_MAIN_NEXA = """\
// {APP_NAME} — Nexa PWA entry point
// This file is executed in the browser via Pyodide/Nexa WASM runtime

let message = "Hello from {APP_NAME} running on Nexa v26!"
print(message)

let numbers = [1, 2, 3, 4, 5]
let doubled = [n * 2 for n in numbers]
print(f"Doubled: {{doubled}}")

// Result-based error handling
import "result"
let r = result.ok(42)
if result.is_ok(r) {
    print(f"Result value: {{result.unwrap(r)}}")
}
"""


def create_pwa_scaffold(output_dir: str, app_name: str = "MyNexa App") -> str:
    """
    Scaffold a complete Nexa PWA project.

    Args:
        output_dir: destination folder
        app_name:   display name of the app

    Returns:
        Path to the created directory.
    """
    path = Path(output_dir)
    path.mkdir(parents=True, exist_ok=True)

    def _write(fname: str, content: str):
        (path / fname).write_text(content.replace("{APP_NAME}", app_name), encoding="utf-8")

    _write("index.html", _HTML)
    _write("nexa_pwa.js", _JS)
    _write("style.css", _CSS)
    _write("sw.js", _SW)
    _write("main.nexa", _MAIN_NEXA)

    manifest = json.loads(json.dumps(_MANIFEST))
    for k in manifest:
        if isinstance(manifest[k], str):
            manifest[k] = manifest[k].replace("{APP_NAME}", app_name)
    (path / "manifest.json").write_text(json.dumps(manifest, indent=2), encoding="utf-8")

    # nexa.json project manifest
    nexa_json = {
        "name": app_name.lower().replace(" ", "-"),
        "version": "0.1.0",
        "type": "pwa",
        "description": f"A Nexa PWA — {app_name}",
        "entry": "main.nexa",
        "runtime": "wasm",
        "nexa_version": ">=26.0",
    }
    (path / "nexa.json").write_text(json.dumps(nexa_json, indent=2), encoding="utf-8")

    # README
    readme = f"""# {app_name}

A Nexa PWA (Progressive Web App) powered by Nexa v26.

## Run locally

```bash
cd {os.path.basename(output_dir)}
python -m http.server 3000
# → open http://localhost:3000
```

## Deploy

Simply upload the folder to any static host (Netlify, Vercel, GitHub Pages).

## How it works

- Nexa code in `main.nexa` runs in-browser via Pyodide (WASM Python)
- Native Nexa WASM target ships in v27 for ~10× faster execution
- Service worker (`sw.js`) enables offline usage
"""
    (path / "README.md").write_text(readme, encoding="utf-8")

    print(f"""
  📱 Nexa PWA scaffold created: {path}

  📁 Structure:
     {os.path.basename(output_dir)}/
     ├── index.html     (PWA shell)
     ├── nexa_pwa.js    (Nexa ↔ WASM bridge)
     ├── style.css      (dark theme)
     ├── sw.js          (service worker — offline support)
     ├── manifest.json  (PWA manifest)
     ├── main.nexa      (your Nexa code)
     └── nexa.json      (project config)

  🌐 Run:  python -m http.server 3000
           open http://localhost:3000
""")
    return str(path)
