from sqlalchemy import or_

from database import SessionLocal, engine, models
from database.models import User

db = SessionLocal()


def search_database(id) -> User:
    """
    Returns the user associated with the id argument
    """
    return (
        db.query(User)
        .filter(or_(User.correo_institucional == id, User.numero_de_documento == id))
        .first()
    )


def insert_data(data) -> None:
    """
    Inserts a new user into the database
    """
    item = User(**data)
    db.add(item)
    db.commit()
    db.refresh(item)


def create_database(data) -> None:
    """
    Creates the SQL database from scratch and populates it
    """
    models.Base.metadata.create_all(bind=engine)
    existing_row = search_database(data["correo_institucional"])
    if existing_row:
        return
    insert_data(data)


def save_attribute(id, attribute, data) -> None:
    """
    Updates the attribute value with the content of data
    """
    key = eval("User." + attribute)
    db.query(User).filter(
        or_(User.correo_institucional == id, User.numero_de_documento == id)
    ).update({key: data})
    db.commit()


def verify_code(id, code) -> bool:
    """
    Verifies that two-factor authentification code matches the database record
    """
    db_record = search_database(id=id)
    valid_code = code == db_record.codigo
    if valid_code:
        return True
    return False


def parse_boolean_string(value) -> bool:
    """
    Converts string response to a boolean
    """
    mapping = {"si": True, "sí": True, "no": False}
    return mapping[value]


def boolean_to_string(value) -> str:
    """
    Converts boolean to string
    """
    if value:
        return "Sí"
    return "No"