from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify, current_app
from flask_mail import Message
from utils.i18n import t
from models.user_model import UserModel
import secrets
import string

auth_bp = Blueprint('auth', __name__)

def get_mail():
    """Get mail instance from app"""
    from app import mail
    return mail

def generate_reset_token():
    return ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(32))

def login_required(f):
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            return redirect(url_for('auth.login'))
        return f(*args, **kwargs)
    decorated_function.__name__ = f.__name__
    return decorated_function

def admin_required(f):
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            return redirect(url_for('auth.login'))
        if session.get('user_role') != 'admin':
            flash(t('messages.access_denied', 'Access denied. Administrator privileges required.'), 'error')
            return redirect(url_for('dashboard.index'))
        return f(*args, **kwargs)
    decorated_function.__name__ = f.__name__
    return decorated_function

@auth_bp.route('/')
def index():
    if 'user_id' in session:
        return redirect(url_for('dashboard.index'))
    return redirect(url_for('auth.login'))

@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    if 'user_id' in session:
        return redirect(url_for('dashboard.index'))
    
    print(f"Request method: {request.method}")
    print(f"Form data: {request.form}")
    
    if request.method == 'POST':
        email = request.form.get('email')
        password = request.form.get('password')
        
        print(f"Email: {email}, Password: {'*' * len(password) if password else None}")
        
        if not email or not password:
            flash(t('messages.login_required_fields', 'Email and password are required'), 'error')
            return render_template('auth/login.html')
        
        user = UserModel.get_user_by_email(email)
        print(f"User found: {user is not None}")
        
        if user and UserModel.verify_password(password, user['password']):
            session['user_id'] = user['id']
            session['user_name'] = user['name']
            session['user_email'] = user['email']
            session['user_role'] = user['role']
            # Set language preference in session (default handled elsewhere)
            if 'lang' in user and user['lang']:
                session['lang'] = user['lang']
            flash(t('messages.login_success', 'Login successful!'), 'success')
            return redirect(url_for('dashboard.index'))
        else:
            flash(t('messages.invalid_credentials', 'Invalid email or password'), 'error')
    
    return render_template('auth/login.html')

@auth_bp.route('/logout')
def logout():
    session.clear()
    flash(t('messages.logout_success', 'You have been logged out successfully'), 'success')
    return redirect(url_for('auth.login'))

@auth_bp.route('/forgot-password', methods=['GET', 'POST'])
def forgot_password():
    if request.method == 'POST':
        email = request.form.get('email')

        if not email:
            flash(t('messages.email_required', 'Email is required'), 'error')
            return render_template('auth/forgot_password.html')

        user = UserModel.get_user_by_email(email)

        # Always show the same message to prevent email enumeration
        if user:
            try:
                # Get system settings for branding
                from models.settings_model import SettingsModel
                settings = SettingsModel.get_settings()
                app_title = settings.get('title', 'Survey Manager') if settings else 'Survey Manager'

                # Generate logo HTML if exists
                logo_html = ''
                if settings and settings.get('logo'):
                    logo_url = url_for('static', filename=settings['logo'], _external=True)
                    logo_html = f'<img src="{logo_url}" alt="{app_title}" style="max-height: 60px; max-width: 200px; object-fit: contain; margin-bottom: 15px;">'

                # Generate reset token
                token = UserModel.create_password_reset_token(user['id'], expiration_hours=1)

                # Build reset URL
                reset_url = url_for('auth.reset_password', token=token, _external=True)

                # Send email
                mail = get_mail()
                msg = Message(
                    subject=f'Password Reset - {app_title}',
                    recipients=[email],
                    sender=current_app.config['MAIL_DEFAULT_SENDER']
                )

                msg.html = f"""
                <html>
                <head>
                    <style>
                        body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }}
                        .container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
                        .header {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 10px 10px 0 0; }}
                        .content {{ background: #f9f9f9; padding: 30px; border-radius: 0 0 10px 10px; }}
                        .button {{ display: inline-block; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 5px; margin: 20px 0; }}
                        .footer {{ text-align: center; margin-top: 20px; color: #666; font-size: 12px; }}
                        .warning {{ background: #fff3cd; border-left: 4px solid #ffc107; padding: 10px; margin: 15px 0; }}
                    </style>
                </head>
                <body>
                    <div class="container">
                        <div class="header">
                            {logo_html}
                            <h1>🔑 Password Reset Request</h1>
                            <p style="margin: 10px 0 0 0; font-size: 16px;">{app_title}</p>
                        </div>
                        <div class="content">
                            <p>Hello <strong>{user['name']}</strong>,</p>

                            <p>We received a request to reset your password for your {app_title} account.</p>

                            <p>Click the button below to reset your password:</p>

                            <center>
                                <a href="{reset_url}" class="button">Reset Password</a>
                            </center>

                            <p>Or copy and paste this link into your browser:</p>
                            <p style="word-break: break-all; background: #fff; padding: 10px; border: 1px solid #ddd;">
                                {reset_url}
                            </p>

                            <div class="warning">
                                <strong>⏱️ Important:</strong> This link will expire in <strong>1 hour</strong>.
                            </div>

                            <p>If you didn't request this password reset, you can safely ignore this email. Your password will remain unchanged.</p>

                            <p>Best regards,<br>
                            <strong>{app_title} Team</strong></p>
                        </div>
                        <div class="footer">
                            <p>This is an automated email. Please do not reply to this message.</p>
                        </div>
                    </div>
                </body>
                </html>
                """

                mail.send(msg)

            except Exception as e:
                print(f"Error sending email: {str(e)}")
                # Don't show error to user for security reasons

        msg = t('messages.forgot_password_info', 'If the email exists in our system, you will receive password reset instructions.')
        flash(msg, 'info')
        return redirect(url_for('auth.forgot_password'))

    return render_template('auth/forgot_password.html')

