import os
import sys

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8")

PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
WEBAPP_DIR = os.path.join(PROJECT_ROOT, "client", "webapp")
INDEX_PATH = os.path.join(WEBAPP_DIR, "index.html")
TEMPLATES_DIR = os.path.join(WEBAPP_DIR, "templates")
JS_TEMPLATES_DIR = os.path.join(WEBAPP_DIR, "js", "ui", "templates")
os.makedirs(TEMPLATES_DIR, exist_ok=True)
os.makedirs(JS_TEMPLATES_DIR, exist_ok=True)

import subprocess
try:
    git_html = subprocess.check_output(["git", "show", "e8cd102^:client/webapp/index.html"], encoding="utf-8")
    orig_lines = git_html.splitlines(keepends=True)
except Exception:
    with open(INDEX_PATH, "r", encoding="utf-8") as f:
        orig_lines = f.readlines()

MODALS_SPEC = [
    ("modal-game-notice", "game_notice_modal.html", 471, 482, "system"),
    ("modal-npc-dialogue", "npc_dialogue_modal.html", 485, 515, "system"),
    ("modal-meridian", "meridian_modal.html", 521, 537, "inventory"),
    ("modal-vault", "vault_modal.html", 540, 611, "inventory"),
    ("modal-character", "character_modal.html", 614, 656, "inventory"),
    ("modal-bag", "bag_modal.html", 659, 752, "inventory"),
    ("modal-loot-filter", "loot_filter_modal.html", 755, 809, "inventory"),
    ("modal-megashop", "megashop_modal.html", 812, 877, "activities"),
    ("modal-checkout", "checkout_modal.html", 880, 916, "activities"),
    ("modal-web3", "web3_modal.html", 919, 975, "activities"),
    ("modal-season", "season_modal.html", 978, 1107, "activities"),
    ("modal-agent-orb", "agent_orb_modal.html", 1110, 1307, "activities"),
    ("modal-harvest-report", "harvest_report_modal.html", 1310, 1363, "activities"),
    ("modal-worldmap", "worldmap_modal.html", 1366, 1418, "world"),
    ("modal-dungeon", "dungeon_modal.html", 1421, 1690, "world"),
    ("modal-hideout", "hideout_modal.html", 1693, 1907, "world"),
    ("modal-endgame-atlas", "endgame_atlas_modal.html", 1911, 2046, "endgame"),
    ("modal-war-fog", "war_fog_modal.html", 2049, 2153, "endgame"),
    ("modal-forge", "forge_modal.html", 2156, 2314, "inventory"),
    ("modal-settings", "settings_modal.html", 2317, 2507, "system"),
    ("modal-feedback", "feedback_modal.html", 2510, 2644, "system"),
    ("modal-account", "account_modal.html", 2647, 2951, "auth"),
    ("modal-char-create", "char_create_modal.html", 2954, 3067, "auth"),
    ("modal-story-quests", "story_quests_modal.html", 3071, 3138, "endgame"),
    ("modal-divine-vault", "divine_vault_modal.html", 3141, 3168, "world"),
    ("modal-combat-test-dashboard", "combat_test_dashboard_modal.html", 60, 97, "system"),
]

# 1. Write HTML template files
print("\n--- Writing HTML Template Files ---")
for elem_id, tpl_filename, start, end, cat in MODALS_SPEC:
    m_lines = orig_lines[start-1:end]
    content = "".join(m_lines).strip() + "\n"
    out_path = os.path.join(TEMPLATES_DIR, tpl_filename)
    with open(out_path, "w", encoding="utf-8") as f:
        f.write(content)
    line_count = len(content.splitlines())
    print(f"  [HTML] {tpl_filename:<26} ({line_count} lines)")
    assert line_count <= 400, f"Template {tpl_filename} exceeds 400 lines: {line_count}"

