from flask import Flask, render_template, request, jsonify, session
import json
import os
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
import secrets

app = Flask(__name__)
app.secret_key = secrets.token_hex(16)

# JSON file paths
PARTICIPANTS_FILE = 'data/participants.json'
USERS_FILE = 'data/users.json'

def ensure_data_directory():
    """Create data directory if it doesn't exist"""
    os.makedirs('data', exist_ok=True)

def load_json_file(filename, default=None):
    """Load data from JSON file"""
    if default is None:
        default = []
    
    if not os.path.exists(filename):
        return default
    
    try:
        with open(filename, 'r') as f:
            return json.load(f)
    except (json.JSONDecodeError, FileNotFoundError):
        return default

def save_json_file(filename, data):
    """Save data to JSON file"""
    ensure_data_directory()
    with open(filename, 'w') as f:
        json.dump(data, f, indent=2)

def init_users():
    """Initialize users.json with admin user if it doesn't exist"""
    users = load_json_file(USERS_FILE, [])
    
    # Check if admin user exists
    admin_exists = any(user['email'] == 'admin@ces.com' for user in users)
    
    if not admin_exists:
        admin_user = {
            'id': len(users) + 1,
            'email': 'admin@ces.com',
            'password_hash': generate_password_hash('admin123'),
            'user_type': 'admin',
            'created_at': datetime.now().isoformat()
        }
        users.append(admin_user)
        save_json_file(USERS_FILE, users)

# Initialize on startup
ensure_data_directory()
init_users()

@app.route('/')
def index():
    """Serve the main HTML page"""
    return render_template('index.html')

@app.route('/api/register', methods=['POST'])
def register():
    """Handle participant registration"""
    try:
        data = request.json
        
        # Validate required fields
        required_fields = ['firstName', 'lastName', 'email', 'phone', 'age', 'motivation']
        for field in required_fields:
            if not data.get(field):
                return jsonify({'error': f'Missing required field: {field}'}), 400
        
        # Load existing participants
        participants = load_json_file(PARTICIPANTS_FILE, [])
        
        # Check for duplicate email
        if any(p['email'] == data['email'] for p in participants):
            return jsonify({'error': 'A participant with this email is already registered'}), 400
        
        # Create new participant record
        participant = {
            'id': len(participants) + 1,
            'timestamp': datetime.now().isoformat(),
            'firstName': data['firstName'],
            'lastName': data['lastName'],
            'email': data['email'],
            'phone': data['phone'],
            'age': int(data['age']),
            'education': data.get('education', 'highschool'),
            'mathBackground': data.get('mathBackground', 'basic'),
            'programmingExp': data.get('programmingExp', 'none'),
            'motivation': data['motivation'],
            'emergencyContact': data.get('emergencyContact', '')
        }
        
        # Add to participants list and save
        participants.append(participant)
        save_json_file(PARTICIPANTS_FILE, participants)
        
        return jsonify({'message': 'Registration successful', 'id': participant['id']}), 201
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/login', methods=['POST'])
def login():
    """Handle user login"""
    try:
        data = request.json
        email = data.get('email')
        password = data.get('password')
        
        if not email or not password:
            return jsonify({'error': 'Email and password required'}), 400
        
        # Check admin login
        users = load_json_file(USERS_FILE, [])
        admin_user = next((u for u in users if u['email'] == email and u['user_type'] == 'admin'), None)
        
        if admin_user and check_password_hash(admin_user['password_hash'], password):
            session['user'] = {
                'type': 'admin',
                'email': email,
                'name': 'Administrator'
            }
            return jsonify({
                'message': 'Login successful',
                'user': session['user']
            }), 200
        
        # Check participant login (email + phone as password)
        participants = load_json_file(PARTICIPANTS_FILE, [])
        participant = next((p for p in participants if p['email'] == email and p['phone'] == password), None)
        
        if participant:
            session['user'] = {
                'type': 'participant',
                'email': email,
                'name': f"{participant['firstName']} {participant['lastName']}",
                'data': participant
            }
            return jsonify({
                'message': 'Login successful',
                'user': session['user']
            }), 200
        
        return jsonify({'error': 'Invalid credentials'}), 401
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/logout', methods=['POST'])
def logout():
    """Handle user logout"""
    session.pop('user', None)
    return jsonify({'message': 'Logged out successfully'}), 200

