# -*- coding: utf-8 -*- 
from core.models.develop.clazz import Clazz, get_fields, get_fields_form
from core.models.develop.container import Container
from core.utils.generate_class import generate_model_class, ensure_import_exists,clear_file_content
from core.utils.migrate_class import migrateClass
from core.utils.packages import application, session, engine
from core.utils.view_class_container_fields import get_clazz_fields_migration, get_clazz_relevants_migration
import os
from flask import Blueprint, render_template, request, flash, redirect, url_for, current_app
from core.utils.db import db
from werkzeug.utils import secure_filename
from flask_login import login_required
import traceback
from core.utils.packages.engine import traceError

classname = "clazz"
Record = Clazz

containers = get_fields()
fields = get_fields_form()
blueprintname = Blueprint("clazz", __name__)

@blueprintname.route(f'/develop/{classname}/new/', methods=["GET","POST"])
@traceError
@login_required
def create_record():
    class_names = application.list_class_names()
    if request.method == "GET":
        return render_template("backend/base/new_base.html", containers=containers,classname=classname, class_names=class_names)
    elif request.method == "POST":

        institution = Record()
        session.saveForm(institution,fields)
        db.session.add(institution)
        db.session.commit()
        return redirect(url_for('.view_record', record_id=institution.id,classname=classname, class_names=class_names))
    
@blueprintname.route(f'/develop/{classname}/<int:record_id>/')
@traceError
@login_required
def view_record(record_id):
    class_names = application.list_class_names()
    institution = application.getClazzDevelop(record_id)
    clazz_containers = institution.containers
    clazz_relevants = institution.relevants
    institution.fields.sort(key=lambda field: field.name) 
    clazz_fields = institution.fields 
    
    # Consulta para obtener solo los campos `id` y `name`
    #containers_list = db.session.query(Container.id, Container.name).filter_by(clazz_id=record_id).all()

    # Convertir el resultado en una lista de diccionarios (opcional)
    #clazz_containers = [{"id": container.id, "name": container.name} for container in clazz_containers]
    # Convertir el resultado en una lista de diccionarios (opcional)
    clazz_relevants = [{"id": relevant.id, "name": repr(relevant)} for relevant in clazz_relevants]
    
    # Convertir el resultado en una lista de diccionarios (opcional)
    clazz_fields = [{"id": relevant.id,
                     "name": repr(relevant) or "",
                     "type": relevant.type or "",
                     "input": relevant.input or "",
                     "label": relevant.label or "",
                     "options":relevant.select_options or "",
                     "calculate_file":relevant.calculate_file or "",
                     "calculate_function":relevant.calculate_function or ""
                     } for relevant in clazz_fields]
    
    #print(containers)
    return render_template('backend/base/view_clazz.html', institution=institution,clazz_fields=clazz_fields, containers=containers,classname=classname, clazz_containers=None, clazz_relevants=clazz_relevants, class_names=class_names)

@blueprintname.route(f'/develop/{classname}/<int:record_id>/edit/', methods=['GET', 'POST'])
@traceError
@login_required
def edit_record(record_id):
    class_names = application.list_class_names()
    institution = Record.query.get_or_404(record_id)
    if request.method == 'POST':
        session.saveForm(institution,fields) 
                
        db.session.commit()
        flash('La institución ha sido actualizada exitosamente.', 'success')
        return render_template('backend/base/edit_base.html', institution=institution, containers=containers,classname=classname, class_names=class_names)
    return render_template('backend/base/edit_base.html', institution=institution,containers=containers,classname=classname, class_names=class_names)