# 2. Write JS Template Catalog files
CATALOG_DEFS = {
    "system": {
        "filename": "template_catalog_system.js",
        "title": "SYSTEM & NOTICES TEMPLATES",
        "modals": ["modal-game-notice", "modal-npc-dialogue", "modal-settings", "modal-feedback", "modal-combat-test-dashboard"]
    },
    "auth": {
        "filename": "template_catalog_auth.js",
        "title": "AUTHENTICATION & CHARACTER CREATION TEMPLATES",
        "modals": ["modal-account", "modal-char-create"]
    },
    "inventory": {
        "filename": "template_catalog_inventory.js",
        "title": "INVENTORY, BAG, VAULT & FORGE TEMPLATES",
        "modals": ["modal-meridian", "modal-vault", "modal-character", "modal-bag", "modal-loot-filter", "modal-forge"]
    },
    "world": {
        "filename": "template_catalog_world.js",
        "title": "WORLD MAP, DUNGEONS & HIDEOUT TEMPLATES",
        "modals": ["modal-worldmap", "modal-dungeon", "modal-hideout", "modal-divine-vault"]
    },
    "activities": {
        "filename": "template_catalog_activities.js",
        "title": "MEGASHOP, SEASONS & AGENT ORB TEMPLATES",
        "modals": ["modal-megashop", "modal-checkout", "modal-web3", "modal-season", "modal-agent-orb", "modal-harvest-report"]
    },
    "endgame": {
        "filename": "template_catalog_endgame.js",
        "title": "ENDGAME ATLAS, WAR FOG & QUEST BOARD TEMPLATES",
        "modals": ["modal-endgame-atlas", "modal-war-fog", "modal-story-quests"]
    }
}

print("\n--- Writing JS Template Catalog Files ---")
for cat_key, cat_info in CATALOG_DEFS.items():
    cat_filename = cat_info["filename"]
    cat_path = os.path.join(JS_TEMPLATES_DIR, cat_filename)
    
    js_lines = [
        "// =============================================================================",
        f"// FREEEXILE: UI TEMPLATE CATALOG - {cat_info['title']}",
        f"// Module: js/ui/templates/{cat_filename}",
        "// Standards 2026: Catalog Soft Cap <= 700 lines, Hard Cap <= 1000 lines",
        "// =============================================================================",
        "",
        "(function () {",
        "  'use strict';",
        "",
        "  window.UITemplateManager = window.UITemplateManager || {",
        "    templates: {},",
        "    templateOrder: [],",
        "    register(id, html) {",
        "      if (!this.templates[id]) this.templateOrder.push(id);",
        "      this.templates[id] = html;",
        "      const fullId = id.startsWith('modal-') ? id : 'modal-' + id;",
        "      this.templates[fullId] = html;",
        "      const shortId = id.startsWith('modal-') ? id.slice(6) : id;",
        "      this.templates[shortId] = html;",
        "    }",
        "  };",
        "",
        "  const reg = (id, html) => window.UITemplateManager.register(id, html);",
        ""
    ]
    
    for m_id in cat_info["modals"]:
        # Find modal in MODALS_SPEC
        spec = [s for s in MODALS_SPEC if s[0] == m_id][0]
        start, end = spec[2], spec[3]
        raw_html = "".join(orig_lines[start-1:end]).strip()
        # Escape any special backtick or interpolation if needed
        escaped_html = raw_html.replace("\\", "\\\\").replace("`", "\\`").replace("${", "\\${")
        js_lines.append(f"  // Template: {m_id}")
        js_lines.append(f"  reg('{m_id}', `{escaped_html}`);")
        js_lines.append("")
    
    js_lines.append("})();")
    js_lines.append("")
    
    full_js = "\n".join(js_lines)
    with open(cat_path, "w", encoding="utf-8") as f:
        f.write(full_js)
    
    line_count = len(full_js.splitlines())
    print(f"  [JS CATALOG] {cat_filename:<32} ({line_count} lines)")
    assert line_count <= 1000, f"Catalog {cat_filename} exceeds 1000 lines: {line_count}"

