#!/usr/bin/env python3
"""
Alfred Sovereign Site Importer & Domain Manager (v7.5.3)
- Full 75 Sovereign Root TLDs (.kingdom, .alfred, .gsm, .zion, .lavocat, ...)
- Two-way live sync with Alfred Sovereign Wallet (~/.local/share/alfred-wallet/sns-domains.json)
- Hides Commander Root Authority infrastructure domains on citizen machines
- Builds & deploys PHP 8.4 + MariaDB, Static HTML5, Node.js, and Python apps with Alfred IDE
"""
import os
import sys

os.environ["QT_QPA_PLATFORM"] = "xcb;wayland"

import json
import re
import shutil
import zipfile
import subprocess
from datetime import datetime, timezone
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
    QLabel, QLineEdit, QComboBox, QPushButton, QFileDialog,
    QTableWidget, QTableWidgetItem, QHeaderView, QFrame, QMessageBox,
    QTabWidget
)
from PyQt6.QtCore import Qt

SITES_AVAILABLE = "/etc/nginx/sites-available"
SITES_ENABLED = "/etc/nginx/sites-enabled"
WWW_ROOT = "/var/www"
HTML_ROOT = "/var/www/html"
HOSTS_FILE = "/etc/hosts"
ALFRED_IDE_OPEN = "/usr/local/bin/alfred-ide-open"
ALFRED_IDE_BIN = "/opt/alfred-ide-desktop/codium"
SNS_FILE = os.path.expanduser("~/.local/share/alfred-wallet/sns-domains.json")
WALLET_ADDR_FILE = os.path.expanduser("~/.local/share/alfred-wallet/address.txt")

# All 75 Official Sovereign Root TLDs (anchored by Commander Root Authority) + .local for offline testing
SOVEREIGN_TLDS = [
    "kingdom", "alfred", "gsm", "dome", "lavocat", "mesh", "sovereign", "veil",
    "zion", "eden", "sanctuary", "covenant", "jerusalem", "judah", "israel", "bethel",
    "goshen", "canaan", "salem", "shabbat", "shalom", "selah", "agape", "grace",
    "glory", "hallelujah", "hosanna", "amen", "ark", "temple", "throne", "torah",
    "psalm", "revelation", "exodus", "genesis", "moses", "nazareth", "galilee", "messiah",
    "spirit", "holyghost", "twelve", "tribe", "trumpet", "scroll", "seal", "pillar",
    "lion", "eagle", "dove", "manna", "sabbath", "remnant", "ekklesia", "sion",
    "haven", "refuge", "beacon", "lighthouse", "watchtower", "fortress", "bastion", "shield",
    "vault", "cave", "batcave", "butler", "ghost", "alpha", "alphamatrix", "matrix",
    "metadome", "qgsm", "ygg", "local"
]

COMMANDER_ROOT_DOMAINS = {
    "root.kingdom",
    "treasury.kingdom",
    "treasury.gsm",
    "treasury.alfred",
    "authority.gsm",
    "notary.lavocat",
    "citadel.dome",
}


def is_commander_root_machine():
    return os.path.exists("/etc/alfred/is-root-authority")


def launch_alfred_ide(target_path):
    env = os.environ.copy()
    if os.path.exists(ALFRED_IDE_OPEN):
        subprocess.Popen([ALFRED_IDE_OPEN, target_path], env=env)
    elif os.path.exists(ALFRED_IDE_BIN):
        subprocess.Popen([ALFRED_IDE_BIN, "--no-sandbox", target_path], env=env)
    else:
        subprocess.Popen(["xdg-open", target_path], env=env)


def launch_alfred_wallet():
    for wbin in ("/usr/local/bin/alfred-wallet-web", "/usr/local/bin/alfred-wallet-gui"):
        if os.access(wbin, os.X_OK):
            subprocess.Popen([wbin], start_new_session=True)
            return
    subprocess.Popen(["xdg-open", "http://127.0.0.1:35777"], start_new_session=True)


