"""
Functions dependent on advlabdb.models.
"""

from functools import cache

from flask import flash
from flask_login import current_user
from markupsafe import Markup
from wtforms.fields import BooleanField, IntegerField, SelectField, StringField
from wtforms.validators import DataRequired, NumberRange, Optional

from .models import MAX_MARK, MIN_MARK, Semester


def active_semester_str():
    active_semester = current_user.active_semester
    active_semester_str = str(active_semester)
    if active_semester != Semester.lastSemester():
        flash(
            Markup(
                f"You are in the old semester {active_semester_str}! You should change your active semester in <a href='/user-settings'>user settings</a>."
            ),
            "warning",
        )

    return active_semester_str


def mark_field(mark_type: str):
    return IntegerField(
        mark_type + " Mark",
        validators=[Optional(), NumberRange(MIN_MARK, MAX_MARK)],
        description=f"Between {MIN_MARK} and {MAX_MARK}.",
    )


@cache
def selection_mark_field_choices():
    choices = [(mark, str(mark)) for mark in range(MAX_MARK, MIN_MARK - 1, -1)]
    choices.insert(0, (-1, "Not set yet"))

    return choices


def selection_mark_field(mark_type: str, default):
    choices = selection_mark_field_choices()

    if default is None:
        default = -1

    return SelectField(
        mark_type + " Mark",
        default=default,
        choices=choices,
        validators=[DataRequired()],
    )


def parse_selection_mark_field(field):
    data = int(field.data)
    if data == -1:
        return None

    return data


def user_info_fields():
    phone_number = StringField(
        "Phone Number",
        validators=[Optional()],
    )
    mobile_phone_number = StringField(
        "Mobile Phone Number",
        validators=[Optional()],
    )

    building = StringField(
        "Building",
        validators=[Optional()],
    )
    room = StringField(
        "Room",
        validators=[Optional()],
    )

    return phone_number, mobile_phone_number, building, room


def generate_new_password_field():
    return BooleanField(
        "Generate new random password. For security reasons, it is not possible to manually enter a password. Please use a password manager like Bitwarden or KeepassXC to save the randomly generated password.",
        default=False,
    )