from email.message import EmailMessage
import smtplib
import os
import json
import string
import secrets
from flask_bcrypt import Bcrypt
import shortuuid
from datetime import datetime, timezone
from zoneinfo import ZoneInfo  # Python 3.9+

bcrypt = Bcrypt()


v = {
  'home': 'a_home/home.html',
  'about-us': 'b_about-us/about-us.html',
  'solutions': 'c_solutions/solutions.html',
  'methodology': 'd_methodology/methodology.html',
  "blog": {
      "all_posts": "e_blog/a_all_posts.html",
        "post": "e_blog/b_post.html",
  }, 
  'contact': 'f_contact/contact.html',
  'login': 'g_login/login.html', 
  'recover_pswd': 'g_login/recover_pswd.html',
  'tmp_user': {
    'home': 'h_tmp_usr/a_home.html',
    'txt_editor': 'h_tmp_usr/b_txt_editor.html',
    'my_posts': 'h_tmp_usr/c_my_posts.html',
    'read_post': 'h_tmp_usr/d_read_post.html',
    'edit_post': 'h_tmp_usr/e_edit_post.html',
    'change_pswd': 'h_tmp_usr/f_change_pswd.html',
    'metrics': 'h_tmp_usr/g_metrics.html',
    'manage_profiles': 'h_tmp_usr/h_manage_profiles.html',
    'carousel': 'h_tmp_usr/i_carousel_form.html'
  }

}

l_flash_msj = lambda title, body, typeAlert: {'title': title, 'body': body, 'typeAlert': typeAlert}

def min_read_pst(n_words: int) -> str:
    # https://uapas2.bunam.unam.mx/humanidades/velocidad_lectora/
    # min 250 y más 500 = 750 / 2 = ~375
    t = int(round(n_words / 375, 0))
    resultado = f'{t} min' if t < 60 else f'{int(t/60)} hrs'
    return resultado

def db_conf_obj(dbEnvVarName: str) -> object:
    '''
    dbEnvVarName = nombre de la variable de entorno
    variable que contiene los datos de la base de datos
    '''
    db = os.getenv(dbEnvVarName)
    db = json.loads(db)
    return db

def generar_contrasena():
    """
    Genera una contraseña aleatoria de 25 caracteres.

    La contraseña se compone de una combinación de letras mayúsculas, letras minúsculas y dígitos. La función utiliza
    el módulo `secrets` para asegurar que la generación de la contraseña sea adecuada para propósitos de seguridad.

    Returns:
    -------
    str
        Una cadena de caracteres aleatorios de 25 caracteres, formada por letras (mayúsculas y minúsculas) y dígitos.
    
    Example:
    --------
    >>> generar_contrasena()
    'A9gTz5bNp0Wk3L6Xq2vUv8YwRz1E'
    """
    caracteres = string.ascii_letters + string.digits
    contrasena = ''.join(secrets.choice(caracteres) for _ in range(25))
    return contrasena

def hash_password(password):
    """
    Genera un hash de la contraseña utilizando bcrypt.

    Esta función toma una contraseña en texto plano y la convierte en un hash seguro utilizando el algoritmo bcrypt.
    El hash generado es una cadena en formato UTF-8, adecuada para almacenamiento en bases de datos.

    Parámetros:
    ----------
    password : str
        La contraseña en texto plano que se desea hashear.

    Returns:
    -------
    str or None
        El hash de la contraseña en formato UTF-8 si la operación es exitosa. 
        Devuelve `None` en caso de que ocurra una excepción durante el proceso de hashing.
    
    Example:
    --------
    >>> hash_password('mi_contrasena_segura')
    '$2b$12$D4yU/jEaK4xdgK0R2J6c6Odnk8p3k/RtG2ByjF26.4gnBR4tdA/2i'
    """
    try:
        hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')
        return hashed_password
    except Exception as e:
        return None
    
def getRandomId():
    # POR DEFAULT SHORUUID SACA 22 CARACTERES
    # LOS PODEMOS ACORTAR DE LA SIGUIENTE MANERA: short_id_custom = shortuuid.uuid()[:10]
    # Configurar el generador con una semilla específica (opcional)
    # shortuuid.set_alphabet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-!#$!%&/()=?¡¿")
    shortuuid.set_alphabet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
    # Generar un UUID corto con la semilla personalizada
    short_id_custom = shortuuid.uuid()
    return short_id_custom

def saludo_hr():
    hora = datetime.now().hour
    if 5 <= hora < 12:
        return "🌅 Buenos días"
    elif 12 <= hora < 18:
        return "🌞 Buenas tardes"
    else:
        return "🌙 Buenas noches"
    

def cur_date() -> datetime:
    fecha_actual = datetime.now(ZoneInfo("America/Mexico_City"))
    return fecha_actual


def get_date_n_time(timestamp: datetime) -> dict:
    obj = {
        "date": timestamp.strftime("%d/%m/%Y"),
        "hour": timestamp.strftime("%H:%M:%S")
    }
    return obj

def hex_to_rgb(hex_color):
    # Elimina el símbolo '#' si está presente
    hex_color = hex_color.lstrip('#')
    
    # Convierte los pares de caracteres hexadecimales a enteros
    if len(hex_color) == 6:
        r = int(hex_color[0:2], 16)
        g = int(hex_color[2:4], 16)
        b = int(hex_color[4:6], 16)
        return (r, g, b)
    else:
        raise ValueError("El color HEX debe tener 6 dígitos.")


def rgba_to_string(rgba):
    r, g, b, a = rgba
    return f"rgba({r}, {g}, {b}, {a})"
