"""
Functions not dependent on advlabdb.
"""

from flask import flash, url_for
from markupsafe import Markup, escape


def flashRandomPassword(email: str, password: str):
    flash(f"New random password for email {email}: {password}", category="warning")


def deep_getattr(object, composed_name: str):
    names = composed_name.split(".")
    attr = getattr(object, names[0])
    for name in names[1:]:
        attr = getattr(attr, name)

    return attr


def str_without_semester_formatter(view, context, model, name: str):
    attr = deep_getattr(model, name)

    if attr is None:
        return ""

    if hasattr(attr, "__iter__") and not isinstance(attr, str):
        # List of attributes
        return ", ".join(a.str_without_semester() for a in attr)

    return attr.str_without_semester()


def str_formatter(view, context, model, name: str):
    attr = deep_getattr(model, name)

    if attr is None:
        return ""

    if hasattr(attr, "__iter__") and not isinstance(attr, str):
        # List of attributes
        return ", ".join(a.str() for a in attr)

    return attr.str()


def _details_link(url, attr, attr_formatter):
    return f"<a href='{url}?id={attr.id}'>{escape(attr_formatter(attr))}</a>"


def _default_attr_formatter(attr):
    return attr


def link_formatter(model, name: str, endpoint, attr_formatter=_default_attr_formatter):
    attr = deep_getattr(model, name)

    if attr is None:
        return ""

    url = url_for(f"{endpoint}.details_view")

    if hasattr(attr, "__iter__") and not isinstance(attr, str):
        # List of attributes
        links = (_details_link(url, a, attr_formatter) for a in attr)
        return Markup(", ".join(links))

    # Single attribute
    return Markup(_details_link(url, attr, attr_formatter))


def link_formatter_factory(endpoint, attr_formatter=_default_attr_formatter):
    def formatter(view, context, model, name):
        return link_formatter(model, name, endpoint, attr_formatter)

    return formatter


def email_formatter(view, context, model, name: str):
    attr = deep_getattr(model, name)

    if attr is None:
        return ""

    return Markup(f"<a href='mailto:{escape(attr)}'>{escape(attr)}</a>")


def experiment_marks_missing_formatter(view, context, model, name: str):
    experiment_marks_missing = getattr(model, name)
    if experiment_marks_missing == True:
        return Markup("<span style='color: red;'>Yes</span>")

    return "No"