# plugins/auth/routes.py

from datetime import datetime
from flask import (
    Blueprint, render_template, redirect, flash, url_for, request
)
from flask_login import (
    login_user, logout_user, login_required, current_user
)
from app import db
from .models import User, Invitation
from .forms import (
    LoginForm, RegistrationForm, InviteForm, AdjustInvitesForm
)

bp = Blueprint(
    'auth',
    __name__,
    template_folder='templates',
    url_prefix='/auth'
)


@bp.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('home'))
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data.lower()).first()
        if user and user.check_password(form.password.data):
            login_user(user, remember=form.remember_me.data)
            flash('Logged in successfully.', 'success')
            next_page = request.args.get('next') or url_for('home')
            return redirect(next_page)
        flash('Invalid email or password.', 'danger')
    return render_template('auth/login.html', form=form)


@bp.route('/logout')
@login_required
def logout():
    logout_user()
    flash('Logged out.', 'info')
    return redirect(url_for('home'))


@bp.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('home'))

    invite_code = request.args.get('invite', '').strip()
    form = RegistrationForm(invitation_code=invite_code)

    if form.validate_on_submit():
        # Validate invitation
        invitation = Invitation.query.filter_by(
            code=form.invitation_code.data,
            is_active=True,
            is_used=False
        ).first()
        if not invitation:
            flash('Registration is by invitation only. Provide a valid code.', 'warning')
            return render_template('auth/register.html', form=form)

        if invitation.recipient_email and \
           invitation.recipient_email.lower() != form.email.data.lower():
            flash('This invitation is not valid for that email address.', 'warning')
            return render_template('auth/register.html', form=form)

        # Create the user
        user = User(email=form.email.data.lower())
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.flush()

        # Mark invitation used
        invitation.mark_used(user, request.remote_addr)
        db.session.commit()

        flash('Account created! Please log in.', 'success')
        return redirect(url_for('auth.login'))

    return render_template('auth/register.html', form=form)


@bp.route('/invite', methods=['GET', 'POST'])
@login_required
def send_invite():
    form = InviteForm()

    # Block banned/suspended users from sending
    if current_user.is_banned or current_user.is_deleted or (
        current_user.suspended_until and current_user.suspended_until > datetime.utcnow()
    ):
        flash('You are not permitted to send invitations.', 'warning')
        return redirect(url_for('home'))

    if form.validate_on_submit():
        if current_user.invites_remaining < 1:
            flash('No invites remaining. Ask an admin to increase your quota.', 'danger')
        else:
            recipient = form.email.data.strip().lower()
            inv = Invitation(
                recipient_email=recipient,
                created_by=current_user.id,
                sender_ip=request.remote_addr
            )
            db.session.add(inv)
            current_user.invites_remaining -= 1
            db.session.commit()
            flash(f'Invitation sent to {recipient}.', 'success')
        return redirect(url_for('auth.send_invite'))

    return render_template(
        'auth/invite.html',
        form=form,
        invites=current_user.invites_remaining
    )


@bp.route('/admin/adjust_invites/<int:user_id>', methods=['GET', 'POST'])
@login_required
def adjust_invites(user_id):
    # assume current_user has admin rights
    user = User.query.get_or_404(user_id)
    form = AdjustInvitesForm()
    if form.validate_on_submit():
        user.invites_remaining = max(0, user.invites_remaining + form.delta.data)
        db.session.commit()
        flash(f"{user.email}'s invite quota adjusted by {form.delta.data}.", 'info')
        return redirect(url_for('admin.user_list'))
    return render_template(
        'auth/adjust_invites.html',
        form=form,
        user=user
    )
