from flask import render_template, request, url_for, redirect, flash, session, g, jsonify
from app.routes.auth import bp
from app.services.auth import AuthService
from app.models.database.models import User, db, ChallengeRecord
from app.services.auth.decorators import login_required

@bp.route('/register', methods=['GET', 'POST'])
def register():
    """用户注册页面和处理"""
    from app.models.database.models import SystemConfig

    # 检查是否允许注册
    if not SystemConfig.is_registration_enabled():
        flash('系统当前不允许注册，请联系管理员', 'warning')
        return redirect(url_for('auth.login'))

    # 如果用户已登录，重定向到首页
    if hasattr(g, 'user') and g.user:
        return redirect(url_for('main.index'))

    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')

        # 验证表单数据
        if not username or not email or not password:
            flash('请填写所有必填字段', 'danger')
            return render_template('pages/auth/register.html')

        if password != confirm_password:
            flash('两次输入的密码不一致', 'danger')
            return render_template('pages/auth/register.html')

        # 注册用户
        success, result = AuthService.register_user(username, email, password)

        if success:
            flash('注册成功，请登录', 'success')
            return redirect(url_for('auth.login'))
        else:
            flash(f'注册失败: {result}', 'danger')

    return render_template('pages/auth/register.html')

@bp.route('/login', methods=['GET', 'POST'])
def login():
    """用户登录页面和处理"""
    # 如果用户已登录，重定向到首页
    if hasattr(g, 'user') and g.user:
        return redirect(url_for('main.index'))

    # 获取next参数
    next_url = request.args.get('next') or url_for('main.index')

    if request.method == 'POST':
        username_or_email = request.form.get('username')
        password = request.form.get('password')
        remember = request.form.get('remember') == 'on'

        # 验证表单数据
        if not username_or_email or not password:
            flash('请填写所有必填字段', 'danger')
            return render_template('pages/auth/login.html', next=next_url)

        # 验证用户
        user = AuthService.authenticate_user(username_or_email, password)

        if user:
            # 创建会话
            AuthService.create_session(user, remember)
            flash(f'欢迎回来，{user.username}！', 'success')
            return redirect(next_url)
        else:
            flash('用户名或密码错误', 'danger')

    return render_template('pages/auth/login.html', next=next_url)

@bp.route('/logout')
def logout():
    """用户登出处理"""
    AuthService.logout()
    flash('您已成功登出', 'success')
    return redirect(url_for('main.index'))

@bp.route('/profile', methods=['GET', 'POST'])
@login_required
def profile():
    """用户个人中心页面"""
    # POST请求处理更新用户信息
    if request.method == 'POST':
        # 检查是否是AJAX请求
        is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'

        # 获取表单数据
        email = request.form.get('email')
        avatar = request.form.get('avatar')

        # 验证数据
        if not email:
            message = '电子邮箱不能为空'
            if is_ajax:
                return jsonify({'success': False, 'message': message})
            flash(message, 'danger')
        else:
            # 更新用户信息
            try:
                # 检查邮箱是否已被其他用户使用
                existing_user = User.query.filter(User.email == email, User.id != g.user.id).first()
                if existing_user:
                    message = '该电子邮箱已被使用'
                    if is_ajax:
                        return jsonify({'success': False, 'message': message})
                    flash(message, 'danger')
                else:
                    g.user.email = email
                    g.user.avatar = avatar if avatar.strip() else None
                    db.session.commit()
                    message = '个人信息已更新'

                    if is_ajax:
                        return jsonify({
                            'success': True,
                            'message': message,
                            'user': g.user.to_dict()
                        })
                    flash(message, 'success')
            except Exception as e:
                db.session.rollback()
                message = f'更新失败: {str(e)}'
                if is_ajax:
                    return jsonify({'success': False, 'message': message})
                flash(message, 'danger')

    # 获取方向筛选参数
    challenges_category = request.args.get('category', 'all')

    # 查询用户的题目
    challenges_query = ChallengeRecord.query.filter_by(user_id=g.user.id)
    if challenges_category and challenges_category != 'all':
        challenges_query = challenges_query.filter_by(challenge_type=challenges_category)
    challenges = challenges_query.order_by(ChallengeRecord.created_at.desc()).all()

    # 获取所有方向配置
    try:
        from app.models.database.models import CategoryConfig
        all_categories = CategoryConfig.get_all_categories()
        categories_dict = {cat.id: {'name': cat.name, 'icon': cat.icon} for cat in all_categories}
    except:
        categories_dict = {}

    # 统计各方向题目数量
    challenge_counts = {}
    challenge_counts['all'] = ChallengeRecord.query.filter_by(user_id=g.user.id).count()
    for cat_id in categories_dict.keys():
        challenge_counts[cat_id] = ChallengeRecord.query.filter_by(user_id=g.user.id, challenge_type=cat_id).count()

    # 检查Docker服务是否可用
    docker_available = False
    try:
        import subprocess
        result = subprocess.run(['docker', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=3)
        docker_available = result.returncode == 0
    except Exception:
        docker_available = False

    return render_template('pages/auth/profile.html',
                         user=g.user,
                         challenges=challenges,
                         challenges_category=challenges_category,
                         categories_dict=categories_dict,
                         challenge_counts=challenge_counts,
                         docker_available=docker_available)

@bp.route('/api/my/challenges/<int:challenge_id>', methods=['DELETE'])
@login_required
def api_delete_my_challenge(challenge_id: int):
    """删除当前用户的某个题目记录（个人中心）"""
    try:
        from app.models.database.operations import get_challenge_record, delete_challenge
        if not hasattr(g, 'user') or not g.user:
            return jsonify({'success': False, 'error': 'unauthorized'}), 401
        record = get_challenge_record(int(challenge_id))
        if not record:
            return jsonify({'success': False, 'error': 'not_found'}), 404
        if record.get('user_id') != g.user.id and g.user.role != 'admin':
            return jsonify({'success': False, 'error': 'forbidden'}), 403
        ok = delete_challenge(int(challenge_id))
        if ok:
            return jsonify({'success': True})
        return jsonify({'success': False, 'error': 'delete_failed'}), 500
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@bp.route('/api/change-password', methods=['POST'])
@login_required
def api_change_password():
    """修改当前用户密码"""
    from werkzeug.security import check_password_hash, generate_password_hash
    
    try:
        data = request.get_json()
        current_password = data.get('current_password')
        new_password = data.get('new_password')
        
        if not current_password or not new_password:
            return jsonify({'success': False, 'message': '请填写所有字段'}), 400
        
        if len(new_password) < 6:
            return jsonify({'success': False, 'message': '新密码长度至少6个字符'}), 400
        
        # 验证当前密码
        if not check_password_hash(g.user.password_hash, current_password):
            return jsonify({'success': False, 'message': '当前密码错误'}), 400
        
        # 更新密码
        g.user.password_hash = generate_password_hash(new_password, method='pbkdf2:sha256')
        db.session.commit()
        
        return jsonify({'success': True, 'message': '密码修改成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': f'修改失败: {str(e)}'}), 500