# 3. Write template_manager.js
manager_path = os.path.join(WEBAPP_DIR, "js", "ui", "template_manager.js")
manager_code = """// =============================================================================
// FREEEXILE: UI DYNAMIC TEMPLATE MANAGER & LOADER
// Module: template_manager.js
// Engineering Standards 2026: Strict Separation of Concerns, Soft Cap <= 350 lines
// =============================================================================

(function () {
  'use strict';

  class UITemplateManagerClass {
    constructor() {
      this.templates = {};
      this.templateOrder = [];
      this.mounted = new Set();
      this.defaultContainerId = 'modal-container';
    }

    register(id, html) {
      if (!id || typeof html !== 'string') return;
      if (!this.templates[id]) {
        this.templateOrder.push(id);
      }
      this.templates[id] = html;
      const fullId = id.startsWith('modal-') ? id : `modal-${id}`;
      this.templates[fullId] = html;
      const shortId = id.startsWith('modal-') ? id.slice(6) : id;
      this.templates[shortId] = html;
    }

    get(id) {
      return this.templates[id] || '';
    }

    has(id) {
      return Boolean(this.templates[id]);
    }

    isMounted(id) {
      const fullId = id.startsWith('modal-') ? id : `modal-${id}`;
      return this.mounted.has(fullId) || Boolean(document.getElementById(fullId));
    }

    getContainer(container) {
      if (!container) return document.getElementById(this.defaultContainerId) || document.getElementById('app-viewport') || document.body;
      if (typeof container === 'string') {
        return document.querySelector(container) || document.getElementById(container);
      }
      return container;
    }

    mount(id, container) {
      const targetContainer = this.getContainer(container);
      if (!targetContainer) return null;

      const fullId = id.startsWith('modal-') ? id : `modal-${id}`;
      const existing = document.getElementById(fullId);
      if (existing) {
        this.mounted.add(fullId);
        return existing;
      }

      const html = this.get(id);
      if (!html) return null;

      const temp = document.createElement('div');
      temp.innerHTML = html.trim();
      const el = temp.firstElementChild;
      if (el) {
        targetContainer.appendChild(el);
        this.mounted.add(el.id || fullId);
        return el;
      }
      return null;
    }

    mountAll(container) {
      const targetContainer = this.getContainer(container);
      if (!targetContainer) return;

      const mountedIds = new Set();
      const fragment = document.createDocumentFragment();

      for (const id of this.templateOrder) {
        const fullId = id.startsWith('modal-') ? id : `modal-${id}`;
        if (mountedIds.has(fullId) || document.getElementById(fullId)) {
          mountedIds.add(fullId);
          this.mounted.add(fullId);
          continue;
        }

        const html = this.templates[id];
        if (!html) continue;

        const temp = document.createElement('div');
        temp.innerHTML = html.trim();
        while (temp.firstChild) {
          const node = temp.firstChild;
          if (node.nodeType === 1 && node.id) {
            mountedIds.add(node.id);
            this.mounted.add(node.id);
          }
          fragment.appendChild(node);
        }
      }

      targetContainer.appendChild(fragment);

      window.dispatchEvent(new CustomEvent('freeexile:templatesMounted', {
        detail: { count: this.mounted.size }
      }));
    }

    resolveCandidateUrls(id) {
      if (!id) return [];
      const clean = id.startsWith('modal-') ? id.slice(6) : id;
      const snake = clean.replace(/-/g, '_');
      const candidates = new Set([
        `templates/${snake}_modal.html`,
        `templates/${clean}_modal.html`,
        `templates/${id}.html`,
        `templates/${clean}.html`,
        `templates/${snake}.html`
      ]);
      return Array.from(candidates);
    }

    async loadAndMount(templateName, url, container) {
      if (this.has(templateName)) {
        return this.mount(templateName, container);
      }
      const fetchUrl = url || `templates/${templateName}.html`;
      try {
        const res = await fetch(fetchUrl);
        if (res.ok) {
          const html = await res.text();
          this.register(templateName, html);
          return this.mount(templateName, container);
        }
      } catch (err) {
        console.warn(`[UITemplateManager] Failed to fetch template ${templateName}:`, err);
      }
      return null;
    }

    init(container) {
      this.mountAll(container);
    }
  }

  // Preserve existing instance if already created by catalogs
  const existingTemplates = window.UITemplateManager?.templates || {};
  const existingOrder = window.UITemplateManager?.templateOrder || [];
  window.UITemplateManager = new UITemplateManagerClass();
  for (const [k, v] of Object.entries(existingTemplates)) {
    window.UITemplateManager.register(k, v);
  }
  if (existingOrder.length > 0) {
    window.UITemplateManager.templateOrder = Array.from(new Set([...existingOrder, ...window.UITemplateManager.templateOrder]));
  }

  // Auto-mount immediately if DOM container is present, or on DOMContentLoaded
  const runInit = () => {
    window.UITemplateManager.init();
  };

  if (document.readyState === 'loading') {
    if (document.getElementById(window.UITemplateManager.defaultContainerId)) {
      runInit();
    } else {
      document.addEventListener('DOMContentLoaded', runInit);
    }
  } else {
    runInit();
  }
})();
"""

with open(manager_path, "w", encoding="utf-8") as f:
    f.write(manager_code)

print(f"\n--- Writing Template Manager ---")
print(f"  [JS MANAGER] template_manager.js ({len(manager_code.splitlines())} lines)")

print("\nTemplates and Catalogs generated successfully!")