@auth_bp.route('/reset-password/<token>', methods=['GET', 'POST'])
def reset_password(token):
    # Verify token
    token_data = UserModel.verify_reset_token(token)

    if not token_data:
        flash(t('messages.invalid_expired_token', 'This password reset link is invalid or has expired.'), 'error')
        return redirect(url_for('auth.forgot_password'))

    if request.method == 'POST':
        new_password = request.form.get('new_password')
        confirm_password = request.form.get('confirm_password')

        if not new_password or not confirm_password:
            flash(t('messages.all_fields_required', 'All fields are required'), 'error')
            return render_template('auth/reset_password.html', token=token, user=token_data)

        if new_password != confirm_password:
            flash(t('messages.passwords_not_match', 'Passwords do not match'), 'error')
            return render_template('auth/reset_password.html', token=token, user=token_data)

        if len(new_password) < 6:
            flash(t('messages.password_too_short', 'Password must be at least 6 characters long'), 'error')
            return render_template('auth/reset_password.html', token=token, user=token_data)

        # Reset password
        if UserModel.reset_password_with_token(token, new_password):
            flash(t('messages.password_reset_success', 'Your password has been reset successfully! You can now login with your new password.'), 'success')
            return redirect(url_for('auth.login'))
        else:
            flash(t('messages.password_reset_error', 'An error occurred while resetting your password.'), 'error')
            return redirect(url_for('auth.forgot_password'))

    return render_template('auth/reset_password.html', token=token, user=token_data)

@auth_bp.route('/profile', methods=['GET', 'POST'])
@login_required
def profile():
    user = UserModel.get_user_by_id(session['user_id'])
    
    if request.method == 'POST':
        name = request.form.get('name')
        email = request.form.get('email')
        lang = request.form.get('lang', 'es')
        current_password = request.form.get('current_password')
        new_password = request.form.get('new_password')
        confirm_password = request.form.get('confirm_password')
        
        if not name or not email:
            flash(t('messages.name_email_required', 'Name and email are required'), 'error')
            return render_template('auth/profile.html', user=user)
        
        if email != user['email']:
            existing_user = UserModel.get_user_by_email(email)
            if existing_user and existing_user['id'] != user['id']:
                flash(t('messages.email_exists', 'Email already exists'), 'error')
                return render_template('auth/profile.html', user=user)
        
        UserModel.update_user(user['id'], name, email, user['role'])
        # Update language preference
        if lang in ['es', 'en']:
            UserModel.update_user_lang(user['id'], lang)
            session['lang'] = lang
        session['user_name'] = name
        session['user_email'] = email
        
        if current_password and new_password:
            if not UserModel.verify_password(current_password, user['password']):
                flash(t('messages.current_password_incorrect', 'Current password is incorrect'), 'error')
                return render_template('auth/profile.html', user=user)
            
            if new_password != confirm_password:
                flash(t('messages.passwords_not_match', 'New passwords do not match'), 'error')
                return render_template('auth/profile.html', user=user)
            
            if len(new_password) < 6:
                flash(t('messages.password_too_short', 'Password must be at least 6 characters long'), 'error')
                return render_template('auth/profile.html', user=user)
            
            UserModel.update_user_password(user['id'], new_password)
            flash(t('messages.profile_password_updated', 'Profile and password updated successfully!'), 'success')
        else:
            flash(t('messages.profile_updated', 'Profile updated successfully!'), 'success')
        
        user = UserModel.get_user_by_id(session['user_id'])
    
    return render_template('auth/profile.html', user=user)

@auth_bp.route('/set-lang', methods=['POST'])
def set_lang():
    lang = request.form.get('lang') or (request.json.get('lang') if request.is_json else None)
    if lang not in ['es', 'en']:
        return jsonify({"ok": False, "error": "invalid_lang"}), 400
    session['lang'] = lang
    # Persist if logged in
    if 'user_id' in session:
        try:
            UserModel.update_user_lang(session['user_id'], lang)
        except Exception:
            pass
    return jsonify({"ok": True, "lang": lang})
