import tkinter as tk
import customtkinter as ctk
import os, requests, json, re
from threading import Thread
from tkinter import messagebox
from datetime import datetime

ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("blue")

class CalizEstetico(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("Crisóstomo v7.0 - Versión Corregida")
        self.geometry("1250x980")
        
        # Credenciales y Configuración
        self.api_key_gemini = "AIzaSyD-qYh_vR_LpBq0xX_4pY8xW_Zq1s2t3u" 
        self.url_ollama = "http://localhost:11434/api/generate"
        self.modelo_ollama = "llama3:latest"
        self.lista_paginas = []
        
        self.setup_ui()

    def setup_ui(self):
        self.grid_columnconfigure(1, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Barra Lateral
        self.sidebar = ctk.CTkFrame(self, width=260, fg_color="#1a1a2e")
        self.sidebar.grid(row=0, column=0, sticky="nsew")
        ctk.CTkLabel(self.sidebar, text="CÁLIZ\nESTÉTICO", font=("Serif", 24, "bold"), text_color="#9575CD").pack(pady=40)
        
        self.btn_fiat = ctk.CTkButton(self.sidebar, text="FIAT LUX", fg_color="#7B1FA2", height=45, command=self.iniciar_hilo)
        self.btn_fiat.pack(pady=10, padx=20)

        self.btn_wp = ctk.CTkButton(self.sidebar, text="EXPORTAR A WP", fg_color="#217346", height=45, command=self.exportar_wordpress)
        self.btn_wp.pack(pady=10, padx=20)
        
        self.prog_label = ctk.CTkLabel(self.sidebar, text="Esperando instrucciones...", font=("Arial", 11))
        self.prog_label.pack(side="bottom", pady=10)
        self.progress_bar = ctk.CTkProgressBar(self.sidebar, width=220); self.progress_bar.set(0)
        self.progress_bar.pack(side="bottom", pady=20)

        # Panel Principal
        self.main = ctk.CTkScrollableFrame(self, fg_color="#050510")
        self.main.grid(row=0, column=1, sticky="nsew")

        # 1. Prompt Maestro
        ctk.CTkLabel(self.main, text="1. PROMPT MAESTRO (Identidad):", font=("Arial", 12, "bold")).pack(pady=(10,5), padx=40, anchor="w")
        self.txt_maestro = ctk.CTkTextbox(self.main, height=120, width=850)
        self.txt_maestro.insert("0.0", "Actúa como Crisóstomo. Tono místico, solemne y protector. Prohibido datos personales.")
        self.txt_maestro.pack(padx=40, anchor="w")

        # 2. Estética Visual (CSS)
        ctk.CTkLabel(self.main, text="2. ESTÉTICA VISUAL (Colores, Estilo):", font=("Arial", 12, "bold"), text_color="#9575CD").pack(pady=(10,5), padx=40, anchor="w")
        self.txt_css_prompt = ctk.CTkTextbox(self.main, height=100, width=850, border_color="#9575CD", border_width=1)
        self.txt_css_prompt.insert("0.0", "Fondo negro profundo, textos en violeta suave y dorado. Estilo sacro-tecnológico.")
        self.txt_css_prompt.pack(padx=40, anchor="w")

        # 3. Nombre de la Sede
        ctk.CTkLabel(self.main, text="3. NOMBRE DE LA SEDE:").pack(pady=(10,5), padx=40, anchor="w")
        self.ent_nombre = ctk.CTkEntry(self.main, width=500); self.ent_nombre.pack(padx=40, anchor="w")

        # 4. Estructura Natural
        ctk.CTkLabel(self.main, text="4. ESTRUCTURA NATURAL:").pack(pady=(10,5), padx=40, anchor="w")
        self.txt_entrada = ctk.CTkTextbox(self.main, height=350, width=850); self.txt_entrada.pack(padx=40, anchor="w")

    def parsear_natural(self):
        """Función fundamental para leer la mente del Obispo y organizar las páginas"""
        self.lista_paginas = []
        texto = self.txt_entrada.get("1.0", "end")
        # Divide el texto buscando las palabras clave PÁGINA o BLOG
        bloques = re.split(r'(?i)(PÁGINA:|PAGINA:|BLOG:)', texto)
        
        for i in range(1, len(bloques), 2):
            tipo_header = bloques[i].upper()
            tipo = "page" if "PÁGINA" in tipo_header or "PAGINA" in tipo_header else "post"
            contenido = bloques[i+1]
            
            lineas = contenido.strip().split('\n')
            titulo = lineas[0].strip()
            
            padre = ""
            if "PADRE:" in contenido:
                padre = contenido.split("PADRE:")[1].split('\n')[0].strip()
                
            mision = ""
            if "MISIÓN:" in contenido:
                mision = contenido.split("MISIÓN:")[1].strip()
            elif "MISION:" in contenido:
                mision = contenido.split("MISION:")[1].strip()
            else:
                mision = "Desarrollar contenido místico y profundo."
                
            self.lista_paginas.append({
                "titulo": titulo, 
                "mision": mision, 
                "tipo": tipo, 
                "padre": padre, 
                "contenido_raw": ""
            })

    def consultar_gemini(self, prompt):
        url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key={self.api_key_gemini}"
        try:
            r = requests.post(url, json={"contents": [{"parts": [{"text": prompt}]}]}, timeout=60)
            return r.json()['candidates'][0]['content']['parts'][0]['text']
        except Exception as e:
            return f"/* Error en comunicación: {str(e)} */"

    def consultar_ollama(self, prompt):
        try:
            r = requests.post(self.url_ollama, json={"model": self.modelo_ollama, "prompt": prompt, "stream": False}, timeout=600)
            return r.json()['response']
        except:
            return "<p>Error al conectar con el servidor local de Ollama.</p>"

    def iniciar_hilo(self):
        self.parsear_natural()
        if not self.lista_paginas or not self.ent_nombre.get():
            messagebox.showerror("Error", "Por favor, rellene el nombre de la sede y la estructura.")
            return
        Thread(target=self.proceso_final, daemon=True).start()

    def proceso_final(self):
        self.btn_fiat.configure(state="disabled")
        p_maestro = self.txt_maestro.get("1.0", "end-1c")
        nombre_sede = self.ent_nombre.get().replace(' ','_').lower()
        ruta = f"sedes/{nombre_sede}"
        os.makedirs(ruta, exist_ok=True)

        # 1. Generar CSS
        self.prog_label.configure(text="Forjando Estética CSS...")
        prompt_css = f"Genera SOLO código CSS (sin texto extra) para: {self.txt_css_prompt.get('1.0', 'end')}. Incluye .sacred-title y .sacred-paragraph."
        css_code = self.consultar_gemini(prompt_css).replace("```css", "").replace("```", "").strip()
        with open(f"{ruta}/estilo.css", "w", encoding="utf-8") as f:
            f.write(css_code)

        # 2. Generar Páginas
        total = len(self.lista_paginas)
        for i, p in enumerate(self.lista_paginas):
            self.prog_label.configure(text=f"Generando: {p['titulo']}...")
            investigacion = self.consultar_gemini(f"Proporciona datos para: {p['mision']}")
            
            prompt_final = f"{p_maestro}\n\nDATOS INVESTIGADOS: {investigacion}\nTAREA: Escribe '{p['titulo']}' (Misión: {p['mision']}). Usa HTML con clases 'sacred-title' y 'sacred-paragraph'. 1000 palabras."
            
            p['contenido_raw'] = self.consultar_ollama(prompt_final)
            
            full_html = f"<!DOCTYPE html><html><head><meta charset='UTF-8'><link rel='stylesheet' href='estilo.css'><title>{p['titulo']}</title></head><body class='main-container'>{p['contenido_raw']}</body></html>"
            
            file_name = p['titulo'].replace(' ','_').lower() + ".html"
            with open(f"{ruta}/{file_name}", "w", encoding="utf-8") as f:
                f.write(full_html)
            
            self.progress_bar.set((i+1)/total)

        self.prog_label.configure(text="Obra completada.")
        self.btn_fiat.configure(state="normal")
        messagebox.showinfo("Éxito", f"Se han generado {total} páginas y el archivo de estilo en la carpeta: {ruta}")

    def exportar_wordpress(self):
        if not self.lista_paginas:
            messagebox.showwarning("Aviso", "Primero debe generar el contenido con FIAT LUX.")
            return
        
        nombre_sede = self.ent_nombre.get()
        ruta = f"sedes/{nombre_sede.replace(' ','_').lower()}"
        xml_path = f"{ruta}/wordpress_import.xml"
        
        xml_content = f"""<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wp="http://wordpress.org/export/1.2/">
<channel>
    <title>{nombre_sede}</title>
    <wp:wxr_version>1.2</wp:wxr_version>
"""
        for p in self.lista_paginas:
            xml_content += f"""
    <item>
        <title>{p['titulo']}</title>
        <content:encoded><![CDATA[{p['contenido_raw']}]]></content:encoded>
        <wp:status>publish</wp:status>
        <wp:post_type>{p['tipo']}</wp:post_type>
        <wp:post_parent>{p['padre']}</wp:post_parent>
    </item>"""

        xml_content += "\n</channel>\n</rss>"
        with open(xml_path, "w", encoding="utf-8") as f:
            f.write(xml_content)
        messagebox.showinfo("WP", "Archivo XML exportado correctamente.")

if __name__ == "__main__":
    app = CalizEstetico()
    app.mainloop()