# === Standard Library ===
import glob
import importlib
import json
import os
import re
import shutil
import subprocess
import sys
import webbrowser
# === PyQt6 ===
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QFont, QFontDatabase, QPixmap
from PyQt6.QtWidgets import (
    QApplication, QFileDialog, QHBoxLayout, QLabel, QLineEdit,
    QMainWindow, QMessageBox, QPushButton, QPlainTextEdit,
    QProgressBar, QSizePolicy, QSpacerItem, QStackedLayout,
    QStackedWidget, QVBoxLayout, QWidget
)
# === Local Modules ===
from worker import WorkerThread
# === App Configuration ===
config_path = os.path.join(os.path.dirname(__file__), ".config_app")

class MiVentana(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setMinimumSize(960, 540)
        font_id = QFontDatabase.addApplicationFont(".config_app/urbanist.ttf")
        font_families = QFontDatabase.applicationFontFamilies(font_id)
        font = QFont(font_families[0])
        QApplication.setFont(font)
        self.setStyleSheet(open('.config_app/layout.css', 'r').read())       
        self.stacked_widget = QStackedWidget(self)
        self.pages = {}
        print("Style default load")
        print("Font default load:", font_families)
        #PageImportWallet -->Page start
        #PageWebsites -->Page Two
        #PageTemplates -->Page three
        #PageCreateWebsite -->Page four
        #PagePublic -->Page five
        #PageWebsitesEditor -->Page six
        #PageEditWebsite -->Page seven

        for page_class in [PageImportWallet,PageWebsites,PageTemplates,PageCreateWebsite,PagePublic,PageWebsitesEditor,PageEditWebsite]:
            page_instance = page_class(self.stacked_widget)
            self.stacked_widget.addWidget(page_instance)
            self.pages[page_class.__name__] = page_instance

        self.setCentralWidget(self.stacked_widget)
        # Cargador de arranque -- importante!
        perfiles = os.listdir('.config_app/profiles') if os.path.exists('.config_app/profiles') else []
        if any(os.path.isdir(os.path.join('.config_app/profiles', p)) for p in perfiles):
            self.stacked_widget.setCurrentWidget(self.pages["PageWebsites"])
            print("Wallet Json detected")
        else:
            self.stacked_widget.setCurrentWidget(self.pages["PageImportWallet"])
            print("No detected Wallet Json")
        print("Welcome Neo")
class BasePage(QWidget):
    def __init__(self, stacked_widget, container_width_percentage, layout_type):
        super().__init__()

        self.stacked_widget = stacked_widget
        self.container_width_percentage = container_width_percentage
        BasePage.profile_selected = 'default'

        layout = QVBoxLayout(self)

        for object_name, widget_type, box, height in [
            ('widget_up', QWidget, QHBoxLayout, 30),
            ('widget_center', QWidget, layout_type, None),
            ('widget_down', QWidget, QHBoxLayout, 35)
        ]:
            widget = widget_type()
            layout_widget = box()
            widget.setLayout(layout_widget)
            layout_widget.setContentsMargins(10, 0, 10, 0)
            widget.setObjectName(object_name)
            if height is not None:
                widget.setFixedHeight(height)
            setattr(self, object_name, widget)
            layout.addWidget(widget)
            #widget_up ===
            if object_name == 'widget_up':
                for index, (label_name, text) in enumerate([
                    ('label_title', 'ArWeb'),
                    ('label_balance', 'Balance')
                ]):
                    label = QLabel(text)
                    label.setObjectName(label_name)
                    setattr(self, label_name, label)
                    widget.layout().addWidget(label)
                    if index == 0:
                        spacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
                        widget.layout().addItem(spacer)
            #widget_center ===
            elif object_name == 'widget_center':
                self.container = QWidget()
                self.container_layout = layout_type(self.container)
                self.container_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
                self.container.setLayout(self.container_layout)

                self.loading_group = QWidget()
                loading_group_layout = QVBoxLayout(self.loading_group)

                for obj_name, widget_type, h in [
                    ('label_loading', QLabel, 20),
                    ('progress_bar', QProgressBar, 4)
                ]:
                    w = widget_type()
                    w.setObjectName(obj_name)
                    w.setFixedHeight(h)

                    if isinstance(w, QLabel):
                        w.setAlignment(Qt.AlignmentFlag.AlignCenter)
                        w.setText("Loading...")
                    elif isinstance(w, QProgressBar):
                        w.setRange(0, 0)
                        w.setTextVisible(True)

                    setattr(self, obj_name, w)
                    loading_group_layout.addWidget(w)

                self.container_layout.addWidget(self.loading_group)
                widget.layout().addWidget(self.container)
                self.loading_group.hide()

                # Evento resize personalizado
                self.widget_center.resizeEvent = self.resize_event_custom

            # === Zona widget_down ===
            elif object_name == 'widget_down':
                self.btn_settings = QPushButton('Settings')
                self.btn_settings.setObjectName('button_settings')
                self.btn_settings.setFixedWidth(80)
                self.btn_settings.clicked.connect(self.settings)
                widget.layout().addWidget(self.btn_settings)

                spacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
                widget.layout().addItem(spacer)

                for btn_name, text, func, width in [
                    ('button_back', 'Back', self.go_back, 40),
                    ('button_next', 'Next', self.go_next, 40)
                ]:
                    btn = QPushButton(text)
                    btn.setObjectName(btn_name)
                    btn.setFixedWidth(width)
                    btn.clicked.connect(func)
                    setattr(self, btn_name, btn)
                    widget.layout().addWidget(btn)
                self.button_back.hide()
                self.button_next.hide()


        self.setLayout(layout)

    def settings(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageWebsites"])
    def go_next(self):
        pass
    def go_back(self):
        pass
    def show_balance(self):
        try:
            out = subprocess.run(
                ["ardrive", "get-balance", "-w", f".config_app/profiles/{BasePage.profile_selected}/wallet_{BasePage.profile_selected}.json"],
                capture_output=True, text=True, check=True, timeout=5
            ).stdout.strip().splitlines()
            lines = [" ".join(line.split()) for line in out if line.strip()]
            text = " // ".join(lines) if len(lines) == 2 else "Invalid balance format"
        except Exception:
            text = "Error getting balance"
        self.label_balance.setText(f"Balance: {text}")

    def resize_event_custom(self, event):
        self.container.setFixedWidth(int(self.widget_center.width() * self.container_width_percentage))
        self.container.setFixedHeight(self.widget_center.height())
        QWidget.resizeEvent(self.widget_center, event)

    def showEvent(self, event):
        super().showEvent(event)
        self.show_balance()
        print('Refresh balance')

class PageImportWallet(BasePage):
    def __init__(self, stacked_widget):
        super().__init__(stacked_widget, 0.6, QVBoxLayout)
        self.label_balance.hide()

        for object_name, widget_type, height, text, action in [
            ('label_select', QLabel, 60,
             "Eternal Legacy allows you to create or import an Arweave wallet for your website.\n"
             "How would you like to proceed?", None),
            ('button_create', QPushButton, 40, "Create Arweave Wallet", self.create_wallet),
            ('button_import', QPushButton, 40, "Import Arweave Wallet", self.import_wallet),
        ]:
            widget = widget_type(text)
            widget.setObjectName(object_name)
            widget.setFixedHeight(height)
            widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)

            if widget_type == QLabel:
                widget.setAlignment(Qt.AlignmentFlag.AlignCenter)

            if widget_type == QPushButton and action:
                widget.clicked.connect(action)

            setattr(self, object_name, widget)
            self.container_layout.addWidget(widget)

        self.widget_center.layout().setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.widget_center.layout().addWidget(self.container)

    def create_wallet(self):
        for i in reversed(range(self.container_layout.count())):
            widget = self.container_layout.itemAt(i).widget()
            if widget:
                widget.hide()
        self.loading_group.show()
        self.label_loading.setText("Creating wallet...")

        self.worker = WorkerThread('create_wallet', BasePage.profile_selected)
        self.worker.result.connect(self.verify_worker)
        self.worker.start()

    def import_wallet(self):
        base_dir = f".config_app/profiles/{BasePage.profile_selected}/"
        destino = os.path.join(base_dir, f"wallet_{BasePage.profile_selected}.json")

        def copiar_archivo(origen):
            if not os.path.isfile(origen):
                print("The selected file does not exist")
                return False
            os.makedirs(base_dir, exist_ok=True)
            shutil.copy(origen, destino)
            print(f"File copied as: {destino}")
            return True

        def verify_wallet():
            for i in reversed(range(self.container_layout.count())):
                widget = self.container_layout.itemAt(i).widget()
                if widget:
                    widget.hide()
            self.loading_group.show()
            self.label_loading.setText("Verifying wallet...")

            self.worker = WorkerThread('verify_wallet', BasePage.profile_selected)
            self.worker.result.connect(self.verify_worker)
            self.worker.start()

        file_dialog = QFileDialog(self)
        if file_dialog.exec():
            file_path = file_dialog.selectedFiles()[0]
            if copiar_archivo(file_path):
                verify_wallet()
        else:
            print("No file was selected")

    def verify_worker(self, success: bool):
        base_dir = f".config_app/profiles/{BasePage.profile_selected}/"
        destino = os.path.join(base_dir, f"wallet_{BasePage.profile_selected}.json")
        
        if success:
            print("Wallet verified successfully")
            self.go_next()
        else:
            if os.path.isfile(destino):
                os.remove(destino)
                print(f"Wallet not verified, file {destino} removed.")
            else:
                print(f"The file {destino} does not exist to be removed.")
            
            self.loading_group.hide()

            for i in reversed(range(self.container_layout.count())):
                widget = self.container_layout.itemAt(i).widget()
                if widget and widget is not self.loading_group:
                    widget.show()

            if success:
                print("Wallet verified successfully")
                self.go_next()
            else:
                if os.path.isfile(destino):
                    os.remove(destino)
                    print(f"Wallet not verified, file {destino} removed.")
                else:
                    print(f"The file {destino} does not exist to be removed.")

    def go_next(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageWebsites"])

class PageWebsites(BasePage):
    def __init__(self, stacked_widget):
        super().__init__(stacked_widget, 0.6, QVBoxLayout)
        self.button_back.show()
        for object_name, widget_type, height, text, action in [
            ('label_select', QLabel, 60, "What would you like to do?", None),
            ('button_edit', QPushButton, 40, "View or Edit Website", self.edit_website),
            ('button_new_website', QPushButton, 40, "Create New Website", self.new_website),
        ]:
            widget = widget_type(text)
            widget.setObjectName(object_name)
            widget.setFixedHeight(height)
            widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)

            if widget_type == QLabel:
                widget.setAlignment(Qt.AlignmentFlag.AlignCenter)

            if widget_type == QPushButton and action:
                widget.clicked.connect(action)

            setattr(self, object_name, widget)
            self.container_layout.addWidget(widget)

        self.widget_center.layout().setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.widget_center.layout().addWidget(self.container)

    def edit_website(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageWebsitesEditor"])

    def new_website(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageTemplates"])

    def go_back(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageImportWallet"])

class PageTemplates(BasePage):
    def __init__(self, stacked_widget):
        super().__init__(stacked_widget, 0.98, QHBoxLayout)
        self.button_back.show()
        self.container_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.container_layout.setContentsMargins(0, 0, 0, 0)

    def showEvent(self, event):
        super().showEvent(event)
        if not hasattr(self, "widget_rotary"):
            self.build_template_view()

    def build_template_view(self):
        if hasattr(self, "widget_rotary"):
            self.container_layout.removeWidget(self.button_before)
            self.container_layout.removeWidget(self.widget_rotary)
            self.container_layout.removeWidget(self.button_after)
            self.widget_rotary.deleteLater()
            self.button_before.deleteLater()
            self.button_after.deleteLater()
            del self.widget_rotary, self.button_before, self.button_after
            self.elements.clear()

        for name, widget_type, text, callback in [
            ("button_before", QPushButton, "◀", self.go_before),
            ("widget_rotary", QWidget, None, ""),
            ("button_after", QPushButton, "▶", self.go_after),
        ]:
            widget = widget_type(text) if text else widget_type()
            widget.setObjectName(name)
            if isinstance(widget, QPushButton):
                widget.setFixedSize(40, 40)
                widget.clicked.connect(callback)
                widget.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
                setattr(self, name, widget)
            else:
                widget.setContentsMargins(0, 0, 0, 0)
                self.widget_rotary_layout = QStackedLayout(widget)
                self.widget_rotary_layout.setContentsMargins(0, 0, 0, 0)
                self.widget_rotary_layout.setSpacing(0)
                widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
                self.widget_rotary = widget

        self.elements = []
        self.current_index = 0
        template_dir = ".config_app/templates"
        if os.path.exists(template_dir):
            for folder_name in os.listdir(template_dir):
                folder_path = os.path.join(template_dir, folder_name)
                if os.path.isdir(folder_path):
                    for file_name in os.listdir(folder_path):
                        if file_name.lower().endswith(".png"):
                            label = QLabel()
                            label.setAlignment(Qt.AlignmentFlag.AlignCenter)
                            label.setStyleSheet("background-color: transparent;")
                            label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
                            label.setPixmap(QPixmap(os.path.join(folder_path, file_name)))
                            label.setScaledContents(True)
                            self.elements.append((folder_name, label))

        self.template_button = QPushButton("Import your template")
        self.template_button.clicked.connect(self.open_zip)
        self.template_button.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        self.elements.append(self.template_button)

        for element in self.elements:
            widget = element if isinstance(element, QPushButton) else element[1]
            self.widget_rotary_layout.addWidget(widget)

        self.widget_rotary_layout.setCurrentIndex(self.current_index)
        self.container_layout.addWidget(self.button_before)
        self.container_layout.addWidget(self.widget_rotary)
        self.container_layout.addWidget(self.button_after)

        layout = self.widget_center.layout()
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(self.container)

        self._update_next_button_visibility()

    def _update_next_button_visibility(self):
        current_element = self.elements[self.current_index]
        if isinstance(current_element, tuple):
            self.button_next.show()
        else:
            self.button_next.hide()

    def go_before(self):
        self.current_index = (self.current_index - 1) % len(self.elements)
        self.widget_rotary_layout.setCurrentIndex(self.current_index)
        self._update_next_button_visibility()

    def go_after(self):
        self.current_index = (self.current_index + 1) % len(self.elements)
        self.widget_rotary_layout.setCurrentIndex(self.current_index)
        self._update_next_button_visibility()

    def open_zip(self):
        try:
            base_path = os.path.dirname(os.path.abspath(__file__))
            zip_script_path = os.path.join(base_path, ".config_app", "code", "open_zip.py")
            print(f"Buscando script en: {zip_script_path}")

            if os.path.exists(zip_script_path):
                print(f"Script encontrado en: {zip_script_path}")
                
                name = os.path.splitext(os.path.basename(zip_script_path))[0]
                print(f"Nombre del módulo: {name}")

                # Cargar el módulo dinámicamente
                spec = importlib.util.spec_from_file_location(name, zip_script_path)
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)
                print("Módulo cargado correctamente.")

                # Verificar si la función 'open_zip' está en el módulo
                if hasattr(module, 'open_zip'):
                    print("Función 'open_zip' encontrada en el módulo.")
                    result = module.open_zip()
                    if result:
                        print("Template imported successfully.")
                        self.build_template_view()
                    else:
                        print("Failed to import template.")
                else:
                    print(f"'open_zip' function not found in {zip_script_path}")
            else:
                print(f"{zip_script_path} no encontrado.")
        except Exception as e:
            print(f"Error loading {zip_script_path}: {e}")
    def go_next(self):
        try:
            item = self.elements[self.current_index]
            if isinstance(item, QPushButton):
                raise Exception
            BasePage.template_selected = item[0]
            print(f"Template selected: {BasePage.template_selected}")
            self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageCreateWebsite"])
        except Exception:
            QMessageBox.warning(self, "Warning", "Please select or import a template first.")
    def go_back(self):
            self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageWebsites"])

class PageCreateWebsite(BasePage):
    def __init__(self, stacked_widget):
        super().__init__(stacked_widget, 0.98, QHBoxLayout)
        self.button_back.show()
        self._last_template_loaded = None
        self.conclave = {}
        self.hugo_memory = {}

        for object_name in [("widget_left"), ("widget_right")]:
            widget = QWidget()
            widget.setObjectName(object_name)
            widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
            layout = QVBoxLayout(widget)
            layout.setContentsMargins(0, 0, 0, 0)
            setattr(self, object_name, widget)
            setattr(self, f"{object_name}_layout", layout)
            self.container_layout.addWidget(widget, 1)

        for object_name, widget_type, text, action, height in [
            ("label_website", QLabel, "General website config", None, 30),
            ("line_project", QLineEdit, "Project Name", None, 30),
            ("line_website_name", QLineEdit, "Website Name", None, 30),
            ("plain_website_description", QPlainTextEdit, "Website Description", None, 65),
            ("plain_website_seo", QPlainTextEdit, "Website Seo (separated with commas)", None, 65),
            ("button_favicon", QPushButton, "Select Favicon", self.favicon, 30)
        ]:
            widget = widget_type()
            widget.setObjectName(object_name)
            widget.setFixedHeight(height)

            if isinstance(widget, (QLabel, QPushButton)):
                widget.setText(text)

            if isinstance(widget, QPushButton) and action:
                widget.clicked.connect(action)
                self.conclave[object_name] = False

            if isinstance(widget, (QLineEdit, QPlainTextEdit)):
                widget.setPlaceholderText(text)
                widget.textChanged.connect(self.check_conclave)
                self.conclave[object_name] = False

            self.widget_left_layout.addWidget(widget)

        for icon_name, placeholder in [
            ("footer_nostr", "Nostr link"),
            ("footer_bastyon", "Bastyon link"),
            ("footer_session", "Session link"),
            ("footer_signal", "Signal link")
        ]:
            widget = QWidget()
            widget.setObjectName(f"widget_footer_{icon_name}")
            widget.setFixedHeight(30)
            widget.setLayout(QHBoxLayout())
            widget.layout().setContentsMargins(0, 0, 0, 0)
            widget.setStyleSheet("background-color: white; border: 0px; margin: 0px;")

            label = QLabel()
            label.setFixedSize(30, 30)
            label.setPixmap(QPixmap(f".config_app/images/{icon_name}.svg"))
            label.setScaledContents(True)
            line_edit = QLineEdit()
            line_edit.setFixedHeight(30)

            line_edit.setPlaceholderText(placeholder)
            line_edit.setObjectName(icon_name)  # Añadido aquí

            widget.layout().addWidget(label)
            widget.setFixedHeight(30)
            widget.layout().addWidget(line_edit)

            self.widget_left_layout.addWidget(widget)

        self.widget_center.layout().setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.widget_center.layout().addWidget(self.container)

    def showEvent(self, event):
        super().showEvent(event)
        print(f"Layout is: {BasePage.template_selected}")
        self.reset_widgets()


        if self._last_template_loaded == BasePage.template_selected:
            print("La plantilla ya fue cargada anteriormente, omitiendo carga de widgets.")
            return
        for i in reversed(range(self.widget_right_layout.count())):
            widget = self.widget_right_layout.itemAt(i).widget()
            if widget:
                widget.setParent(None)  

        self._last_template_loaded = BasePage.template_selected 
        template_dir = f".config_app/templates/{BasePage.template_selected}/"

        # Limpiar widgets anteriores
        for i in reversed(range(self.widget_right_layout.count())):
            widget = self.widget_right_layout.itemAt(i).widget()
            if widget:
                widget.setParent(None)

        self._last_template_loaded = BasePage.template_selected

        # Ruta del template seleccionado
        template_dir = f".config_app/templates/{BasePage.template_selected}/"
        print(f"Buscando archivos en: {template_dir}")

        # Buscar y cargar el .py
        for file_path in glob.glob(f"{template_dir}*.py"):
            print(f"Encontrado archivo Python: {file_path}")
            try:
                name = os.path.splitext(os.path.basename(file_path))[0]
                spec = importlib.util.spec_from_file_location(name, file_path)
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)

                if hasattr(module, 'add_right_widgets'):
                    print(f"Llamando a add_right_widgets desde {file_path}")
                    module.add_right_widgets(self)
                else:
                    print(f"'add_right_widgets' no encontrado en {file_path}")

            except Exception as e:
                print(f"Error cargando {file_path} → {e}")
        template_dir = f".config_app/templates/{BasePage.template_selected}/"

        # Buscar y cargar archivos .css
        css_files = glob.glob(os.path.join(template_dir, "*.css"))

        if css_files:
            css_path = css_files[0]
            print(f"Hoja de estilo encontrada: {css_path}")
            try:
                with open(css_path, "r", encoding="utf-8") as f:
                    self.setStyleSheet(f.read())
                    print(f"Estilo aplicado desde: {css_path}")
            except Exception as e:
                print(f"Error al cargar el estilo desde {css_path} → {e}")
        else:
            print(f"No se encontró ningún archivo .css en: {template_dir}")


    def reset_widgets(self):
        for container in [self.widget_left, self.widget_right]:
            for widget in container.findChildren(QWidget):
                if isinstance(widget, QLineEdit):
                    widget.clear()
                elif isinstance(widget, QPlainTextEdit):
                    widget.setPlainText("")
                elif isinstance(widget, QPushButton):
                    widget.setStyleSheet("")  # Restablecer estilos de botones
                elif widget.objectName().startswith("widget_footer_"):
                    line_edit = widget.findChild(QLineEdit)
                    if line_edit:
                        line_edit.clear()
                widget.setStyleSheet("")  # Restablecer estilos generales

    def favicon(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "Select a Favicon (.ico)",
            "",
            "Icon files (*.ico)"
        )
        if file_path:
            self.hugo_memory['favicon'] = file_path
            self.conclave['button_favicon'] = True
            button = self.findChild(QPushButton, "button_favicon")
            if button:
                button.setStyleSheet("background-color: #4CAF50; color: white;")
                print(self.hugo_memory)
        else:
            self.conclave['button_favicon'] = False
            button = self.findChild(QPushButton, "button_favicon")
            if button:
                button.setStyleSheet("")
        self.check_conclave()

    def check_conclave(self):
        all_completed = True

        for object_name in self.conclave.keys():
            widget = self.findChild(QWidget, object_name)
            if isinstance(widget, (QLineEdit, QPlainTextEdit)):
                text = widget.toPlainText() if isinstance(widget, QPlainTextEdit) else widget.text()
                self.conclave[object_name] = bool(text.strip())

            if not self.conclave[object_name]:
                all_completed = False

        if all_completed:
            self.button_next.show() 
        else:
            self.button_next.hide()
            pass

    def go_next(self):
        for widget in self.findChildren((QLineEdit, QPlainTextEdit)):
            name = widget.objectName()
            if not name:
                parent = widget.parent()
                if parent and parent.objectName().startswith("widget_footer_"):
                    name = parent.objectName().replace("widget_footer_", "")
                else:
                    continue
            text = widget.text().strip() if isinstance(widget, QLineEdit) else widget.toPlainText().strip()
            self.hugo_memory[name] = text
        if "line_project" in self.hugo_memory:
            BasePage.project_selected = self.hugo_memory["line_project"]
        for i in reversed(range(self.container_layout.count())):
            widget = self.container_layout.itemAt(i).widget()
            if widget:
                widget.hide()

        self.loading_group.show()
        self.label_loading.setText("Creating website...")
        self.hugo_memory = {k: v for k, v in self.hugo_memory.items() if not (k.startswith("footer_") and not v.strip())}

        self.worker = WorkerThread('create_website', BasePage.profile_selected, self.hugo_memory, BasePage.template_selected, BasePage.project_selected)
        self.worker.result.connect(self.veify_worker)
        self.worker.start()
    def veify_worker(self, result):
        if result:
            print("Next steps")
            for i in reversed(range(self.container_layout.count())):
                widget = self.container_layout.itemAt(i).widget()
                if widget:
                    widget.show()

            self.loading_group.hide()
            self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PagePublic"])
        else:
            print("Error: no se pudo crear el sitio.")
            QMessageBox.warning(self, "Warning", "Please select or import a template first.")
            for i in reversed(range(self.container_layout.count())):
                widget = self.container_layout.itemAt(i).widget()
                if widget:
                    widget.show()

            self.loading_group.hide()
    def go_back(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageTemplates"])

class PagePublic(BasePage):
    def __init__(self, stacked_widget):
        super().__init__(stacked_widget, 0.6, QVBoxLayout)

        for object_name, widget_type, height, text, action in [
            ('label_select', QLabel, 60,
             "Your website has been successfully generated. What would you like to do?", None),
            ('button_edit_website', QPushButton, 40, "Edit Website", self.edit_website),
            ('button_view_website', QPushButton, 40, "View Website", self.view_website),
            ('button_public_website', QPushButton, 40, "Public Website on arweave", self.public_website)
        ]:
            widget = widget_type(text)
            widget.setObjectName(object_name)
            widget.setFixedHeight(height)
            widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)

            if widget_type == QLabel:
                widget.setAlignment(Qt.AlignmentFlag.AlignCenter)

            if widget_type == QPushButton and action:
                widget.clicked.connect(action)

            setattr(self, object_name, widget)
            self.container_layout.addWidget(widget)

        self.widget_center.layout().setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.widget_center.layout().addWidget(self.container)

        self._worker_key = 'public_arweave'  # default fallback

    def showEvent(self, event):
        super().showEvent(event)
        manifest_path = os.path.abspath(
            f".config_app/profiles/{BasePage.profile_selected}/{BasePage.project_selected}/manifest.json"
        )

        if os.path.isfile(manifest_path):
            self.label_loading.setText("Refresh Website on arweave...")
            print("refreesh on arweave")
            self._worker_key = 'refresh_arweave'
        else:
            self.label_loading.setText("Upload Website on arweave...")
            self._worker_key = 'public_arweave'
            print("refreesh on arweave")


    def edit_website(self):
        p = os.path.abspath(f".config_app/profiles/{BasePage.profile_selected}/{BasePage.project_selected}")
        if os.path.exists(p):
            if sys.platform == "win32":
                os.startfile(p)
            else:
                subprocess.run(["open" if sys.platform == "darwin" else "xdg-open", p])

    def view_website(self):
        index_path = f".config_app/profiles/{BasePage.profile_selected}/{BasePage.project_selected}/public/index.html"
        absolute_path = os.path.abspath(index_path)
        if os.path.exists(absolute_path):
            webbrowser.open(f"file://{absolute_path}")

    def public_website(self):
        for i in reversed(range(self.container_layout.count())):
            widget = self.container_layout.itemAt(i).widget()
            if widget:
                widget.hide()
        self.loading_group.show()

        self.worker = WorkerThread(
            key=self._worker_key,
            profile_selected=BasePage.profile_selected,
            project_selected=BasePage.project_selected
        )
        self.worker.result.connect(self.go_next)
        self.worker.start()
        
    def go_next(self, result):
        for i in reversed(range(self.container_layout.count())):
            widget = self.container_layout.itemAt(i).widget()
            if widget:
                widget.show()
            
        self.loading_group.hide()  
        if result:
            manifest_path = os.path.join(
                ".config_app", "profiles",
                BasePage.profile_selected,
                BasePage.project_selected,
                "manifest.json"
            )

            if os.path.exists(manifest_path):
                with open(manifest_path, "r", encoding="utf-8") as file:
                    data = json.load(file)
                    created = data.get("created", [])
                    if created and "dataTxId" in created[0]:
                        data_tx_id = created[0]["dataTxId"]
                        webbrowser.open(f"https://arweave.net/{data_tx_id}")

            self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageWebsites"])
        else:
            QMessageBox.critical(self, "Error", "La publicación en Arweave falló. Revisa tu conexión, claves o drive.")

    def go_back(self):
            self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageTemplates"])

class PageWebsitesEditor(BasePage):#reformular toda la pagina en aras de que muestre en nombre
    def __init__(self, stacked_widget):
        super().__init__(stacked_widget, 0.98, QHBoxLayout)
        self.button_back.show()
        self.container_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.container_layout.setContentsMargins(0, 0, 0, 0)
        self.current_index = 0

    def showEvent(self, event):
        super().showEvent(event)

        while self.container_layout.count():
            item = self.container_layout.takeAt(0)
            widget = item.widget()
            if widget:
                widget.deleteLater()

        profile_path = os.path.join(".config_app", "profiles", BasePage.profile_selected)
        self.proyectos = {}

        if os.path.exists(profile_path):
            for project_name in os.listdir(profile_path):
                project_path = os.path.join(profile_path, project_name)
                if os.path.isdir(project_path):
                    themes_path = os.path.join(project_path, "themes")
                    plantilla = None
                    if os.path.exists(themes_path):
                        template_folders = [
                            f for f in os.listdir(themes_path)
                            if os.path.isdir(os.path.join(themes_path, f))
                        ]
                        if template_folders:
                            plantilla = template_folders[0]
                    self.proyectos[project_name] = plantilla

        if not self.proyectos:
            label = QLabel("No websites yet")
            label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            self.container_layout.addWidget(label)
        else:
            self.create_structure()



    def create_structure(self):
        self.button_next.show()


        # Botón anterior
        self.button_before = QPushButton("◀")
        self.button_before.setFixedSize(40, 40)
        self.button_before.clicked.connect(self.go_before)
        self.button_before.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
        self.container_layout.addWidget(self.button_before)

        # Contenedor central con QStackedLayout
        self.widget_rotary = QLabel()
        self.widget_rotary.setContentsMargins(0, 0, 0, 0)
        self.widget_rotary_layout = QStackedLayout(self.widget_rotary)
        self.widget_rotary_layout.setContentsMargins(0, 0, 0, 0)
        self.widget_rotary_layout.setSpacing(0)
        self.widget_rotary.setStyleSheet("background-color: black;")

        self.widget_rotary.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        self.container_layout.addWidget(self.widget_rotary)

        self.images = []  # Almacenaremos las imágenes aquí

        # Cargar imágenes según plantilla
        for project_name, plantilla in self.proyectos.items():
            plantilla_dir = os.path.join(".config_app", "templates", plantilla)
            image_path = None


            # Imprimir la ruta donde se está buscando la imagen
            print(f"Buscando imágenes en: {plantilla_dir}")

            # Buscar cualquier archivo de imagen en la carpeta de la plantilla
            if os.path.exists(plantilla_dir):
                for f in os.listdir(plantilla_dir):
                    if f.lower().endswith((".png", ".jpg", ".jpeg", ".gif")):
                        image_path = os.path.join(plantilla_dir, f)
                        print(f"Imagen encontrada: {image_path}")
                        break  # Solo tomamos la primera imagen válida

            # Crear el QLabel y cargar la imagen
            image_label = QLabel()
            image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
            
            # Establecer fondo transparente y expandir el QLabel
            image_label.setStyleSheet("background-color: transparent;")
            image_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
            image_label.setScaledContents(True)  # Asegurar que la imagen se escale al tamaño del QLabel

            if image_path and os.path.exists(image_path):
                # Establecer la imagen en el QLabel
                image_label.setPixmap(QPixmap(image_path))
            else:
                image_label.setText(f"No image for '{plantilla}'")

            # Añadir la imagen al layout y almacenarla para control
            self.widget_rotary_layout.addWidget(image_label)
            self.images.append((project_name, image_label))  # Guardar el proyecto y su imagen
            self.label_balance.setText(project_name)

        # Botón siguiente
        self.button_after = QPushButton("▶")
        self.button_after.setFixedSize(40, 40)
        self.button_after.clicked.connect(self.go_after)  # Usamos go_next para guardar el nombre del proyecto
        self.button_after.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
        self.container_layout.addWidget(self.button_after)

        self.current_index = 0  # Empezamos con la primera imagen
        self.widget_rotary_layout.setCurrentIndex(self.current_index)

    def go_next(self):
        # Ahora guardamos BasePage.project_selected como el nombre del proyecto de la imagen que esté viéndose
        selected_project = self.images[self.current_index][0]  # Nombre del proyecto
        BasePage.project_selected = selected_project
        print(f"Proyecto seleccionado: {selected_project}")

        # Guardar también la plantilla seleccionada
        plantilla = self.proyectos[selected_project]  # Obtener la plantilla del proyecto
        BasePage.template_selected = plantilla  # Guardar la plantilla seleccionada
        print(f"Plantilla seleccionada: {plantilla}")
        print(BasePage.project_selected)


        # Opcional: Cambiar a la página de edición, sin modificar la imagen
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageEditWebsite"])

    def go_back(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageWebsites"])

    def go_before(self):
        if self.widget_rotary_layout.count() > 0:
            self.current_index = (self.current_index - 1) % self.widget_rotary_layout.count()
            self.widget_rotary_layout.setCurrentIndex(self.current_index)

            project_name = self.images[self.current_index][0]
            plantilla = self.proyectos[project_name]
            print(f"[◀ Anterior] Proyecto: {project_name} | Plantilla: {plantilla}")
            self.label_balance.setText(project_name)


    def go_after(self):
        if self.widget_rotary_layout.count() > 0:
            self.current_index = (self.current_index + 1) % self.widget_rotary_layout.count()
            self.widget_rotary_layout.setCurrentIndex(self.current_index)

            project_name = self.images[self.current_index][0]
            plantilla = self.proyectos[project_name]
            print(f"[▶ Siguiente] Proyecto: {project_name} | Plantilla: {plantilla}")
            self.label_balance.setText(project_name)


class PageEditWebsite(BasePage):
    def __init__(self, stacked_widget):
        super().__init__(stacked_widget, 0.98, QHBoxLayout)

        self.button_back.show()
        self._last_template_loaded = None
        self.conclave = {}
        self.hugo_memory = {}


        for object_name in [("widget_left"), ("widget_right")]:
            widget = QWidget()
            widget.setObjectName(object_name)
            widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
            layout = QVBoxLayout(widget)
            layout.setContentsMargins(0, 0, 0, 0)
            setattr(self, object_name, widget)
            setattr(self, f"{object_name}_layout", layout)
            self.container_layout.addWidget(widget, 1)

        for object_name, widget_type, text, action, height in [
            ("label_website", QLabel, "General website config", None, 30),
            ("button_open_website", QPushButton, "Open website in browser", self.open_website, 30),
            ("button_edit_website", QPushButton, "Edit manually website (public folder)", self.edit, 30),
            ("button_view_manifest", QPushButton, "View manifest", self.view_manifest, 30),
            ("label_qr", QLabel, "", None, 80),
            ("phantom", QLabel, None, None, 30),
            ("phantom", QLabel, None, None, 80),
            ("phantom", QLabel, None, None, 30),
            ("phantom", QLabel, None, None, 30)

        ]:
            widget = widget_type()
            widget.setObjectName(object_name)
            widget.setFixedHeight(height)

            if isinstance(widget, (QLabel, QPushButton)):
                widget.setText(text)

            if isinstance(widget, QPushButton) and action:
                widget.clicked.connect(action)

            self.widget_left_layout.addWidget(widget)

        self.widget_center.layout().setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.widget_center.layout().addWidget(self.container)

    def showEvent(self, event):
        super().showEvent(event)
        print(BasePage.project_selected)
        print(f"Layout is: {BasePage.template_selected}")
        self.reset_widgets()

        if self._last_template_loaded == BasePage.template_selected:
            print("La plantilla ya fue cargada anteriormente, omitiendo carga de widgets.")
            return
        for i in reversed(range(self.widget_right_layout.count())):
            widget = self.widget_right_layout.itemAt(i).widget()
            if widget:
                widget.setParent(None)  
        self._last_template_loaded = BasePage.template_selected 

        template_dir = f".config_app/templates/{BasePage.template_selected}/"
        for file_path in glob.glob(f"{template_dir}*.py"):
            try:
                name = os.path.splitext(os.path.basename(file_path))[0]
                spec = importlib.util.spec_from_file_location(name, file_path)
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)

                if hasattr(module, 'add_right_widgets'):
                    print(f"Cargando: {file_path}")
                    module.add_right_widgets(self)

            except Exception as e:
                print(f"Error en {file_path} → {e}")
        template_dir = f".config_app/templates/{BasePage.template_selected}/"

        # Buscar y cargar archivos .css
        css_files = glob.glob(os.path.join(template_dir, "*.css"))

        if css_files:
            css_path = css_files[0]
            print(f"Hoja de estilo encontrada: {css_path}")
            try:
                with open(css_path, "r", encoding="utf-8") as f:
                    self.setStyleSheet(f.read())
                    print(f"Estilo aplicado desde: {css_path}")
            except Exception as e:
                print(f"Error al cargar el estilo desde {css_path} → {e}")
        else:
            print(f"No se encontró ningún archivo .css en: {template_dir}")
    def reset_widgets(self):
        for container in [self.widget_left, self.widget_right]:
            for widget in container.findChildren(QWidget):
                if isinstance(widget, QLineEdit):
                    widget.clear()
                elif isinstance(widget, QPlainTextEdit):
                    widget.setPlainText("")
                elif isinstance(widget, QPushButton):
                    widget.setStyleSheet("")  # Restablecer estilos de botones
                elif widget.objectName().startswith("widget_footer_"):
                    line_edit = widget.findChild(QLineEdit)
                    if line_edit:
                        line_edit.clear()
                widget.setStyleSheet("")  # Restablecer estilos generales

    def reset_left_widgets(self):
        for widget in self.widget_left.findChildren(QWidget):
            if isinstance(widget, QLineEdit):
                widget.clear()
            elif isinstance(widget, QPlainTextEdit):
                widget.setPlainText("")
            elif isinstance(widget, QPushButton):
                widget.setStyleSheet("")  # Restablecer estilos de botones
            elif widget.objectName().startswith("widget_footer_"):
                line_edit = widget.findChild(QLineEdit)
                if line_edit:
                    line_edit.clear()
            widget.setStyleSheet("")  # Restablecer estilos generales

    def view_manifest(self):
        manifest_path = os.path.join(
            ".config_app", "profiles",
            BasePage.profile_selected,
            BasePage.project_selected,
            "manifest.json"
        )
        if os.path.exists(manifest_path):
            webbrowser.open(f"file://{os.path.abspath(manifest_path)}")
    def open_website(self):

        manifest_path = os.path.join(
            ".config_app", "profiles",
            BasePage.profile_selected,
            BasePage.project_selected,
            "manifest.json"
        )

        if os.path.exists(manifest_path):
            with open(manifest_path, "r", encoding="utf-8") as file:
                data = json.load(file)
                created = data.get("created", [])
                if created and "dataTxId" in created[0]:
                    data_tx_id = created[0]["dataTxId"]
                    webbrowser.open(f"https://arweave.net/{data_tx_id}")

    def edit(self):
        import os, subprocess, sys

        manifest_path = os.path.join(
            ".config_app", "profiles",
            BasePage.profile_selected,
            BasePage.project_selected
        )

        if os.path.exists(manifest_path):
            if sys.platform.startswith('darwin'):
                subprocess.Popen(['open', manifest_path])
            elif os.name == 'nt':
                os.startfile(manifest_path)
            elif os.name == 'posix':
                subprocess.Popen(['xdg-open', manifest_path])

    def check_conclave(self):
        all_completed = True

        for object_name in self.conclave.keys():
            widget = self.findChild(QWidget, object_name)
            if isinstance(widget, (QLineEdit, QPlainTextEdit)):
                text = widget.toPlainText() if isinstance(widget, QPlainTextEdit) else widget.text()
                self.conclave[object_name] = bool(text.strip())

            if not self.conclave[object_name]:
                all_completed = False

        if all_completed:
            self.button_next.show() 
        else:
            self.button_next.hide()
            pass

    def go_next(self):

        for widget in self.findChildren((QLineEdit, QPlainTextEdit)):
            name = widget.objectName()
            if not name:
                parent = widget.parent()
                if parent and parent.objectName().startswith("widget_footer_"):
                    name = parent.objectName().replace("widget_footer_", "")
                else:
                    continue
            text = widget.text().strip() if isinstance(widget, QLineEdit) else widget.toPlainText().strip()
            self.hugo_memory[name] = text
        if "line_project" in self.hugo_memory:
            BasePage.project_selected = self.hugo_memory["line_project"]
        for i in reversed(range(self.container_layout.count())):
            widget = self.container_layout.itemAt(i).widget()
            if widget:
                widget.hide()

        self.loading_group.show()
        self.label_loading.setText("edit website...")
        self.hugo_memory = {k: v for k, v in self.hugo_memory.items() if not (k.startswith("footer_") and not v.strip())}

        self.worker = WorkerThread('edit_website', BasePage.profile_selected, self.hugo_memory, BasePage.template_selected, BasePage.project_selected)
        self.worker.result.connect(self.veify_worker)
        self.worker.start()
    def veify_worker(self, result):
        if result:
            print("Next steps")
            for i in reversed(range(self.container_layout.count())):
                widget = self.container_layout.itemAt(i).widget()
                if widget:
                    widget.show()

            self.loading_group.hide()
            self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PagePublic"])
        else:
            print("Error: no se pudo crear el sitio.")
            QMessageBox.warning(self, "Warning", "Please select or import a template first.")
            for i in reversed(range(self.container_layout.count())):
                widget = self.container_layout.itemAt(i).widget()
                if widget:
                    widget.show()

            self.loading_group.hide()
    def go_back(self):
        self.stacked_widget.setCurrentWidget(self.stacked_widget.parent().pages["PageTemplates"])

        
if __name__ == "__main__":
    app = QApplication([])
    ventana = MiVentana()
    ventana.show()
    app.exec()
