# BFH Science Self-Service Portal
# Copyright (C) 2025-2026 IKUS Software
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

import cherrypy
from cherrypy_foundation.flash import flash
from cherrypy_foundation.form import CherryForm
from cherrypy_foundation.tools.i18n import gettext_lazy as _
from cherrypy_foundation.url import url_for
from wtforms.fields import BooleanField, PasswordField, StringField, SubmitField
from wtforms.validators import InputRequired, Length


class LoginForm(CherryForm):
    """
    Login form to prompt user credentials.
    """

    login = StringField(
        _('Login'),
        default=lambda: getattr(cherrypy.serving.request, 'login', ''),
        validators=[
            InputRequired(),
            Length(max=256),
        ],
        render_kw={"placeholder": _("Enter a valid email address"), "autofocus": True},
    )
    password = PasswordField(
        _('Password'),
        validators=[
            InputRequired(),
            Length(max=256),
        ],
        render_kw={"placeholder": _("Enter password")},
    )
    persistent = BooleanField(
        _('Remember me'),
        default=lambda: getattr(cherrypy.serving.request, 'login_persistent', False),
        render_kw={},
    )
    submit = SubmitField(
        _('Login'),
    )

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # Add a tooltip on remember me to include session timeouts.
        persistent_timeout = cherrypy.config.get('tools.sessions_timeout.persistent_timeout', -1)
        idle_timeout = cherrypy.config.get('tools.sessions.timeout', -1)
        title = _(
            "Check this to stay signed in for %d day(s). If left unchecked, your session will end after %d hour(s) of inactivity."
        ) % (persistent_timeout // 1440, idle_timeout // 60)
        self.persistent.render_kw['label-title'] = title


class LoginPage:
    """
    Show a login page to the user if not authenticated.
    """

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['GET', 'POST'])
    @cherrypy.tools.jinja2(template='login.html')
    @cherrypy.tools.ratelimit(methods=['POST'])
    def index(self, **kwargs):

        # Redirect user to dashboard if already login
        if getattr(cherrypy.request, 'login', False):
            raise cherrypy.HTTPRedirect(url_for('dashboard'))

        #  When data is submited, validate credentials.
        form = LoginForm(data=cherrypy.request.params)
        if form.validate_on_submit():
            userobj = cherrypy.tools.auth.login_with_credentials(form.login.data, form.password.data)
            if userobj:
                cherrypy.tools.sessions_timeout.set_persistent(form.persistent.data)
                raise cherrypy.tools.auth.redirect_to_original_url()
            else:
                flash(_("Invalid login or password."))
        elif form.error_message:
            flash(form.error_message)

        return {'form': form}
