from connection.database import Database
from decorador.decorator import Response as r
from models.empresas_model import EmpresaModel
from argon2 import PasswordHasher
from fastapi.responses import JSONResponse
import inspect
import re

class Empresas:

    """Clase para gestionar empresas"""
    """Class for handling empresas"""

    def __init__(self):
        self.conn = Database()
        self.db = self.conn.setConnection()
        self.ph = PasswordHasher()

    """Método para realizar el registro de empresas"""
    """Method for performing empresa registration"""

    def register_empresas(self, data):
        function_name = inspect.currentframe().f_code.co_name
        nombre = data["nombre"]
        cif = data["cif"]
        iban = data["iban"]
        tarjeta = data["tarjeta"]
        email = data["email"]

        email_expr = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
        validateEmail = self.db.query(EmpresaModel).filter(EmpresaModel.EMAIL == email).first()

        if not re.match(email_expr, email):
            raise Exception("Error, correo electrónico no tiene un formato válido")
        elif validateEmail:
            raise Exception("Error, el email esta en uso")
        else:
            pass

        new_empresa = EmpresaModel(
            NOMBRE=nombre,
            CIF=cif,
            IBAN=iban,
            TARJETA=tarjeta,
            EMAIL=email
        )

        self.db.add(new_empresa)
        self.db.commit()
        self.db.refresh(new_empresa)
        response = r.generate_response(function_name, 201, new_empresa.ID, error=False, custom_message="Empresa creada con éxito")

        return JSONResponse(content=response, status_code=201)
    
    """Método para obtener las empresas"""
    """Method to get the empresas"""

    def get_empresas(self, data):
        function_name = inspect.currentframe().f_code.co_name
        page = data["page"]
        per_page = data["per_page"]
        
        offset = (page - 1) * per_page        
        query = self.db.query(EmpresaModel.ID, EmpresaModel.NOMBRE, EmpresaModel.CIF, EmpresaModel.IBAN, EmpresaModel.TARJETA, EmpresaModel.EMAIL).offset(offset).limit(per_page).all()
        
        total_items = self.db.query(EmpresaModel).count()
        total_pages = (total_items // per_page) + (1 if total_items % per_page > 0 else 0)
        
        if query:
            result = {
                "items": [{"id": empresa.ID, "nombre": empresa.NOMBRE, "cif": empresa.CIF, "iban": empresa.IBAN, "tarjeta": empresa.TARJETA, "email": empresa.EMAIL} for empresa in query],
                "page": page,
                "per_page": per_page,
                "total_items": total_items,
                "total_pages": total_pages
            }
            
            response = r.generate_response(function_name, 200, result)
            return JSONResponse(content=response, status_code=200)
        else:
            response = r.generate_response(function_name, 404, None, error=True, custom_message="Empresa no encontrada")
            return JSONResponse(content=response, status_code=404)
        
    """Metodos para seleccionar una empresa específica"""
    """Methods to select a specific empresa"""

    def get_empresas_by_modulo(self, data):
        function_name = inspect.currentframe().f_code.co_name
        query = self.db.query(EmpresaModel.ID, EmpresaModel.NOMBRE, EmpresaModel.CIF, EmpresaModel.IBAN, EmpresaModel.TARJETA, EmpresaModel.EMAIL
        ).filter(EmpresaModel.ID == data["id"]).first()
        
        if query:
            result = {
                "id": query.ID,
                "nombre": query.NOMBRE,
                "cif": query.CIF,
                "iban": query.IBAN,
                "tarjeta": query.TARJETA,
                "email": query.EMAIL
            }
            
            response = r.generate_response(function_name, 200, result)        
            return JSONResponse(content=response, status_code=200)
        else:
            response = r.generate_response(function_name, 404, None, error=True, custom_message="Empresa no encontrada")
            return JSONResponse(content=response, status_code=404)
        
    """Método para actualizar las empresas"""
    """Method to update the empresas"""

    def update_empresas(self, data):
        function_name = inspect.currentframe().f_code.co_name
        query = self.db.query(EmpresaModel).filter(EmpresaModel.ID == data["id"]).first()
        
        if query:
            query.NOMBRE = data["nombre"]
            query.CIF = data["cif"]
            query.IBAN = data["iban"]
            query.TARJETA = data["tarjeta"]
            query.EMAIL = data["email"]
            
            self.db.commit()
            
            result = {
                "id": query.ID,
                "nombre": query.NOMBRE,
                "cif": query.CIF,
                "iban": query.IBAN,
                "tarjeta": query.TARJETA,
                "email": query.EMAIL
            }
            
            response = r.generate_response(function_name, 200, result)        
            return JSONResponse(content=response, status_code=200)
        else:
            response = r.generate_response(function_name, 404, None, error=True, custom_message="Empresa no encontrada")
            return JSONResponse(content=response, status_code=404)
        
    """Método para eliminar una empresa"""
    """Method to delete an empresa"""

    def delete_empresas(self, data):
        function_name = inspect.currentframe().f_code.co_name
        query = self.db.query(EmpresaModel).filter(EmpresaModel.ID == data["id"]).first()
        
        if query:
            self.db.delete(query)
            self.db.commit()
            
            response = r.generate_response(function_name, 200, error=False, custom_message="Empresa eliminada con éxito", data=query.NOMBRE)
            return JSONResponse(content=response, status_code=200)
        else:
            response = r.generate_response(function_name, 404, None, error=True, custom_message="Empresa no encontrada")            
            return JSONResponse(content=response, status_code=404)