from flask import Blueprint, render_template, redirect, url_for, flash, request, session
from flask_login import login_user, logout_user, login_required, current_user
from cpm_assessment import db, bcrypt
from .models import User, PasswordResetToken
from .forms import RegistrationForm, LoginForm, ChangePasswordForm, ResetPasswordRequestForm, ResetPasswordForm
from cpm_assessment.utils import send_email
import secrets
import os

auth_bp = Blueprint('auth', __name__)

@auth_bp.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
        
        user_role = form.role.data
        is_active_status = True # Default for user and client
        if user_role == 'consultant':
            is_active_status = False # Consultants need admin approval

        user = User(
            username=form.username.data, 
            email=form.email.data, 
            mobile_number=form.mobile_number.data,
            date_of_birth=form.date_of_birth.data,
            gender=form.gender.data,
            password=hashed_password, 
            role=user_role, 
            is_active=is_active_status
        )
        db.session.add(user)
        db.session.commit()
        
        # Send notification to admin
        try:
            html = render_template('email/new_user_notification.html', 
                                   username=user.username, 
                                   email=user.email, 
                                   role=user.role, 
                                   is_active=user.is_active)
            send_email(['admin@vrwellness.in', 'swarunimh@gmail.com'], f"New User Registration: {user.username}", html)
        except Exception as e:
            print(f"Failed to send admin notification: {e}")
        
        if user_role == 'consultant':
            flash('Your consultant account has been created and is awaiting admin approval.', 'info')
        else:
            flash('Your account has been created! You are now able to log in', 'success')
        
        return redirect(url_for('auth.login'))
    return render_template('auth/register.html', form=form)

@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user and bcrypt.check_password_hash(user.password, form.password.data):
            if not user.is_active:
                flash('Your account is not active. Please contact support or wait for admin approval.', 'warning')
                return redirect(url_for('auth.login'))
            login_user(user, remember=form.remember.data)
            next_page = request.args.get('next')
            return redirect(next_page) if next_page else redirect(url_for('main.index'))
        else:
            flash('Login Unsuccessful. Please check email and password', 'danger')
    return render_template('auth/login.html', form=form)

@auth_bp.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('main.index'))

@auth_bp.route('/change_password', methods=['GET', 'POST'])
@login_required
def change_password():
    form = ChangePasswordForm()
    if form.validate_on_submit():
        if bcrypt.check_password_hash(current_user.password, form.old_password.data):
            hashed_password = bcrypt.generate_password_hash(form.new_password.data).decode('utf-8')
            current_user.password = hashed_password
            db.session.commit()
            try:
                from app.utils import send_email
                html_admin = render_template(
                    'email/password_change_notification.html',
                    recipient_name="Admin",
                    username=current_user.username,
                    email=current_user.email,
                    changed_at=""
                )
                send_email(['admin@vrwellness.in', 'swarunimh@gmail.com'], f'Password Changed: {current_user.username}', html_admin)
            except Exception as e:
                print(f"Failed to notify admin about password change: {e}")
            flash('Your password has been updated successfully!', 'success')
            return redirect(url_for('profile.profile'))
        else:
            flash('Current password is incorrect.', 'danger')
    return render_template('auth/change_password.html', form=form)

@auth_bp.route('/reset_password_request', methods=['GET', 'POST'])
def reset_password_request():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    
    form = ResetPasswordRequestForm()
    if form.validate_on_submit():
        user = User.query.filter_by(mobile_number=form.mobile_number.data).first()
        if user:
            # Create a one-time use password reset token
            reset_token = PasswordResetToken(user_id=user.id)
            db.session.add(reset_token)
            db.session.commit()
            
            flash(f'Password reset initiated for mobile number {user.mobile_number}. '
                  f'Your reset token is: {reset_token.token}. Please use this token to reset your password. '
                  f'This token can only be used once and expires in 24 hours.', 'info')
            return redirect(url_for('auth.reset_password'))
    return render_template('auth/reset_password_request.html', form=form)

@auth_bp.route('/reset_password', methods=['GET', 'POST'])
def reset_password():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    
    form = ResetPasswordForm()
    if form.validate_on_submit():
        # Find and validate the one-time use token
        reset_token = PasswordResetToken.find_valid_token(form.token.data)
        if not reset_token:
            # Check if token exists but is used or expired
            existing_token = PasswordResetToken.query.filter_by(token=form.token.data).first()
            if existing_token:
                if existing_token.is_used:
                    return render_template('link_used.html', link_type='password_reset')
                else:
                    return render_template('link_expired.html', link_type='password_reset')
            else:
                return render_template('link_expired.html', link_type='password_reset')
        
        # Mark token as used immediately to prevent reuse
        reset_token.mark_as_used()
        
        # Update user password
        user = reset_token.user
        hashed_password = bcrypt.generate_password_hash(form.new_password.data).decode('utf-8')
        user.password = hashed_password
        db.session.commit()
        
        flash('Your password has been reset successfully! You can now log in.', 'success')
        return redirect(url_for('auth.login'))
    
    return render_template('auth/reset_password.html', form=form)
