import gradio as gr
import json
import pandas as pd
import spacy
import subprocess
import sys
import logging
from pathlib import Path
from seo_analyzer import SEOSpaceAnalyzer

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def setup_spacy_model():
    """Carga o descarga el modelo spaCy necesario."""
    try:
        spacy.load("es_core_news_lg")
        logger.info("Modelo spaCy 'es_core_news_lg' cargado correctamente.")
    except OSError:
        logger.info("Descargando spaCy model es_core_news_lg...")
        subprocess.run([sys.executable, "-m", "spacy", "download", "es_core_news_lg"], check=True)

def list_content_storage_files() -> list:
    """Devuelve la lista de archivos en la carpeta content_storage."""
    base_dir = Path("content_storage")
    if not base_dir.exists():
        return []
    return [str(file.relative_to(base_dir)) for file in base_dir.glob("**/*") if file.is_file()]

def download_storage_file(selected_file: str) -> str:
    """Dado el nombre del archivo (relativo a content_storage), devuelve la ruta para descarga."""
    if not selected_file:
        return ""
    file_path = Path("content_storage") / selected_file
    return str(file_path) if file_path.exists() else ""

def refresh_file_list() -> list:
    """Actualiza la lista de archivos disponibles en content_storage."""
    return list_content_storage_files()

# Creamos la interfaz
def create_interface() -> gr.Blocks:
    analyzer = SEOSpaceAnalyzer()

    # Definimos una función envoltorio para incluir callbacks de estado
    def analyze_with_callbacks(sitemap_url: str):
        status_msgs = []

        def status_callback(msg: str):
            status_msgs.append(msg)
            logger.info(msg)

        def progress_callback(current: int, total: int):
            logger.info(f"Batch {current} de {total} procesado.")

        # Se llama al método modificado que procesa en lotes de 5
        results = analyzer.analyze_sitemap(sitemap_url, progress_callback=progress_callback, status_callback=status_callback)
        final_status = "\n".join(status_msgs) if status_msgs else "Análisis completado."
        # 'results' es una tupla de 7 elementos:
        # (stats, recommendations, content_analysis, links, details, similarities, seo_tags)
        # Devolvemos esos 7 outputs más el mensaje final en estado (total 8)
        return (*results, final_status)

    with gr.Blocks(title="SEO Analyzer Pro", theme=gr.themes.Soft()) as demo:
        gr.Markdown("""
        # 🧠 SEO Analyzer Pro
        Este espacio analiza contenido web orientado a normativa bancaria y genera:
        - Temas inferidos automáticamente
        - Títulos y meta descripciones SEO
        - Alertas por lenguaje de riesgo
        """)
        with gr.Row():
            sitemap_input = gr.Textbox(label="📍 URL del Sitemap", placeholder="https://ejemplo.com/sitemap.xml")
            analyze_btn = gr.Button("🔍 Analizar")
            clear_btn = gr.Button("🧹 Limpiar")
            download_json_btn = gr.Button("📥 Descargar JSON")
            download_csv_btn = gr.Button("📤 Descargar CSV")
        status_output = gr.Textbox(label="Estado del análisis", interactive=False)
        with gr.Tabs():
            with gr.Tab("📊 Resumen"):
                stats_output = gr.JSON(label="Estadísticas")
                recommendations_output = gr.JSON(label="Recomendaciones SEO")
            with gr.Tab("📝 Contenido"):
                content_output = gr.JSON(label="Análisis de contenido")
            with gr.Tab("🔗 Enlaces"):
                links_output = gr.JSON(label="Análisis de enlaces")
                links_plot = gr.Plot(label="Visualización de enlaces internos")
            with gr.Tab("📄 Detalles"):
                details_output = gr.JSON(label="Detalles por página")
            with gr.Tab("🧠 SEO y Temas"):
                seo_tags_output = gr.JSON(label="Metadatos SEO generados")
                # Los siguientes se actualizan vía change en seo_tags_output
                topics_output = gr.JSON(label="Temas inferidos")
                flags_output = gr.JSON(label="Términos prohibidos detectados")
            with gr.Tab("🔗 Similitud"):
                similarity_output = gr.JSON(label="Similitud entre URLs")
            with gr.Tab("📁 Archivos"):
                file_dropdown = gr.Dropdown(label="Archivos en content_storage", choices=list_content_storage_files())
                refresh_btn = gr.Button("Actualizar lista")
                download_file_btn = gr.Button("Descargar Archivo Seleccionado", variant="secondary")
                file_download = gr.File(label="Archivo Seleccionado")
        def export_json() -> str:
            if analyzer.current_analysis:
                path = Path("content_storage/seo_report.json")
                with open(path, "w", encoding="utf-8") as f:
                    json.dump(analyzer.current_analysis, f, indent=2, ensure_ascii=False)
                return str(path)
            return ""
        def export_csv() -> str:
            if not analyzer.current_analysis:
                return ""
            path = Path("content_storage/seo_summary.csv")
            data = []
            for url, seo in analyzer.current_analysis.get("seo_tags", {}).items():
                data.append({
                    "url": url,
                    "title": seo.get("title", ""),
                    "meta_description": seo.get("meta_description", ""),
                    "flags": ", ".join(seo.get("flags", [])),
                    "topics": ", ".join(analyzer.current_analysis.get("topics", {}).get(url, [])),
                    "summary": analyzer.current_analysis.get("summaries", {}).get(url, "")
                })
            pd.DataFrame(data).to_csv(path, index=False)
            return str(path)
        analyze_btn.click(
            fn=analyze_with_callbacks,
            inputs=sitemap_input,
            outputs=[
                stats_output, recommendations_output, content_output,
                links_output, details_output, similarity_output,
                seo_tags_output, status_output
            ],
            show_progress=True
        )
        clear_btn.click(fn=lambda: [None]*8, outputs=[
            stats_output, recommendations_output, content_output,
            links_output, details_output, similarity_output,
            seo_tags_output, status_output
        ])
        download_json_btn.click(fn=export_json, outputs=status_output)
        download_csv_btn.click(fn=export_csv, outputs=status_output)
        links_output.change(fn=analyzer.plot_internal_links, inputs=links_output, outputs=links_plot)
        seo_tags_output.change(fn=lambda: analyzer.current_analysis.get("topics", {}), outputs=topics_output)
        seo_tags_output.change(fn=lambda: analyzer.current_analysis.get("flags", {}), outputs=flags_output)
        refresh_btn.click(fn=refresh_file_list, outputs=file_dropdown)
        download_file_btn.click(fn=download_storage_file, inputs=file_dropdown, outputs=file_download)
    return demo

if __name__ == "__main__":
    setup_spacy_model()
    app = create_interface()
    app.launch(server_name="0.0.0.0", server_port=7860)