from django import template
from django.utils.html import format_html
from ..models import Control, ImpactChoice, Incident, Risk, LikelihoodChoice

register = template.Library()

_RISK_STATUS_MAP = dict(Risk.STATUS_CHOICES)
_CONTROL_STATUS_MAP = dict(Control.STATUS_CHOICES)
_INCIDENT_STATUS_MAP = dict(Incident.STATUS_CHOICES)
LEVEL_ID_MAP = {"Low": 1, "Medium": 2, "High": 3, "Critical": 4}

# ---------------------------------------------------------------------------
# Likelihood
# ---------------------------------------------------------------------------

# Likelihood Label
def get_likelihood_label(likelihood_obj):
    if not likelihood_obj:
        return ""
    return f"{likelihood_obj.value} ({likelihood_obj.name})"

@register.filter
def likelihood_id_label(likelihood):
    if isinstance(likelihood, LikelihoodChoice):
        return f"{likelihood.value} ({likelihood.name})"
    return likelihood

# Likelihood Value
def get_likelihood_value(likelihood):
    if isinstance(likelihood, LikelihoodChoice):
        return likelihood.value
    return likelihood

@register.filter
def likelihood_value(likelihood_obj):
    return get_likelihood_value(likelihood_obj)

# Likelihood Class
def get_likelihood_class(likelihood):
    value = get_likelihood_value(likelihood)
    LIKELIHOOD_MAP = {
        1: "is-control-verylow",
        2: "is-control-low",
        3: "is-control-mid",
        4: "is-control-high",
    }
    return LIKELIHOOD_MAP.get(value, "is-light")

@register.filter
def likelihood_class(likelihood):
    return get_likelihood_class(likelihood)

# ---------------------------------------------------------------------------
# Impact
# ---------------------------------------------------------------------------

# Impact Label
def get_impact_label(impact_obj):
    if not impact_obj:
        return ""
    return f"{impact_obj.value} ({impact_obj.name})"

@register.filter
def impact_id_label(impact):
    if isinstance(impact, ImpactChoice):
        return f"{impact.value} ({impact.name})"
    return impact

# Impact Value
def get_impact_value(impact):
    if isinstance(impact, ImpactChoice):
        return impact.value
    return impact

@register.filter
def impact_value(impact_obj):
    return get_impact_value(impact_obj)

# Impact Class
def get_impact_class(impact):
    value = get_impact_value(impact)
    IMPACT_MAP = {
        1: "is-control-verylow",
        2: "is-control-low",
        3: "is-control-mid",
        4: "is-control-high",
        5: "is-control-veryhigh",
    }
    return IMPACT_MAP.get(value, "is-light")

@register.filter
def impact_class(impact):
    return get_impact_class(impact)

# ---------------------------------------------------------------------------
# Unsorted
# ---------------------------------------------------------------------------

@register.simple_tag
def sort_url(request, field, current_sort, current_dir):
    query = request.GET.copy()
    # Richtung bestimmen
    if current_sort == field and current_dir == "asc":
        query["dir"] = "desc"
    else:
        query["dir"] = "asc"
    query["sort"] = field
    return f"?{query.urlencode()}"

@register.filter
def dict_get(d, key):
    try:
        return d.get(key)
    except Exception:
        return None

@register.filter
def mul(a, b):
    try:
        return int(a) * int(b)
    except (TypeError, ValueError):
        return ""

@register.filter
def level_id(level):
    return LEVEL_ID_MAP.get(str(level), "")

@register.filter
def user_display(user):
    if not user:
        return ""
    full = user.get_full_name()
    return full if full else user.username

def _short(label: str) -> str:
    """First Segment of - from Impact and Likelihood"""
    if not label:
        return ""
    for sep in (" – ", " - ", "("):
        if sep in label:
            return label.split(sep, 1)[0].strip()
    return label.strip()


@register.filter
def risk_status_label(code):
    return _RISK_STATUS_MAP.get(code, code)

@register.filter
def control_status_label(code):
    return _CONTROL_STATUS_MAP.get(code, code)

@register.filter
def incident_status_label(code):
    return _INCIDENT_STATUS_MAP.get(code, code)

@register.filter
def cia_label(value):
    mapping = dict(Risk.CIA_CHOICES)
    return mapping.get(value, value)

LIKELIHOOD_MAP = {
    1: "is-control-verylow",
    2: "is-control-low",
    3: "is-control-mid",
    4: "is-control-high",
}

IMPACT_MAP = {
    1: "is-control-verylow",
    2: "is-control-low",
    3: "is-control-mid",
    4: "is-control-high",
    5: "is-control-veryhigh",
}

LEVEL_MAP = {
    "Low": "is-control-low",
    "Medium": "is-control-mid",
    "High": "is-control-high",
    "Critical": "is-control-veryhigh",
}

@register.filter
def level_class(level):
    return LEVEL_MAP.get(str(level), "is-light")

@register.filter
def score_class(score):
    """Score 1..20 → 5 Stufen"""
    try:
        s = int(score)
    except (TypeError, ValueError):
        return "is-light"
    if s <= 4:
        return "is-control-verylow"
    if s <= 8:
        return "is-control-low"
    if s <= 12:
        return "is-control-mid"
    if s <= 16:
        return "is-control-high"
    return "is-control-veryhigh"

@register.filter
def to_bg(css_class: str):
    """
    Wandelt is-control-foo -> has-background-control-foo um.
    Für Tabellenzellen-Hintergrundfarben.
    """
    try:
        css = str(css_class)
    except Exception:
        return ""
    return css.replace("is-control-", "has-background-control-") if css.startswith("is-control-") else css

@register.filter
def score_bg_class(score):
    """
    Mappt Score (1..20) auf deine Farbhintergründe.
    """
    try:
        s = int(score)
    except (TypeError, ValueError):
        return ""
    if s <= 4:
        return "has-background-control-verylow"
    elif s <= 8:
        return "has-background-control-low"
    elif s <= 12:
        return "has-background-control-mid"
    elif s <= 16:
        return "has-background-control-high"
    else:
        return "has-background-control-veryhigh"