"""
LadderToSCL - Conversor de Siemens LAD/FUP XML a SCL

Este script es parte de un conjunto de herramientas para convertir proyectos de Siemens LAD/FUP a SCL.

"""
# ToUpload/x3_generate_scl.py
# -*- coding: utf-8 -*-
import json
import os
import re
import argparse
import sys
import traceback
script_root = os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration

# --- Importar Generadores Específicos ---
try:
    from generators.generate_scl_db import generate_scl_for_db
    from generators.generate_scl_code_block import generate_scl_for_code_block
    from generators.generate_md_udt import generate_udt_markdown
    from generators.generate_md_tag_table import generate_tag_table_markdown
    from generators.generator_utils import (
        format_variable_name,
        generate_scl_declarations,
    )
except ImportError as e:
    print(
        f"Error crítico: No se pudieron importar los módulos de 'generators': {e}",
        file=sys.stderr,
    )
    sys.exit(1)

# --- Constantes ---
# SCL_OUTPUT_DIRNAME = "scl_output" # <-- Ya no se usa directamente en __main__, se lee de config


# --- Modificar generate_scl_or_markdown para usar el nuevo directorio de salida ---
def generate_scl_or_markdown(
    processed_json_filepath, final_output_directory, project_root_dir
):  # <-- MODIFICADO: Nombre del argumento
    """
    Genera un archivo SCL o Markdown a partir del JSON procesado,
    llamando a la función generadora apropiada y escribiendo el archivo
    en el directorio de salida final (ej. 'scl_output').
    Pasa project_root_dir a los generadores relevantes.
    """
    if not os.path.exists(processed_json_filepath):
        print(
            f"Error: JSON procesado no encontrado: '{processed_json_filepath}'",
            file=sys.stderr,
        )
        return False  # Indicar fallo

    print(f"Cargando JSON procesado desde: {processed_json_filepath}")
    try:
        with open(processed_json_filepath, "r", encoding="utf-8") as f:
            data = json.load(f)
    except Exception as e:
        print(f"Error al cargar/parsear JSON procesado: {e}", file=sys.stderr)
        traceback.print_exc(file=sys.stderr)
        return False  # Indicar fallo

    block_name = data.get("block_name", "UnknownBlock")
    block_type = data.get("block_type", "Unknown")
    scl_block_name = format_variable_name(block_name)  # Nombre SCL seguro
    output_content = []
    output_extension = ".scl"  # Por defecto

    print(
        f"Generando salida para: {block_type} '{scl_block_name}' (Original: {block_name})"
    )

    # --- Selección del Generador y Extensión ---
    generation_function = None
    func_args = {"data": data}
    if block_type == "GlobalDB":
        print("  -> Modo de generación: DATA_BLOCK SCL")
        generation_function = generate_scl_for_db
        func_args["project_root_dir"] = project_root_dir
        output_extension = ".scl"
    elif block_type == "InstanceDB":  # <-- ADDED: Handle InstanceDB
        print("  -> Modo de generación: INSTANCE_DATA_BLOCK SCL")
        generation_function = generate_scl_for_db  # Use the same generator as GlobalDB
        func_args["project_root_dir"] = project_root_dir
        output_extension = ".scl"
    elif block_type in ["FC", "FB", "OB"]:
        print(f"  -> Modo de generación: {block_type} SCL")
        generation_function = generate_scl_for_code_block
        func_args["project_root_dir"] = project_root_dir
        output_extension = ".scl"
    elif block_type == "PlcUDT":
        print("  -> Modo de generación: UDT Markdown")
        generation_function = generate_udt_markdown
        # generate_udt_markdown no necesita project_root_dir por ahora
        output_extension = ".md"
    elif block_type == "PlcTagTable":
        print("  -> Modo de generación: Tag Table Markdown")
        generation_function = generate_tag_table_markdown
        output_extension = ".md"
    else:
        print(
            f"Error: Tipo de bloque desconocido '{block_type}'. No se generará archivo.",
            file=sys.stderr,
        )
        return False  # Indicar fallo

    # --- Llamar a la función generadora ---
    if generation_function:
        try:
            output_content = generation_function(**func_args)
        except Exception as gen_e:
            print(
                f"Error durante la generación de contenido para {block_type} '{scl_block_name}': {gen_e}",
                file=sys.stderr,
            )
            traceback.print_exc(file=sys.stderr)
            return False  # Indicar fallo

    # --- Escritura del Archivo de Salida en el Directorio Final ---
    output_filename_base = f"{scl_block_name}{output_extension}"
    # El 'final_output_directory' ya viene calculado desde __main__
    output_filepath = os.path.join(final_output_directory, output_filename_base)

    print(
        f"  -> Escribiendo archivo de salida final en: {os.path.relpath(output_filepath)}"
    )
    try:
        # Asegurar que el directorio de salida exista (ya debería estar hecho en __main__)
        os.makedirs(os.path.dirname(output_filepath), exist_ok=True)
        with open(output_filepath, "w", encoding="utf-8") as f:
            for line in output_content:
                f.write(line + "\n")
        print(f"Generación de {output_extension.upper()} completada.")
        return True  # Indicar éxito
    except Exception as e:
        print(
            f"Error al escribir el archivo final {output_extension.upper()}: {e}",
            file=sys.stderr,
        )
        traceback.print_exc(file=sys.stderr)
        return False  # Indicar fallo