def get_local_wallet_address():
    try:
        if os.path.exists(WALLET_ADDR_FILE):
            addr = open(WALLET_ADDR_FILE, "r").read().strip()
            if addr:
                return addr
    except Exception:
        pass
    return "LocalCitizenWallet"


def load_user_wallet_domains():
    """Returns user-owned domains from ~/.local/share/alfred-wallet/sns-domains.json."""
    if not os.path.exists(SNS_FILE):
        return []
    try:
        with open(SNS_FILE, "r", encoding="utf-8") as f:
            data = json.load(f)
        if not isinstance(data, list):
            return []
        is_root = is_commander_root_machine()
        out = []
        for item in data:
            if not isinstance(item, dict):
                continue
            dom = str(item.get("domain") or "").strip().lower()
            if not dom:
                continue
            if not is_root and (dom in COMMANDER_ROOT_DOMAINS or item.get("rootSigned") is True):
                continue
            out.append(item)
        return out
    except Exception:
        return []


def register_domain_in_wallet_sns(domain, tld, target_dir):
    """Links a deployed domain back into ~/.local/share/alfred-wallet/sns-domains.json so Wallet & Site Importer stay in sync."""
    try:
        os.makedirs(os.path.dirname(SNS_FILE), exist_ok=True)
        data = []
        if os.path.exists(SNS_FILE):
            try:
                with open(SNS_FILE, "r", encoding="utf-8") as f:
                    loaded = json.load(f)
                    if isinstance(loaded, list):
                        data = loaded
            except Exception:
                data = []
        owner = get_local_wallet_address()
        now_iso = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
        existing_idx = next(
            (i for i, d in enumerate(data) if isinstance(d, dict) and str(d.get("domain", "")).lower() == domain.lower()),
            -1
        )
        rec = {
            "domain": domain.lower(),
            "tld": tld.lstrip("."),
            "address": owner,
            "owner": owner,
            "yggdrasil": "200:7777::1",
            "ipv4": "127.0.0.1",
            "hostingPreset": "FULL_STACK",
            "webroot": target_dir,
            "linuxLiveProvisioned": True,
            "userOwned": True,
            "rootSigned": False,
            "role": f"Sovereign .{tld.lstrip('.')} Website",
            "verified": True,
            "createdAt": now_iso,
        }
        if existing_idx >= 0:
            data[existing_idx].update(rec)
        else:
            data.insert(0, rec)
        with open(SNS_FILE, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2)
    except Exception:
        pass


class SiteImporterWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Alfred Sovereign Web Hosting & Site Importer (75 Sovereign TLDs • Wallet Linked)")
        self.resize(920, 680)
        self.setStyleSheet("""
            QMainWindow, QWidget {
                background-color: #0b0d14;
                color: #e2e8f0;
                font-family: 'Segoe UI', 'Inter', 'Noto Sans', sans-serif;
            }
            QFrame#headerCard {
                background-color: #121422;
                border-bottom: 1px solid rgba(232, 184, 58, 0.3);
                padding: 14px;
            }
            QFrame#stackCard {
                background-color: #131728;
                border: 1px solid rgba(16, 185, 129, 0.35);
                border-radius: 8px;
                padding: 10px 14px;
            }
            QLabel#mainTitle {
                color: #E8B83A;
                font-size: 20px;
                font-weight: bold;
            }
            QLabel#subTitle {
                color: #94a3b8;
                font-size: 12px;
            }
            QTabWidget::pane {
                border: 1px solid rgba(232, 184, 58, 0.2);
                background-color: #0f111c;
                border-radius: 6px;
                margin-top: -1px;
            }
            QTabBar::tab {
                background: #141724;
                color: #94a3b8;
                padding: 10px 22px;
                font-weight: 600;
                border-top-left-radius: 6px;
                border-top-right-radius: 6px;
                margin-right: 4px;
            }
            QTabBar::tab:selected {
                background: #0f111c;
                color: #E8B83A;
                border-top: 2px solid #E8B83A;
            }
            QLineEdit, QComboBox {
                background-color: #161826;
                border: 1px solid rgba(232, 184, 58, 0.3);
                border-radius: 6px;
                padding: 8px 12px;
                color: #ffffff;
                font-size: 13px;
            }
            QLineEdit:focus, QComboBox:focus {
                border-color: #E8B83A;
            }
            QPushButton {
                background: rgba(232, 184, 58, 0.15);
                border: 1px solid #E8B83A;
                color: #fde68a;
                border-radius: 6px;
                padding: 7px 14px;
                font-weight: 600;
            }
            QPushButton:hover {
                background: rgba(232, 184, 58, 0.3);
                color: #ffffff;
            }
            QPushButton#btnPrimary {
                background-color: #E8B83A;
                color: #0b0d14;
                font-weight: bold;
                border: none;
                padding: 10px 22px;
            }
            QPushButton#btnPrimary:hover {
                background-color: #f5c74e;
            }
            QPushButton#btnIde {
                background-color: rgba(16, 185, 129, 0.18);
                border: 1px solid #10b981;
                color: #6ee7b7;
                font-weight: bold;
                padding: 7px 14px;
            }
            QPushButton#btnIde:hover {
                background-color: rgba(16, 185, 129, 0.35);
                color: #ffffff;
            }
            QTableWidget {
                background-color: #121422;
                border: 1px solid rgba(232, 184, 58, 0.2);
                gridline-color: #1f2338;
                color: #e2e8f0;
            }
            QHeaderView::section {
                background-color: #181b2e;
                color: #E8B83A;
                font-weight: bold;
                padding: 6px;
                border: 1px solid #232742;
            }
        """)

        central = QWidget()
        self.setCentralWidget(central)
        main_layout = QVBoxLayout(central)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)

        # Header Card
        header = QFrame()
        header.setObjectName("headerCard")
        h_layout = QHBoxLayout(header)
        h_layout.setContentsMargins(24, 14, 24, 14)

        title_col = QVBoxLayout()
        title_col.setSpacing(4)
        t_lbl = QLabel("🌐 SOVEREIGN WEB HOSTING & SITE IMPORTER")
        t_lbl.setObjectName("mainTitle")
        title_col.addWidget(t_lbl)

        s_lbl = QLabel("All 75 Official Sovereign Root TLDs • Linked Two-Way with Alfred Sovereign Wallet & Alfred IDE")
        s_lbl.setObjectName("subTitle")
        title_col.addWidget(s_lbl)
        h_layout.addLayout(title_col, 1)

        btn_wallet = QPushButton("◆ Open Sovereign Wallet")
        btn_wallet.setCursor(Qt.CursorShape.PointingHandCursor)
        btn_wallet.clicked.connect(launch_alfred_wallet)
        h_layout.addWidget(btn_wallet)

        btn_code_ide = QPushButton("⚡ Code New Site in Alfred IDE")
        btn_code_ide.setObjectName("btnIde")
        btn_code_ide.setCursor(Qt.CursorShape.PointingHandCursor)
        btn_code_ide.clicked.connect(lambda: launch_alfred_ide(HTML_ROOT))
        h_layout.addWidget(btn_code_ide)

        main_layout.addWidget(header)

        # Tabs
        self.tabs = QTabWidget()
        self.tabs.setContentsMargins(16, 16, 16, 16)

        tab_import = QWidget()
        self.setup_import_tab(tab_import)
        self.tabs.addTab(tab_import, "Import && Host Website (75 TLDs)")

        tab_manage = QWidget()
        self.setup_manage_tab(tab_manage)
        self.tabs.addTab(tab_manage, "My Hosted Sites && Wallet Domains")

        tab_gohostme = QWidget()
        self.setup_gohostme_tab(tab_gohostme)
        self.tabs.addTab(tab_gohostme, "GoHostMe Native Server")

        main_layout.addWidget(self.tabs)

    def setup_import_tab(self, parent):
        layout = QVBoxLayout(parent)
        layout.setContentsMargins(24, 16, 24, 16)
        layout.setSpacing(10)

        # Stack Info Banner
        stack_card = QFrame()
        stack_card.setObjectName("stackCard")
        sc_layout = QVBoxLayout(stack_card)
        sc_layout.setContentsMargins(12, 8, 12, 8)
        sc_lbl = QLabel(
            "<b>⚡ Ready-to-Code Local Hosting Stack:</b> "
            "Nginx (:80) + PHP 8.4-FPM + MariaDB 11.8 &nbsp;|&nbsp; "
            "<b>DB Host:</b> <code>127.0.0.1:3306</code> &nbsp; "
            "<b>User:</b> <code>alfred</code> &nbsp; "
            "<b>Pass:</b> <code>alfred</code> &nbsp; "
            "<b>Web Root:</b> <code>/var/www/&lt;domain&gt;/public_html</code>"
        )
        sc_lbl.setStyleSheet("color: #a7f3d0; font-size: 12px;")
        sc_lbl.setWordWrap(True)
        sc_layout.addWidget(sc_lbl)
        layout.addWidget(stack_card)

        # Step 1: Select Source Files
        layout.addWidget(QLabel("1. SELECT WEBSITE SOURCE (OPTIONAL — LEAVE BLANK TO GENERATE STARTER APP):"))
        src_row = QHBoxLayout()
        self.src_path_input = QLineEdit()
        self.src_path_input.setPlaceholderText("/path/to/my-website-folder or website.zip (or leave blank for starter template)")
        btn_browse_folder = QPushButton("Browse Folder...")
        btn_browse_folder.clicked.connect(self.browse_folder)
        btn_browse_zip = QPushButton("Browse .ZIP...")
        btn_browse_zip.clicked.connect(self.browse_zip)
        src_row.addWidget(self.src_path_input)
        src_row.addWidget(btn_browse_folder)
        src_row.addWidget(btn_browse_zip)
        layout.addLayout(src_row)

        # Step 2: Choose Sovereign Domain or Pick from Wallet
        layout.addWidget(QLabel("2. CHOOSE SOVEREIGN DOMAIN (ALL 75 ROOT TLDs OR PICK FROM ALFRED WALLET):"))
        wallet_row = QHBoxLayout()
        self.wallet_dom_combo = QComboBox()
        self.refresh_wallet_domain_combo()
        self.wallet_dom_combo.currentIndexChanged.connect(self.on_wallet_domain_selected)
        btn_sync_wallet = QPushButton("🔄 Sync Wallet Domains")
        btn_sync_wallet.clicked.connect(self.refresh_wallet_domain_combo)
        wallet_row.addWidget(self.wallet_dom_combo, 3)
        wallet_row.addWidget(btn_sync_wallet, 1)
        layout.addLayout(wallet_row)

        dom_row = QHBoxLayout()
        self.dom_name_input = QLineEdit()
        self.dom_name_input.setPlaceholderText("e.g. myportfolio, ministry, store, studio")
        self.dom_ext_combo = QComboBox()
        self.dom_ext_combo.setMaxVisibleItems(18)
        for tld in SOVEREIGN_TLDS:
            self.dom_ext_combo.addItem(f".{tld}")
        dom_row.addWidget(self.dom_name_input, 3)
        dom_row.addWidget(self.dom_ext_combo, 1)
        layout.addLayout(dom_row)

        # Step 3: Engine type
        layout.addWidget(QLabel("3. SELECT WEB ENGINE & RUNTIME:"))
        self.engine_combo = QComboBox()
        self.engine_combo.addItems([
            "PHP 8.4 + MariaDB / WordPress / Dynamic Web App",
            "Static HTML5 / Single Page App / Modern JS",
            "Node.js / Express (Proxy to local port 3000)",
            "Python / FastAPI / Flask (Proxy to local port 8000)"
        ])
        layout.addWidget(self.engine_combo)

        # Deploy button
        layout.addSpacing(4)
        self.status_box = QLabel("")
        self.status_box.setStyleSheet("color: #10b981; font-weight: bold; font-size: 13px;")
        layout.addWidget(self.status_box)

        btn_deploy = QPushButton("🚀 DEPLOY SOVEREIGN WEBSITE & LINK TO WALLET")
        btn_deploy.setObjectName("btnPrimary")
        btn_deploy.setCursor(Qt.CursorShape.PointingHandCursor)
        btn_deploy.clicked.connect(self.deploy_website)
        layout.addWidget(btn_deploy)
        layout.addStretch()

    def refresh_wallet_domain_combo(self):
        if not hasattr(self, "wallet_dom_combo"):
            return
        self.wallet_dom_combo.blockSignals(True)
        self.wallet_dom_combo.clear()
        user_doms = load_user_wallet_domains()
        if user_doms:
            self.wallet_dom_combo.addItem(f"◆ Pick from My Sovereign Wallet ({len(user_doms)} registered) — or type a new domain below...", "")
            for d in user_doms:
                dom = str(d.get("domain", "")).strip()
                role = str(d.get("role", "Sovereign Domain")).strip()
                self.wallet_dom_combo.addItem(f"👑 {dom}  ({role})", dom)
        else:
            self.wallet_dom_combo.addItem("◆ No custom domains in Wallet yet — type any name below across all 75 Sovereign TLDs", "")
        self.wallet_dom_combo.blockSignals(False)

    def on_wallet_domain_selected(self, idx):
        dom = self.wallet_dom_combo.itemData(idx)
        if not dom or "." not in dom:
            return
        prefix, tld = dom.rsplit(".", 1)
        self.dom_name_input.setText(prefix)
        ext = f".{tld.lower()}"
        i = self.dom_ext_combo.findText(ext)
        if i >= 0:
            self.dom_ext_combo.setCurrentIndex(i)

    def setup_manage_tab(self, parent):
        layout = QVBoxLayout(parent)
        layout.setContentsMargins(20, 18, 20, 18)
        layout.setSpacing(12)

        top_row = QHBoxLayout()
        top_row.addWidget(QLabel("MY HOSTED SOVEREIGN WEBSITES & WALLET DOMAINS:"))
        btn_refresh = QPushButton("🔄 Refresh List")
        btn_refresh.clicked.connect(self.load_sites)
        top_row.addStretch()
        top_row.addWidget(btn_refresh)
        layout.addLayout(top_row)

        self.site_table = QTableWidget()
        self.site_table.setColumnCount(4)
        self.site_table.setHorizontalHeaderLabels(["Domain / URL", "Web Root", "Engine / Status", "Actions"])
        self.site_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        self.site_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        self.site_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        self.site_table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
        layout.addWidget(self.site_table)
        self.load_sites()

    def setup_gohostme_tab(self, parent):
        layout = QVBoxLayout(parent)
        layout.setContentsMargins(24, 24, 24, 24)
        layout.setSpacing(14)

        t = QLabel("GoHostMe Native Sovereign Server Control Panel")
        t.setStyleSheet("font-size: 16px; font-weight: bold; color: #E8B83A;")
        layout.addWidget(t)

        d = QLabel(
            "GoHostMe is Alfred Linux's built-in hosting control panel, providing complete management "
            "for MariaDB databases, virtual hosts, SSL certificates, PM2 process management, and DNS records.<br><br>"
            "<b>Web Control Panel:</b> <code>http://127.0.0.1:2280</code><br>"
            "<b>Local Control Panel Login:</b> Username <code>alfred</code> / Password <code>alfred</code><br>"
            "<b>Local MariaDB Developer Credentials:</b> User <code>alfred</code> / Password <code>alfred</code> on <code>127.0.0.1:3306</code>"
        )
        d.setWordWrap(True)
        layout.addWidget(d)

        btn_open = QPushButton("🌐 Open GoHostMe Web Panel (Port 2280 — Login: alfred / alfred)")
        btn_open.setObjectName("btnPrimary")
        btn_open.setCursor(Qt.CursorShape.PointingHandCursor)
        btn_open.clicked.connect(lambda: subprocess.Popen(["xdg-open", "http://127.0.0.1:2280"]))
        layout.addWidget(btn_open)

        btn_restart = QPushButton("🔄 Restart GoHostMe & Local Hosting Services")
        btn_restart.clicked.connect(self.restart_gohostme)
        layout.addWidget(btn_restart)
        layout.addStretch()

    def browse_folder(self):
        f = QFileDialog.getExistingDirectory(self, "Select Website Directory")
        if f:
            self.src_path_input.setText(f)
            if not self.dom_name_input.text():
                self.dom_name_input.setText(os.path.basename(f).lower().replace(" ", "-"))

    def browse_zip(self):
        f, _ = QFileDialog.getOpenFileName(self, "Select Website ZIP Archive", "", "ZIP Archives (*.zip)")
        if f:
            self.src_path_input.setText(f)
            if not self.dom_name_input.text():
                base = os.path.splitext(os.path.basename(f))[0]
                self.dom_name_input.setText(base.lower().replace(" ", "-"))

    def deploy_website(self):
        src = self.src_path_input.text().strip()
        name = re.sub(r'[^a-z0-9\-]', '', self.dom_name_input.text().strip().lower())
        ext = self.dom_ext_combo.currentText()
        engine = self.engine_combo.currentIndex()

        if not name:
            QMessageBox.warning(self, "Missing Name", "Please enter a valid domain name prefix (e.g. 'myblog').")
            return

        domain = f"{name}{ext}"
        db_name = "site_" + re.sub(r'[^a-z0-9_]', '_', name)
        target_dir = f"{WWW_ROOT}/{domain}/public_html"

        try:
            # 1. Create directory
            subprocess.run(["sudo", "mkdir", "-p", target_dir], check=True)

            # 2. Copy or extract source files
            if src:
                if os.path.isdir(src):
                    subprocess.run(["sudo", "cp", "-r", f"{src}/.", target_dir], check=True)
                elif zipfile.is_zipfile(src):
                    with zipfile.ZipFile(src, 'r') as zip_ref:
                        zip_ref.extractall("/tmp/site_extracted")
                    subprocess.run(["sudo", "cp", "-r", "/tmp/site_extracted/.", target_dir], check=True)
                    shutil.rmtree("/tmp/site_extracted", ignore_errors=True)
            else:
                if engine == 0:
                    subprocess.run(
                        ["sudo", "mariadb", "-e", f"CREATE DATABASE IF NOT EXISTS `{db_name}`; GRANT ALL PRIVILEGES ON `{db_name}`.* TO 'alfred'@'localhost'; GRANT ALL PRIVILEGES ON `{db_name}`.* TO 'alfred'@'127.0.0.1'; FLUSH PRIVILEGES;"],
                        check=False
                    )
                    index_path = f"/tmp/{domain}_index.php"
                    with open(index_path, "w") as f:
                        f.write(f"""<?php
$db_status = "Connected to MariaDB ({db_name})";
try {{
    $pdo = new PDO("mysql:host=127.0.0.1;dbname={db_name};charset=utf8mb4", "alfred", "alfred", [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    ]);
}} catch (Exception $e) {{
    $db_status = "DB Notice: " . htmlspecialchars($e->getMessage());
}}
?>
<!DOCTYPE html>
<html>
<head><title>{domain} — Sovereign PHP 8.4 + MariaDB Site</title>
<style>
body {{ background: #0b0d14; color: #e2e8f0; font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }}
.card {{ background: #121422; border: 1px solid #E8B83A; padding: 40px; border-radius: 12px; text-align: center; box-shadow: 0 0 30px rgba(232, 184, 58, 0.2); max-width: 560px; }}
h1 {{ color: #E8B83A; margin: 0 0 10px 0; }}
.badge {{ display: inline-block; background: rgba(16,185,129,0.18); border: 1px solid #10b981; color: #6ee7b7; padding: 6px 14px; border-radius: 999px; font-size: 13px; margin-top: 12px; }}
code {{ color: #fde68a; }}
</style>
</head>
<body>
<div class="card">
<h1>👑 {domain}</h1>
<p>Sovereign Dynamic Website Hosted on Alfred Linux (PHP <?= PHP_VERSION ?>)</p>
<p>Root Directory: <code>{target_dir}</code></p>
<div class="badge">✓ <?= $db_status ?></div>
</div>
</body>
</html>""")
                    subprocess.run(["sudo", "cp", index_path, f"{target_dir}/index.php"], check=True)
                    os.remove(index_path)
                else:
                    index_path = f"/tmp/{domain}_index.html"
                    with open(index_path, "w") as f:
                        f.write(f"""<!DOCTYPE html>
<html>
<head><title>{domain} — Sovereign Site</title>
<style>
body {{ background: #0b0d14; color: #e2e8f0; font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }}
.card {{ background: #121422; border: 1px solid #E8B83A; padding: 40px; border-radius: 12px; text-align: center; box-shadow: 0 0 30px rgba(232, 184, 58, 0.2); }}
h1 {{ color: #E8B83A; margin: 0 0 10px 0; }}
p {{ color: #94a3b8; }}
</style>
</head>
<body>
<div class="card">
<h1>👑 {domain}</h1>
<p>Sovereign Website Hosted on Alfred Linux</p>
<p>Root Directory: <code>{target_dir}</code></p>
</div>
</body>
</html>""")
                    subprocess.run(["sudo", "cp", index_path, f"{target_dir}/index.html"], check=True)
                    os.remove(index_path)

            # 3. Permissions: alfred:www-data 2775
            subprocess.run(["sudo", "chown", "-R", "alfred:www-data", f"{WWW_ROOT}/{domain}"], check=True)
            subprocess.run(["sudo", "chmod", "-R", "2775", f"{WWW_ROOT}/{domain}"], check=True)

            # 4. Write Nginx Config (use .conf consistently and remove any duplicate non-.conf link)
            vhost_path = f"/tmp/vhost_{domain}.conf"
            if engine in (0, 1):
                conf_content = f"""server {{
    listen 80;
    server_name {domain} *.{domain};
    root {target_dir};
    index index.php index.html index.htm;
    location / {{
        try_files $uri $uri/ /index.php?$query_string;
    }}
    location ~ \\.php$ {{
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
    }}
}}
"""
            elif engine == 2:
                conf_content = f"""server {{
    listen 80;
    server_name {domain} *.{domain};
    location / {{
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }}
}}
"""
            else:
                conf_content = f"""server {{
    listen 80;
    server_name {domain} *.{domain};
    location / {{
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }}
}}
"""
            with open(vhost_path, "w") as f:
                f.write(conf_content)

            subprocess.run(["sudo", "rm", "-f", f"{SITES_ENABLED}/{domain}", f"{SITES_AVAILABLE}/{domain}"], check=False)
            subprocess.run(["sudo", "cp", vhost_path, f"{SITES_AVAILABLE}/{domain}.conf"], check=True)
            subprocess.run(["sudo", "ln", "-sf", f"{SITES_AVAILABLE}/{domain}.conf", f"{SITES_ENABLED}/{domain}.conf"], check=True)
            os.remove(vhost_path)

            # 5. Add to /etc/hosts
            with open(HOSTS_FILE, "r") as f:
                hosts_data = f.read()
            if not re.search(rf"(^|\s){re.escape(domain)}(\s|$)", hosts_data, re.M):
                subprocess.run(["sudo", "sh", "-c", f"echo '127.0.0.1 {domain}' >> {HOSTS_FILE}"], check=True)

            # 6. Link back to Alfred Sovereign Wallet (~/.local/share/alfred-wallet/sns-domains.json)
            register_domain_in_wallet_sns(domain, ext, target_dir)
            self.refresh_wallet_domain_combo()

            # 7. Reload Nginx
            subprocess.run(["sudo", "systemctl", "reload", "nginx"], check=False)

            self.status_box.setText(f"✓ Successfully deployed & linked to Wallet: http://{domain}")
            QMessageBox.information(
                self,
                "Site Deployed & Linked to Wallet!",
                f"Your sovereign website has been deployed and linked to your Alfred Sovereign Wallet!\n\n"
                f"URL: http://{domain}\n"
                f"Web Root: {target_dir}\n"
                f"Database: {db_name} (User: alfred / Pass: alfred)"
            )
            self.load_sites()
            self.tabs.setCurrentIndex(1)

        except Exception as e:
            QMessageBox.critical(self, "Deployment Error", f"Failed to deploy site:\n{str(e)}")

    def _add_site_row(self, label, url, web_root, engine_label):
        row = self.site_table.rowCount()
        self.site_table.insertRow(row)

        self.site_table.setItem(row, 0, QTableWidgetItem(label))
        self.site_table.setItem(row, 1, QTableWidgetItem(web_root))

        st = QTableWidgetItem(engine_label)
        st.setForeground(Qt.GlobalColor.green)
        self.site_table.setItem(row, 2, st)

        btn_box = QWidget()
        b_layout = QHBoxLayout(btn_box)
        b_layout.setContentsMargins(4, 2, 4, 2)
        b_layout.setSpacing(6)

        btn_open = QPushButton("🌐 Open")
        btn_open.clicked.connect(lambda checked, u=url: subprocess.Popen(["xdg-open", u]))
        b_layout.addWidget(btn_open)

        if os.path.isdir(web_root):
            btn_edit = QPushButton("⚡ Alfred IDE")
            btn_edit.setObjectName("btnIde")
            btn_edit.clicked.connect(lambda checked, p=web_root: launch_alfred_ide(p))
            b_layout.addWidget(btn_edit)

        self.site_table.setCellWidget(row, 3, btn_box)

    def load_sites(self):
        self.site_table.setRowCount(0)
        seen_domains = set()
        is_root = is_commander_root_machine()

        # 1. Subdirectory apps under /var/www/html/<app>
        if os.path.isdir(HTML_ROOT):
            for entry in sorted(os.listdir(HTML_ROOT)):
                sub_path = os.path.join(HTML_ROOT, entry)
                if os.path.isdir(sub_path) and not entry.startswith("."):
                    has_php = any(f.endswith(".php") for f in os.listdir(sub_path))
                    eng = "PHP 8.4 + MariaDB (Active)" if has_php else "Local Web App (Active)"
                    self._add_site_row(
                        f"127.0.0.1/{entry}/",
                        f"http://127.0.0.1/{entry}/",
                        sub_path,
                        eng
                    )

        # 2. Virtual hosts in /etc/nginx/sites-enabled (stripping .conf and excluding Commander root domains on citizen machines)
        if os.path.exists(SITES_ENABLED):
            for s in sorted(os.listdir(SITES_ENABLED)):
                if s == "default":
                    continue
                dom = s[:-5] if s.endswith(".conf") else s
                if not is_root and dom in COMMANDER_ROOT_DOMAINS:
                    continue
                if dom in seen_domains:
                    continue
                seen_domains.add(dom)
                path = f"{WWW_ROOT}/{dom}/public_html"
                self._add_site_row(
                    dom,
                    f"http://{dom}",
                    path if os.path.exists(path) else "(proxy)",
                    "Sovereign VHost + Wallet Linked"
                )

        # 3. Also show any user-registered Wallet domains that haven't been provisioned into Nginx yet
        for d in load_user_wallet_domains():
            dom = str(d.get("domain", "")).strip().lower()
            if not dom or dom in seen_domains:
                continue
            seen_domains.add(dom)
            path = f"{WWW_ROOT}/{dom}/public_html"
            self._add_site_row(
                dom,
                f"http://{dom}",
                path if os.path.exists(path) else "(Registered in Wallet — Click Import tab to deploy)",
                "Wallet Registered Domain"
            )

    def restart_gohostme(self):
        subprocess.run(["sudo", "systemctl", "restart", "mariadb", "php8.4-fpm", "nginx", "alfred-gohostme-api"], check=False)
        QMessageBox.information(self, "Restarted", "Nginx, PHP 8.4-FPM, MariaDB, and GoHostMe have been restarted.")


def main():
    app = QApplication(sys.argv)
    win = SiteImporterWindow()
    if "--sites" in sys.argv:
        win.tabs.setCurrentIndex(1)
    win.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()
