from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify
from werkzeug.security import generate_password_hash, check_password_hash
from app.models.user import User, db
from app.utils.email import send_verification_email, generate_verification_code
import logging
from functools import wraps
import time
from datetime import datetime, timedelta

# 创建蓝图
user_bp = Blueprint('user', __name__)


# 使用内存字典代替Redis存储验证码
class VerificationStore:
    def __init__(self):
        self.codes = {}  # 存储格式: {email: {'code': code, 'expires': timestamp}}

    def setex(self, email, seconds, code):
        """设置验证码并指定过期时间"""
        expiry = datetime.now() + timedelta(seconds=seconds)
        self.codes[email] = {'code': code, 'expires': expiry}
        return True

    def get(self, email):
        """获取验证码，如果过期则返回None"""
        if email not in self.codes:
            return None

        data = self.codes[email]
        if datetime.now() > data['expires']:
            # 验证码已过期，删除它
            self.delete(email)
            return None

        return data['code']

    def delete(self, email):
        """删除验证码"""
        if email in self.codes:
            del self.codes[email]
        return True


# 使用内存存储验证码
verification_codes = VerificationStore()


def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            return redirect(url_for('user.login'))
        return f(*args, **kwargs)

    return decorated_function


@user_bp.route('/login', methods=['GET', 'POST'])
def login():
    # 保持原代码不变
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        remember_me = request.form.get('remember_me') == 'on'

        if not username or not password:
            return render_template('login.html', error='用户名和密码不能为空')

        # 检查用户是否存在
        user = User.query.filter((User.username == username) | (User.email == username)).first()

        if not user or not user.check_password(password):
            return render_template('login.html', error='用户名或密码错误')

        if user.status == 0:
            return render_template('login.html', error='账号已被禁用，请联系管理员')

        # 登录成功，保存用户信息到会话
        session['user_id'] = user.id
        session['username'] = user.username
        session['role_id'] = user.role_id

        if remember_me:
            # 设置会话过期时间为7天
            session.permanent = True

        # 记录登录日志（可选）
        # log_user_action('用户登录')

        # 重定向到首页
        return redirect(url_for('index'))

    return render_template('login.html')


@user_bp.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form.get('username')
        email = request.form.get('email')
        password = request.form.get('password')
        confirm_password = request.form.get('confirm_password')
        verification_code = request.form.get('verification_code')

        # 验证表单数据
        if not username or not email or not password or not confirm_password or not verification_code:
            return render_template('register.html', error='所有字段都是必填项')

        if password != confirm_password:
            return render_template('register.html', error='两次输入的密码不匹配')

        # 检查用户名和邮箱是否已存在
        if User.query.filter_by(username=username).first():
            return render_template('register.html', error='用户名已存在')

        if User.query.filter_by(email=email).first():
            return render_template('register.html', error='邮箱已被注册')

        # 验证验证码
        stored_code = verification_codes.get(email)
        if not stored_code or stored_code != verification_code:
            return render_template('register.html', error='验证码无效或已过期')

        # 创建新用户
        try:
            new_user = User(
                username=username,
                password=password,  # 密码会在模型中自动哈希
                email=email,
                nickname=username  # 默认昵称与用户名相同
            )
            db.session.add(new_user)
            db.session.commit()

            # 清除验证码
            verification_codes.delete(email)

            flash('注册成功，请登录', 'success')
            return redirect(url_for('user.login'))
        except Exception as e:
            db.session.rollback()
            logging.error(f"User registration failed: {str(e)}")
            return render_template('register.html', error='注册失败，请稍后重试')

    return render_template('register.html')


@user_bp.route('/logout')
def logout():
    # 清除会话数据
    session.pop('user_id', None)
    session.pop('username', None)
    session.pop('role_id', None)
    return redirect(url_for('user.login'))


@user_bp.route('/send_verification_code', methods=['POST'])
def send_verification_code():
    data = request.get_json()
    email = data.get('email')

    if not email:
        return jsonify({'success': False, 'message': '请提供邮箱地址'})

    # 检查邮箱格式
    import re
    if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
        return jsonify({'success': False, 'message': '邮箱格式不正确'})

    # 生成验证码
    code = generate_verification_code()

    # 存储验证码(10分钟有效)
    verification_codes.setex(email, 600, code)  # 10分钟过期

    # 发送验证码邮件
    if send_verification_email(email, code):
        return jsonify({'success': True, 'message': '验证码已发送'})
    else:
        return jsonify({'success': False, 'message': '邮件发送失败，请稍后重试'})
