"""
User Management Blueprint
Handles user CRUD operations
"""
from flask import Blueprint, render_template, request, jsonify, send_file, session
from werkzeug.security import generate_password_hash, check_password_hash
from blueprints.auth import login_required, can_user, get_current_user
from io import BytesIO
import json
import os

users_bp = Blueprint('users', __name__, url_prefix='/users')

# Path to users file
USERS_FILE = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'users.json')

def load_users():
    """Load users from JSON file"""
    if os.path.exists(USERS_FILE):
        try:
            with open(USERS_FILE, 'r') as f:
                return json.load(f)
        except:
            return []
    return []

def save_users(users):
    """Save users to JSON file"""
    os.makedirs(os.path.dirname(USERS_FILE), exist_ok=True)
    with open(USERS_FILE, 'w') as f:
        json.dump(users, f, indent=2)

def permission_required(permission):
    """Decorator to require specific permission"""
    from functools import wraps
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not can_user(permission):
                return jsonify({
                    'status': 'error',
                    'message': 'Permission denied'
                }), 403
            return f(*args, **kwargs)
        return decorated_function
    return decorator

# Routes
@users_bp.route('/')
@login_required
def user_manager():
    """Serve the user management page"""
    if not can_user('manage_users'):
        return "<h1>403 - Permission Denied</h1><p>You don't have permission to manage users.</p>", 403
    current_user_id = session.get('user_id', -1)
    return render_template('user_manager.html', current_user_id=current_user_id)

@users_bp.route('/api', methods=['GET'])
@login_required
@permission_required('manage_users')
def get_users():
    """Get all users"""
    users = load_users()
    return jsonify({
        'status': 'success',
        'users': users
    })

@users_bp.route('/api', methods=['POST'])
@login_required
@permission_required('manage_users')
def add_user():
    """Add a new user with hashed password"""
    try:
        data = request.json
        
        # Validate required fields
        if not data.get('username') or not data.get('password') or not data.get('defaultLocation'):
            return jsonify({
                'status': 'error',
                'message': 'Username, password, and default location are required'
            }), 400
        
        users = load_users()
        
        # Check if username already exists
        if any(user['username'] == data['username'] for user in users):
            return jsonify({
                'status': 'error',
                'message': 'Username already exists'
            }), 400
        
        # Hash the password
        hashed_password = generate_password_hash(data['password'], method='pbkdf2:sha256')
        
        # Get location settings
        location_settings = data.get('locationSettings', {})
        default_location = data['defaultLocation']
        
        # Ensure default location is accessible
        if default_location not in location_settings:
            location_settings[default_location] = {}
        location_settings[default_location]['accessible'] = True
        
        # Create new user
        new_user = {
            'username': data['username'],
            'password': hashed_password,
            'defaultLocation': default_location,
            'locationSettings': location_settings,
            'permissions': data.get('permissions', {}),
            'active': data.get('active', True)
        }
        
        users.append(new_user)
        save_users(users)
        
        return jsonify({
            'status': 'success',
            'message': 'User added successfully',
            'users': users
        })
    
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500

@users_bp.route('/api/<int:user_index>', methods=['DELETE'])
@login_required
@permission_required('manage_users')
def delete_user(user_index):
    """Delete a specific user by index"""
    try:
        users = load_users()
        
        if user_index < 0 or user_index >= len(users):
            return jsonify({
                'status': 'error',
                'message': 'Invalid user index'
            }), 400
        
        users.pop(user_index)
        save_users(users)
        
        return jsonify({
            'status': 'success',
            'message': 'User deleted successfully',
            'users': users
        })
    
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500

@users_bp.route('/api/<int:user_index>/active', methods=['PATCH'])
@login_required
@permission_required('manage_users')
def toggle_user_active(user_index):
    """Toggle user active status"""
    try:
        data = request.json
        users = load_users()
        
        if user_index < 0 or user_index >= len(users):
            return jsonify({
                'status': 'error',
                'message': 'Invalid user index'
            }), 400
        
        users[user_index]['active'] = data.get('active', True)
        save_users(users)
        
        return jsonify({
            'status': 'success',
            'message': 'User status updated',
            'users': users
        })
    
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500

@users_bp.route('/api/<int:user_index>/change-password', methods=['POST'])
@login_required
@permission_required('manage_users')
def change_user_password(user_index):
    """Change a user's password with current user verification"""
    try:
        data = request.json
        new_password = data.get('newPassword')
        current_user_password = data.get('currentUserPassword')
        
        if not new_password or not current_user_password:
            return jsonify({
                'status': 'error',
                'message': 'New password and current user password are required'
            }), 400
        
        if len(new_password) < 6:
            return jsonify({
                'status': 'error',
                'message': 'Password must be at least 6 characters long'
            }), 400
        
        # Verify current user's password
        current_user = get_current_user()
        if not current_user:
            return jsonify({
                'status': 'error',
                'message': 'Not authenticated'
            }), 401
        
        if not check_password_hash(current_user['password'], current_user_password):
            return jsonify({
                'status': 'error',
                'message': 'Your password is incorrect. Password change denied for security reasons.'
            }), 403
        
        # Load users and validate index
        users = load_users()
        if user_index < 0 or user_index >= len(users):
            return jsonify({
                'status': 'error',
                'message': 'Invalid user index'
            }), 400
        
        # Update password
        hashed_password = generate_password_hash(new_password, method='pbkdf2:sha256')
        target_username = users[user_index]['username']
        users[user_index]['password'] = hashed_password
        save_users(users)
        
        return jsonify({
            'status': 'success',
            'message': f'Password changed successfully for user "{target_username}"'
        })
    
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500

@users_bp.route('/api/download')
@login_required
@permission_required('manage_users')
def download_users():
    """Download users as JSON file"""
    try:
        users = load_users()
        
        if not users:
            return jsonify({
                'status': 'error',
                'message': 'No users to download'
            }), 400
        
        json_data = json.dumps(users, indent=2)
        
        return send_file(
            BytesIO(json_data.encode()),
            mimetype='application/json',
            as_attachment=True,
            download_name='users.json'
        )
    
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500