@app.route('/api/participants', methods=['GET'])
def get_participants():
    """Get all participants (admin only)"""
    if 'user' not in session or session['user']['type'] != 'admin':
        return jsonify({'error': 'Admin access required'}), 403
    
    participants = load_json_file(PARTICIPANTS_FILE, [])
    return jsonify(participants), 200

@app.route('/api/participants/stats', methods=['GET'])
def get_stats():
    """Get registration statistics (admin only)"""
    if 'user' not in session or session['user']['type'] != 'admin':
        return jsonify({'error': 'Admin access required'}), 403
    
    participants = load_json_file(PARTICIPANTS_FILE, [])
    
    # Calculate statistics
    total = len(participants)
    
    # Age groups
    age_groups = {'Under 18': 0, '18-29': 0, '30-49': 0, '50+': 0}
    for p in participants:
        age = p['age']
        if age < 18:
            age_groups['Under 18'] += 1
        elif age < 30:
            age_groups['18-29'] += 1
        elif age < 50:
            age_groups['30-49'] += 1
        else:
            age_groups['50+'] += 1
    
    # Math backgrounds
    math_levels = {}
    for p in participants:
        level = p['mathBackground']
        math_levels[level] = math_levels.get(level, 0) + 1
    
    # Programming experience
    prog_levels = {}
    for p in participants:
        level = p['programmingExp']
        prog_levels[level] = prog_levels.get(level, 0) + 1
    
    # Education levels
    edu_levels = {}
    for p in participants:
        level = p['education']
        edu_levels[level] = edu_levels.get(level, 0) + 1
    
    return jsonify({
        'total': total,
        'ageGroups': age_groups,
        'mathLevels': math_levels,
        'programmingLevels': prog_levels,
        'educationLevels': edu_levels
    }), 200

@app.route('/api/participants/export', methods=['GET'])
def export_participants():
    """Export participants data as JSON (admin only)"""
    if 'user' not in session or session['user']['type'] != 'admin':
        return jsonify({'error': 'Admin access required'}), 403
    
    participants = load_json_file(PARTICIPANTS_FILE, [])
    
    # Create response with proper headers for download
    response = app.response_class(
        response=json.dumps(participants, indent=2),
        status=200,
        mimetype='application/json'
    )
    response.headers['Content-Disposition'] = f'attachment; filename=ces_participants_{datetime.now().strftime("%Y%m%d")}.json'
    return response

@app.route('/api/participants/clear', methods=['DELETE'])
def clear_participants():
    """Clear all participants (admin only)"""
    if 'user' not in session or session['user']['type'] != 'admin':
        return jsonify({'error': 'Admin access required'}), 403
    
    save_json_file(PARTICIPANTS_FILE, [])
    return jsonify({'message': 'All participants cleared'}), 200

@app.route('/api/user/session', methods=['GET'])
def get_session():
    """Get current user session"""
    if 'user' in session:
        return jsonify(session['user']), 200
    else:
        return jsonify({'error': 'Not logged in'}), 401

@app.route('/api/health', methods=['GET'])
def health_check():
    """Simple health check endpoint"""
    return jsonify({
        'status': 'healthy',
        'timestamp': datetime.now().isoformat(),
        'participants_count': len(load_json_file(PARTICIPANTS_FILE, []))
    }), 200

# Error handlers
@app.errorhandler(404)
def not_found(error):
    return jsonify({'error': 'Endpoint not found'}), 404

@app.errorhandler(500)
def internal_error(error):
    return jsonify({'error': 'Internal server error'}), 500

if __name__ == '__main__':
    # Create some sample data if files don't exist (for testing)
    if not os.path.exists(PARTICIPANTS_FILE):
        sample_participants = [
            {
                'id': 1,
                'timestamp': datetime.now().isoformat(),
                'firstName': 'Maria',
                'lastName': 'Santos',
                'email': 'maria.santos@email.com',
                'phone': '09123456789',
                'age': 16,
                'education': 'highschool',
                'mathBackground': 'intermediate',
                'programmingExp': 'none',
                'motivation': 'I want to learn how mathematics can be fun and visual through programming.',
                'emergencyContact': 'Carmen Santos - 09987654321'
            }
        ]
        save_json_file(PARTICIPANTS_FILE, sample_participants)
    
    app.run(debug=True, host='0.0.0.0', port=8080)