@blueprintname.route(f'/develop/{classname}/migrate/', methods=['GET', 'POST'])
@traceError
@login_required
def migrate():
  try:
    def format_classname(name):
        """Formatea un nombre a CamelCase para usarse como nombre de clase."""
        return ''.join(word.capitalize() for word in name.split())

    def format_filename(name):
        """Formatea un nombre a snake_case para usarse como nombre de archivo."""
        return '_'.join(word.lower() for word in name.split())

    table = application.getAllClazzes()

    # Borrar listado en develop
    file_path_statement = 'project/models/production/clazzlist.py'
    clear_file_content(file_path_statement)
    
    # Borrar listado en produccion
    #file_path_statement = '../production/models/clazzlist.py'
    #clear_file_content(file_path_statement)
    with open(file_path_statement, 'a', encoding='utf-8') as file:
        file.write("# -*- coding: utf-8 -*- \n")

    list_by_name = {}
    list_by_id = {}
    for clazz in table:
        institution = clazz
        fields = get_clazz_fields_migration(clazz.id)
        relevants = get_clazz_relevants_migration(clazz.id)
        id = institution.id
        name = institution.name
        label = institution.label
        tag = institution.tag
        treeView = institution.treeView
        template = institution.template
        plural = institution.plural
        sort_field_results = institution.sort_field_results
        table_fields = institution.table_fields
        search_fields = institution.search_fields
        extraActions = institution.extraActions
        clazz_representation = institution.clazz_representation

        classname = format_classname(name)
        filename = format_filename(f"{name}.py")
        #print(fields, name, plural, classname,filename)

        # Crea migration en develop
        directory = "project/models/production"
        response = generate_model_class(fields, classname, filename,directory,plural,relevants)
        #print("llega aca")
        
        # Crea migration en production
        #directory = "../production/models/production"
        #response = generate_model_class(fields, classname, filename,directory,plural)
        
        if response:
            nameImport = format_filename(f"{name}")
            list_by_name[nameImport] = {
                "id": id,
                "name": nameImport,
                "classname": classname,
                "filename": filename,
                "label": label,
                "tag": tag,
                "treeView": treeView,
                "template": template,
                "plural": plural,
                "extraActions": extraActions,
                "sort_field_results": sort_field_results,
                "table_fields": table_fields,
                "search_fields": search_fields,
                "clazz_representation": clazz_representation,
            }
            list_by_id[id] = {
                "id": id,
                "name": nameImport,
                "classname": classname,
                "filename": filename,
                "label": label,
                "tag": tag,
                "treeView": treeView,
                "template": template,
                "plural": plural,
                "extraActions": extraActions,
                "sort_field_results": sort_field_results,
                "table_fields": table_fields,
                "search_fields": search_fields,
                "clazz_representation": clazz_representation,
            }
            
            import_statement = f'from . import {nameImport}'
            
            # Crea Class List en Develop
            file_path_statement = 'project/models/production/clazzlist.py'
            ensure_import_exists(file_path_statement, import_statement)
            
            # Crea Class List en Production
            #file_path_statement = '../production/models/production/clazzlist.py'
            #ensure_import_exists(file_path_statement, import_statement)

            #generate_route_class(record_id,classname,format_filename(name))
            flash(f'{response}', 'success')
        else:
            flash(f'Error', 'danger')

    # Crea funciones de listado en clazzlist.py
    file_path_statement = 'project/models/production/clazzlist.py'
    with open(file_path_statement, 'a', encoding='utf-8') as file:
        file.write('\n\ndef get_list_by_name():\n')
        file.write('    return ' + str(list_by_name) + '\n')
        file.write('\n\ndef get_list_by_id():\n')
        file.write('    return ' + str(list_by_id) + '\n')
        print(f"'{list_by_name}' fue agregado al archivo.")
        print(f"'{list_by_id}' fue agregado al archivo.")

    migrateClass()
    return redirect(url_for(".list_record"))
  except Exception as e:
        print("Error: ", str(e))
        print(traceback.format_exc())
        return str(e), 500

@blueprintname.route(f'/develop/{classname}/<int:record_id>/delete/', methods=['POST'])
@traceError
@login_required
def delete_record(record_id):
    institution = Record.query.get_or_404(record_id)
    db.session.delete(institution)
    db.session.commit()
    flash('La institución ha sido eliminada exitosamente.', 'success')
    return redirect(url_for('.list_record'))  # Asumiendo que existe una ruta para listar instituciones

@blueprintname.route(f'/develop/{classname}/all/')
@traceError
@login_required
def list_record():
    class_names = application.list_class_names()
    institutions = Record.query.all()
    return render_template('backend/base/list_clazz.html', institutions=institutions,classname=classname, class_names=class_names)