# --- Ejecución (MODIFICADO para usar SCL_OUTPUT_DIRNAME) ---
if __name__ == "__main__":
    # Lógica para ejecución standalone
    try:
        import tkinter as tk
        from tkinter import filedialog
    except ImportError:
        print("Error: Tkinter no está instalado. No se puede mostrar el diálogo de archivo.", file=sys.stderr)
        tk = None

    input_json_file = ""
    project_root_dir = ""

    if tk:
        root = tk.Tk()
        root.withdraw()
        print("Por favor, selecciona el archivo JSON procesado de entrada (generado por x2)...")
        input_json_file = filedialog.askopenfilename(
            title="Selecciona el archivo JSON procesado de entrada (_processed.json)",
            filetypes=[("Processed JSON files", "*_processed.json"), ("JSON files", "*.json"), ("All files", "*.*")]
        )
        if input_json_file:
            print(f"Archivo JSON procesado seleccionado: {input_json_file}")
            print("Por favor, selecciona el directorio raíz del proyecto XML (ej. la carpeta 'PLC')...")
            project_root_dir = filedialog.askdirectory(
                title="Selecciona el directorio raíz del proyecto XML"
            )
            if project_root_dir:
                 print(f"Directorio raíz del proyecto seleccionado: {project_root_dir}")
            else:
                 print("No se seleccionó directorio raíz. Saliendo.", file=sys.stderr)
        else:
            print("No se seleccionó archivo JSON procesado. Saliendo.", file=sys.stderr)
        root.destroy()

    if input_json_file and project_root_dir:
        # Calcular directorio de salida final
        # <-- NUEVO: Leer nombre del directorio de salida desde la configuración -->
        configs = load_configuration()
        xml_parser_config = configs.get("XML Parser to SCL", {})
        cfg_scl_output_dirname = xml_parser_config.get("scl_output_dir", "scl_output") # Leer con default
        # <-- FIN NUEVO -->

        final_output_dir = os.path.join(project_root_dir, cfg_scl_output_dirname) # Usar valor leído

        print(f"(x3 - Standalone) Generando SCL/MD desde: '{os.path.relpath(input_json_file)}'")
        print(f"(x3 - Standalone) Directorio de salida final: '{os.path.relpath(final_output_dir)}'")
        print(f"(x3 - Standalone) Usando ruta raíz del proyecto: '{project_root_dir}' para buscar UDTs.")

        # Asegurar que el directorio de salida final exista
        try:
            os.makedirs(final_output_dir, exist_ok=True)
        except OSError as e:
            print(
                f"Error Crítico (x3): No se pudo crear el directorio de salida '{final_output_dir}': {e}",
                file=sys.stderr,
            )
            # sys.exit(1) # No usar sys.exit
            success = False # Marcar como fallo para evitar la llamada
        else:
             success = True # Marcar como éxito para proceder

        if success: # Solo intentar si se pudo crear el directorio
            try:
                # Llamar a la función principal
                success = generate_scl_or_markdown(
                    input_json_file, final_output_dir, project_root_dir
                )
                if success:
                    print("\nGeneración de SCL/MD completada exitosamente.")
                else:
                    # La función generate_scl_or_markdown ya imprime el error
                    print(f"\nError durante la generación desde '{os.path.relpath(input_json_file)}'.", file=sys.stderr)
                    # sys.exit(1) # No usar sys.exit
            except Exception as e:
                print(f"Error Crítico no manejado en x3: {e}", file=sys.stderr)
                traceback.print_exc(file=sys.stderr)
                # sys.exit(1) # No usar sys.exit
    else:
        # Mensajes de cancelación ya impresos si aplica
        pass
