import logging
import os
from datetime import datetime
from flask import render_template, request, jsonify, redirect, url_for, flash, current_app
from flask_login import login_required, current_user
from app.main import bp
from app import db
from app.upload.file_handler import get_file_upload_handler
from app.upload.fixture_parser import get_fixture_parser
from app.utils.security import require_admin, require_active_user

logger = logging.getLogger(__name__)

@bp.route('/')
def index():
    """Home page"""
    # Check if database is available
    try:
        from app.database import get_db_manager
        db_manager = get_db_manager()
        if not db_manager.test_connection():
            # Add logging to debug template loading
            logger.info(f"Template folder path: {current_app.template_folder}")
            logger.info(f"Template folder exists: {os.path.exists(current_app.template_folder) if current_app.template_folder else 'None'}")
            template_path = os.path.join(current_app.template_folder or '', 'setup', 'database.html')
            logger.info(f"Full template path: {template_path}")
            logger.info(f"Template file exists: {os.path.exists(template_path)}")
            return render_template('setup/database.html')
    except Exception as e:
        logger.warning(f"Database check failed: {str(e)}")
        # Add logging to debug template loading
        logger.info(f"Template folder path: {current_app.template_folder}")
        logger.info(f"Template folder exists: {os.path.exists(current_app.template_folder) if current_app.template_folder else 'None'}")
        template_path = os.path.join(current_app.template_folder or '', 'setup', 'database.html')
        logger.info(f"Full template path: {template_path}")
        logger.info(f"Template file exists: {os.path.exists(template_path)}")
        return render_template('setup/database.html')
    
    if current_user.is_authenticated:
        return redirect(url_for('main.dashboard'))
    return render_template('main/index.html')

@bp.route('/dashboard')
@login_required
@require_active_user
def dashboard():
    """Main dashboard"""
    try:
        # Check if database is available
        from app.database import get_db_manager
        db_manager = get_db_manager()
        if not db_manager.test_connection():
            flash('Database connection failed. Please check database setup.', 'error')
            return render_template('setup/database.html')
        
        from app.models import Match, FileUpload
        from sqlalchemy import func
        
        # Get user statistics
        user_matches = Match.query.filter_by(created_by=current_user.id).count()
        user_uploads = FileUpload.query.filter_by(uploaded_by=current_user.id).count()
        
        # Get recent fixtures (grouped by fixture_id)
        recent_fixtures_query = db.session.query(
            Match.fixture_id,
            Match.filename,
            func.count(Match.id).label('match_count'),
            func.min(Match.created_at).label('upload_date')
        ).filter_by(created_by=current_user.id)\
         .group_by(Match.fixture_id, Match.filename)\
         .order_by(func.min(Match.created_at).desc())\
         .limit(5)
        
        recent_fixtures = recent_fixtures_query.all()
        
        # Get system statistics (for admins)
        system_stats = {}
        if current_user.is_admin:
            db_manager = get_db_manager()
            system_stats = db_manager.get_database_stats()
            
            file_handler = get_file_upload_handler()
            upload_stats = file_handler.get_upload_statistics()
            system_stats.update(upload_stats)
        
        return render_template('main/dashboard.html',
                             user_matches=user_matches,
                             user_uploads=user_uploads,
                             recent_fixtures=recent_fixtures,
                             system_stats=system_stats)
    
    except Exception as e:
        logger.error(f"Dashboard error: {str(e)}")
        flash('Error loading dashboard', 'error')
        return render_template('main/dashboard.html')

@bp.route('/fixtures')
@login_required
@require_active_user
def fixtures():
    """List fixtures with pagination and filtering"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 20, type=int), 100)
        
        # Filtering options
        status_filter = request.args.get('status')
        search_query = request.args.get('search', '').strip()
        
        from app.models import Match
        from sqlalchemy import func, and_
        
        # Base query for fixtures (grouped by fixture_id)
        base_query = db.session.query(
            Match.fixture_id,
            Match.filename,
            func.count(Match.id).label('match_count'),
            func.min(Match.created_at).label('upload_date'),
            func.sum(Match.active_status.cast(db.Integer)).label('active_matches'),
            func.max(Match.created_by).label('created_by')  # Assuming all matches in fixture have same creator
        ).group_by(Match.fixture_id, Match.filename)
        
        # Apply user filter
        if not current_user.is_admin:
            base_query = base_query.filter(Match.created_by == current_user.id)
        
        # Apply search filter
        if search_query:
            search_pattern = f"%{search_query}%"
            base_query = base_query.filter(Match.filename.ilike(search_pattern))
        
        # Get all fixtures
        fixtures_query = base_query.order_by(func.min(Match.created_at).desc())
        
        # Apply status filter after grouping
        fixtures = fixtures_query.all()
        
        if status_filter:
            filtered_fixtures = []
            for fixture in fixtures:
                if status_filter == 'active' and fixture.active_matches > 0:
                    filtered_fixtures.append(fixture)
                elif status_filter == 'inactive' and fixture.active_matches == 0:
                    filtered_fixtures.append(fixture)
                elif status_filter == 'complete' and fixture.active_matches == fixture.match_count:
                    filtered_fixtures.append(fixture)
                elif not status_filter:
                    filtered_fixtures.append(fixture)
            fixtures = filtered_fixtures
        
        # Manual pagination
        total = len(fixtures)
        start = (page - 1) * per_page
        end = start + per_page
        fixtures_page = fixtures[start:end]
        
        # Create pagination object
        class SimplePagination:
            def __init__(self, page, per_page, total, items):
                self.page = page
                self.per_page = per_page
                self.total = total
                self.items = items
                self.pages = (total + per_page - 1) // per_page
                self.has_prev = page > 1
                self.has_next = page < self.pages
                self.prev_num = page - 1 if self.has_prev else None
                self.next_num = page + 1 if self.has_next else None
        
        pagination = SimplePagination(page, per_page, total, fixtures_page)
        
        return render_template('main/matches.html',
                             fixtures=fixtures_page,
                             pagination=pagination,
                             status_filter=status_filter,
                             search_query=search_query)
    
    except Exception as e:
        logger.error(f"Fixtures list error: {str(e)}")
        flash('Error loading fixtures', 'error')
        return render_template('main/matches.html', fixtures=[], pagination=None)

# Keep the old /matches route for backward compatibility
@bp.route('/matches')
@login_required
@require_active_user
def matches():
    """Redirect to fixtures for backward compatibility"""
    return redirect(url_for('main.fixtures'))

@bp.route('/fixture/<fixture_id>')
@login_required
@require_active_user
def fixture_detail(fixture_id):
    """Fixture detail page showing all matches in the fixture"""
    try:
        from app.models import Match, FileUpload
        
        # Get all matches for this fixture
        if current_user.is_admin:
            matches = Match.query.filter_by(fixture_id=fixture_id).all()
        else:
            matches = Match.query.filter_by(fixture_id=fixture_id, created_by=current_user.id).all()
        
        if not matches:
            flash('Fixture not found', 'error')
            return redirect(url_for('main.matches'))
        
        # Get fixture info from first match
        fixture_info = {
            'fixture_id': fixture_id,
            'filename': matches[0].filename,
            'upload_date': matches[0].created_at,
            'total_matches': len(matches),
            'active_matches': sum(1 for m in matches if m.active_status),
            'created_by': matches[0].created_by
        }
        
        # Get associated uploads for the fixture
        match_ids = [m.id for m in matches]
        uploads = FileUpload.query.filter(FileUpload.match_id.in_(match_ids)).all() if match_ids else []
        
        return render_template('main/fixture_detail.html',
                             fixture_info=fixture_info,
                             matches=matches,
                             uploads=uploads)
    
    except Exception as e:
        logger.error(f"Fixture detail error: {str(e)}")
        flash('Error loading fixture details', 'error')
        return redirect(url_for('main.matches'))

@bp.route('/fixture/<fixture_id>/delete', methods=['POST'])
@login_required
@require_active_user
def delete_fixture(fixture_id):
    """Delete entire fixture and all related matches"""
    try:
        from app.models import Match, MatchOutcome, FileUpload
        
        # Get all matches for this fixture
        if current_user.is_admin:
            matches = Match.query.filter_by(fixture_id=fixture_id).all()
        else:
            matches = Match.query.filter_by(fixture_id=fixture_id, created_by=current_user.id).all()
        
        if not matches:
            flash('Fixture not found', 'error')
            return redirect(url_for('main.matches'))
        
        fixture_filename = matches[0].filename
        match_count = len(matches)
        
        # Delete all related data in correct order to handle foreign key constraints
        match_ids = [m.id for m in matches]
        
        # First, get file upload IDs that will be deleted
        file_uploads = FileUpload.query.filter(FileUpload.match_id.in_(match_ids)).all()
        upload_ids = [upload.id for upload in file_uploads]
        
        # Delete system logs that reference uploads (to avoid foreign key constraint)
        if upload_ids:
            from app.models import SystemLog
            SystemLog.query.filter(SystemLog.upload_id.in_(upload_ids)).delete(synchronize_session=False)
        
        # Delete system logs that reference matches
        if match_ids:
            from app.models import SystemLog
            SystemLog.query.filter(SystemLog.match_id.in_(match_ids)).delete(synchronize_session=False)
        
        # Delete match outcomes
        MatchOutcome.query.filter(MatchOutcome.match_id.in_(match_ids)).delete(synchronize_session=False)
        
        # Delete file uploads associated with matches
        FileUpload.query.filter(FileUpload.match_id.in_(match_ids)).delete(synchronize_session=False)
        
        # Delete matches
        Match.query.filter_by(fixture_id=fixture_id).delete(synchronize_session=False)
        
        db.session.commit()
        
        logger.info(f"Fixture {fixture_id} ({fixture_filename}) with {match_count} matches deleted by user {current_user.username}")
        flash(f'Fixture "{fixture_filename}" and all {match_count} related matches have been deleted successfully.', 'success')
        
        return redirect(url_for('main.matches'))
    
    except Exception as e:
        db.session.rollback()
        logger.error(f"Fixture deletion error: {str(e)}")
        flash('Error deleting fixture', 'error')
        return redirect(url_for('main.matches'))

@bp.route('/match/<int:id>')
@login_required
@require_active_user
def match_detail(id):
    """Individual match detail page"""
    try:
        from app.models import Match, FileUpload
        if current_user.is_admin:
            match = Match.query.get_or_404(id)
        else:
            match = Match.query.filter_by(id=id, created_by=current_user.id).first_or_404()
        
        # Get match outcomes
        outcomes = match.outcomes.all()
        
        # Get associated uploads
        uploads = FileUpload.query.filter_by(match_id=id).all()
        
        return render_template('main/match_detail.html',
                             match=match,
                             outcomes=outcomes,
                             uploads=uploads)
    
    except Exception as e:
        logger.error(f"Match detail error: {str(e)}")
        flash('Error loading match details', 'error')
        return redirect(url_for('main.fixture_detail', fixture_id=request.args.get('fixture_id', '')))

@bp.route('/match/<int:match_id>/outcomes', methods=['POST'])
@login_required
@require_active_user
def update_match_outcomes(match_id):
    """Update match outcomes via AJAX"""
    try:
        from app.models import Match, MatchOutcome
        
        # Get the match
        if current_user.is_admin:
            match = Match.query.get_or_404(match_id)
        else:
            match = Match.query.filter_by(id=match_id, created_by=current_user.id).first_or_404()
        
        data = request.get_json()
        if not data or 'outcomes' not in data:
            return jsonify({'error': 'No outcomes data provided'}), 400
        
        outcomes_data = data['outcomes']
        updated_outcomes = []
        
        # Update or create outcomes
        for column_name, float_value in outcomes_data.items():
            try:
                # Validate the float value
                float_val = float(float_value)
                
                # Find existing outcome or create new one
                outcome = MatchOutcome.query.filter_by(
                    match_id=match_id,
                    column_name=column_name
                ).first()
                
                if outcome:
                    outcome.float_value = float_val
                    outcome.updated_at = datetime.utcnow()
                else:
                    outcome = MatchOutcome(
                        match_id=match_id,
                        column_name=column_name,
                        float_value=float_val
                    )
                    db.session.add(outcome)
                
                updated_outcomes.append({
                    'column_name': column_name,
                    'float_value': float_val
                })
                
            except ValueError:
                return jsonify({'error': f'Invalid numeric value for {column_name}'}), 400
        
        # Update match timestamp
        match.updated_at = datetime.utcnow()
        db.session.commit()
        
        logger.info(f"Match {match_id} outcomes updated by user {current_user.username}")
        
        return jsonify({
            'message': 'Outcomes updated successfully',
            'updated_outcomes': updated_outcomes
        }), 200
    
    except Exception as e:
        db.session.rollback()
        logger.error(f"Update match outcomes error: {str(e)}")
        return jsonify({'error': 'Failed to update outcomes'}), 500

@bp.route('/match/<int:match_id>/outcomes/<int:outcome_id>', methods=['DELETE'])
@login_required
@require_active_user
def delete_match_outcome(match_id, outcome_id):
    """Delete a specific match outcome"""
    try:
        from app.models import Match, MatchOutcome
        
        # Get the match to verify ownership
        if current_user.is_admin:
            match = Match.query.get_or_404(match_id)
        else:
            match = Match.query.filter_by(id=match_id, created_by=current_user.id).first_or_404()
        
        # Get the outcome
        outcome = MatchOutcome.query.filter_by(
            id=outcome_id,
            match_id=match_id
        ).first_or_404()
        
        column_name = outcome.column_name
        db.session.delete(outcome)
        
        # Update match timestamp
        match.updated_at = datetime.utcnow()
        db.session.commit()
        
        logger.info(f"Outcome {column_name} deleted from match {match_id} by user {current_user.username}")
        
        return jsonify({
            'message': f'Outcome "{column_name}" deleted successfully'
        }), 200
    
    except Exception as e:
        db.session.rollback()
        logger.error(f"Delete match outcome error: {str(e)}")
        return jsonify({'error': 'Failed to delete outcome'}), 500

@bp.route('/uploads')
@login_required
@require_active_user
def uploads():
    """List uploads with pagination and filtering"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 20, type=int), 100)
        
        # Filtering options
        file_type_filter = request.args.get('file_type')
        status_filter = request.args.get('status')
        
        from app.models import FileUpload
        # Base query
        if current_user.is_admin:
            query = FileUpload.query
        else:
            query = FileUpload.query.filter_by(uploaded_by=current_user.id)
        
        # Apply filters
        if file_type_filter:
            query = query.filter_by(file_type=file_type_filter)
        
        if status_filter:
            query = query.filter_by(upload_status=status_filter)
        
        # Pagination
        uploads_pagination = query.order_by(FileUpload.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        return render_template('main/uploads.html',
                             uploads=uploads_pagination.items,
                             pagination=uploads_pagination,
                             file_type_filter=file_type_filter,
                             status_filter=status_filter)
    
    except Exception as e:
        logger.error(f"Uploads list error: {str(e)}")
        flash('Error loading uploads', 'error')
        return render_template('main/uploads.html', uploads=[], pagination=None)

@bp.route('/statistics')
@login_required
@require_active_user
def statistics():
    """Statistics page"""
    try:
        # Get file handler and parser statistics
        file_handler = get_file_upload_handler()
        fixture_parser = get_fixture_parser()
        
        upload_stats = file_handler.get_upload_statistics()
        parsing_stats = fixture_parser.get_parsing_statistics()
        
        from app.models import FileUpload, Match
        # User-specific statistics
        user_stats = {
            'total_uploads': FileUpload.query.filter_by(uploaded_by=current_user.id).count(),
            'total_matches': Match.query.filter_by(created_by=current_user.id).count(),
            'active_matches': Match.query.filter_by(
                created_by=current_user.id, active_status=True
            ).count(),
            'pending_zip_uploads': Match.query.filter_by(
                created_by=current_user.id, zip_upload_status='pending'
            ).count()
        }
        
        # System statistics (admin only)
        system_stats = {}
        if current_user.is_admin:
            from app.database import get_db_manager
            db_manager = get_db_manager()
            system_stats = db_manager.get_database_stats()
        
        return render_template('main/statistics.html',
                             upload_stats=upload_stats,
                             parsing_stats=parsing_stats,
                             user_stats=user_stats,
                             system_stats=system_stats)
    
    except Exception as e:
        logger.error(f"Statistics error: {str(e)}")
        flash('Error loading statistics', 'error')
        return render_template('main/statistics.html')

@bp.route('/admin')
@login_required
@require_admin
def admin_panel():
    """Admin panel"""
    try:
        # Get system overview
        from app.database import get_db_manager
        db_manager = get_db_manager()
        system_stats = db_manager.get_database_stats()
        
        from app.models import SystemLog, User
        # Get recent system logs
        recent_logs = SystemLog.query.order_by(SystemLog.created_at.desc()).limit(20).all()
        
        # Get user statistics
        total_users = User.query.count()
        active_users = User.query.filter_by(is_active=True).count()
        admin_users = User.query.filter_by(is_admin=True).count()
        
        user_stats = {
            'total_users': total_users,
            'active_users': active_users,
            'admin_users': admin_users,
            'inactive_users': total_users - active_users
        }
        
        # Get upload statistics
        file_handler = get_file_upload_handler()
        upload_stats = file_handler.get_upload_statistics()
        
        return render_template('main/admin.html',
                             system_stats=system_stats,
                             user_stats=user_stats,
                             upload_stats=upload_stats,
                             recent_logs=recent_logs)
    
    except Exception as e:
        logger.error(f"Admin panel error: {str(e)}")
        flash('Error loading admin panel', 'error')
        return render_template('main/admin.html')

@bp.route('/admin/users')
@login_required
@require_admin
def admin_users():
    """Admin user management"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 20, type=int), 100)
        
        search_query = request.args.get('search', '').strip()
        status_filter = request.args.get('status')
        
        from app.models import User
        # Base query
        query = User.query
        
        # Apply filters
        if status_filter == 'active':
            query = query.filter_by(is_active=True)
        elif status_filter == 'inactive':
            query = query.filter_by(is_active=False)
        elif status_filter == 'admin':
            query = query.filter_by(is_admin=True)
        
        # Search functionality
        if search_query:
            search_pattern = f"%{search_query}%"
            query = query.filter(
                db.or_(
                    User.username.ilike(search_pattern),
                    User.email.ilike(search_pattern)
                )
            )
        
        # Pagination
        users_pagination = query.order_by(User.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        return render_template('main/admin_users.html',
                             users=users_pagination.items,
                             pagination=users_pagination,
                             search_query=search_query,
                             status_filter=status_filter)
    
    except Exception as e:
        logger.error(f"Admin users error: {str(e)}")
        flash('Error loading users', 'error')
        return render_template('main/admin_users.html', users=[], pagination=None)

@bp.route('/admin/logs')
@login_required
@require_admin
def admin_logs():
    """Admin system logs"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 50, type=int), 200)
        
        level_filter = request.args.get('level')
        module_filter = request.args.get('module')
        
        from app.models import SystemLog
        # Base query
        query = SystemLog.query
        
        # Apply filters
        if level_filter:
            query = query.filter_by(level=level_filter)
        
        if module_filter:
            query = query.filter_by(module=module_filter)
        
        # Pagination
        logs_pagination = query.order_by(SystemLog.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        # Get available modules for filter
        modules = db.session.query(SystemLog.module).distinct().all()
        modules = [m[0] for m in modules if m[0]]
        
        return render_template('main/admin_logs.html',
                             logs=logs_pagination.items,
                             pagination=logs_pagination,
                             level_filter=level_filter,
                             module_filter=module_filter,
                             modules=modules)
    
    except Exception as e:
        logger.error(f"Admin logs error: {str(e)}")
        flash('Error loading logs', 'error')
        return render_template('main/admin_logs.html', logs=[], pagination=None)

@bp.route('/admin/users/<int:user_id>/edit', methods=['POST'])
@login_required
@require_admin
def admin_edit_user(user_id):
    """Edit user details"""
    try:
        from app.models import User
        user = User.query.get_or_404(user_id)
        
        # Prevent editing the current admin user's admin status
        if user.id == current_user.id and request.json.get('is_admin') == False:
            return jsonify({'error': 'Cannot remove admin status from your own account'}), 400
        
        data = request.get_json()
        if not data:
            return jsonify({'error': 'No data provided'}), 400
        
        # Update user fields
        if 'username' in data:
            # Check if username is already taken by another user
            existing_user = User.query.filter_by(username=data['username']).first()
            if existing_user and existing_user.id != user.id:
                return jsonify({'error': 'Username already exists'}), 400
            user.username = data['username']
        
        if 'email' in data:
            # Check if email is already taken by another user
            existing_user = User.query.filter_by(email=data['email']).first()
            if existing_user and existing_user.id != user.id:
                return jsonify({'error': 'Email already exists'}), 400
            user.email = data['email']
        
        if 'is_active' in data:
            user.is_active = bool(data['is_active'])
        
        if 'is_admin' in data:
            user.is_admin = bool(data['is_admin'])
        
        user.updated_at = datetime.utcnow()
        db.session.commit()
        
        logger.info(f"User {user.username} updated by admin {current_user.username}")
        return jsonify({'message': 'User updated successfully', 'user': user.to_dict()}), 200
    
    except Exception as e:
        logger.error(f"Admin edit user error: {str(e)}")
        return jsonify({'error': 'Failed to update user'}), 500

@bp.route('/admin/users/<int:user_id>/delete', methods=['DELETE'])
@login_required
@require_admin
def admin_delete_user(user_id):
    """Delete user"""
    try:
        from app.models import User
        user = User.query.get_or_404(user_id)
        
        # Prevent deleting the current admin user
        if user.id == current_user.id:
            return jsonify({'error': 'Cannot delete your own account'}), 400
        
        username = user.username
        db.session.delete(user)
        db.session.commit()
        
        logger.info(f"User {username} deleted by admin {current_user.username}")
        return jsonify({'message': 'User deleted successfully'}), 200
    
    except Exception as e:
        logger.error(f"Admin delete user error: {str(e)}")
        return jsonify({'error': 'Failed to delete user'}), 500

@bp.route('/admin/users/create', methods=['POST'])
@login_required
@require_admin
def admin_create_user():
    """Create new user"""
    try:
        data = request.get_json()
        if not data:
            return jsonify({'error': 'No data provided'}), 400
        
        # Validate required fields
        required_fields = ['username', 'email', 'password']
        for field in required_fields:
            if field not in data or not data[field]:
                return jsonify({'error': f'{field.title()} is required'}), 400
        
        from app.models import User
        # Check if username already exists
        if User.query.filter_by(username=data['username']).first():
            return jsonify({'error': 'Username already exists'}), 400
        
        # Check if email already exists
        if User.query.filter_by(email=data['email']).first():
            return jsonify({'error': 'Email already exists'}), 400
        
        # Validate password strength
        from app.utils.security import validate_password_strength
        if not validate_password_strength(data['password']):
            return jsonify({'error': 'Password does not meet security requirements'}), 400
        
        # Create new user
        user = User(
            username=data['username'],
            email=data['email'],
            is_active=data.get('is_active', True),
            is_admin=data.get('is_admin', False)
        )
        user.set_password(data['password'])
        
        db.session.add(user)
        db.session.commit()
        
        logger.info(f"User {user.username} created by admin {current_user.username}")
        return jsonify({'message': 'User created successfully', 'user': user.to_dict()}), 201
    
    except Exception as e:
        logger.error(f"Admin create user error: {str(e)}")
        return jsonify({'error': 'Failed to create user'}), 500

@bp.route('/admin/users/<int:user_id>/reset-password', methods=['POST'])
@login_required
@require_admin
def admin_reset_user_password(user_id):
    """Reset user password"""
    try:
        from app.models import User
        user = User.query.get_or_404(user_id)
        
        data = request.get_json()
        if not data or not data.get('new_password'):
            return jsonify({'error': 'New password is required'}), 400
        
        # Validate password strength
        from app.utils.security import validate_password_strength
        if not validate_password_strength(data['new_password']):
            return jsonify({'error': 'Password does not meet security requirements'}), 400
        
        user.set_password(data['new_password'])
        user.updated_at = datetime.utcnow()
        db.session.commit()
        
        logger.info(f"Password reset for user {user.username} by admin {current_user.username}")
        return jsonify({'message': 'Password reset successfully'}), 200
    
    except Exception as e:
        logger.error(f"Admin reset password error: {str(e)}")
        return jsonify({'error': 'Failed to reset password'}), 500

@bp.route('/admin/settings')
@login_required
@require_admin
def admin_system_settings():
    """System settings management page"""
    try:
        from app.models import SystemSettings
        
        # Initialize default settings if they don't exist
        SystemSettings.initialize_default_settings()
        
        # Get all system settings
        settings = SystemSettings.query.all()
        settings_dict = {setting.key: setting for setting in settings}
        
        return render_template('main/admin_settings.html', settings=settings_dict)
    
    except Exception as e:
        logger.error(f"Admin system settings error: {str(e)}")
        flash('Error loading system settings', 'error')
        return render_template('main/admin_settings.html', settings={})

@bp.route('/admin/settings/registration', methods=['GET', 'POST'])
@login_required
@require_admin
def admin_registration_settings():
    """Manage registration settings"""
    try:
        from app.models import SystemSettings
        
        if request.method == 'GET':
            # Get current registration status from database
            registration_enabled = SystemSettings.is_registration_enabled()
            return jsonify({'registration_enabled': registration_enabled}), 200
        
        elif request.method == 'POST':
            data = request.get_json()
            if not data:
                return jsonify({'error': 'No data provided'}), 400
            
            # Update registration setting in database
            registration_enabled = bool(data.get('registration_enabled', False))
            SystemSettings.set_registration_enabled(registration_enabled)
            
            status = 'enabled' if registration_enabled else 'disabled'
            logger.info(f"Registration {status} by admin {current_user.username}")
            
            return jsonify({
                'message': f'Registration {status} successfully',
                'registration_enabled': registration_enabled
            }), 200
    
    except Exception as e:
        logger.error(f"Admin registration settings error: {str(e)}")
        return jsonify({'error': 'Failed to update registration settings'}), 500

@bp.route('/admin/settings/<setting_key>', methods=['GET', 'POST'])
@login_required
@require_admin
def admin_setting_detail(setting_key):
    """Get or update a specific system setting"""
    try:
        from app.models import SystemSettings
        
        if request.method == 'GET':
            setting = SystemSettings.query.filter_by(key=setting_key).first()
            if not setting:
                return jsonify({'error': 'Setting not found'}), 404
            
            return jsonify({'setting': setting.to_dict()}), 200
        
        elif request.method == 'POST':
            data = request.get_json()
            if not data or 'value' not in data:
                return jsonify({'error': 'Value is required'}), 400
            
            value = data['value']
            value_type = data.get('value_type', 'string')
            description = data.get('description')
            
            # Validate value type
            if value_type not in ['string', 'boolean', 'integer', 'float', 'json']:
                return jsonify({'error': 'Invalid value type'}), 400
            
            # Type validation
            if value_type == 'boolean' and not isinstance(value, bool):
                return jsonify({'error': 'Value must be boolean'}), 400
            elif value_type == 'integer':
                try:
                    int(value)
                except (ValueError, TypeError):
                    return jsonify({'error': 'Value must be integer'}), 400
            elif value_type == 'float':
                try:
                    float(value)
                except (ValueError, TypeError):
                    return jsonify({'error': 'Value must be float'}), 400
            
            # Update setting
            setting = SystemSettings.set_setting(setting_key, value, value_type, description)
            
            logger.info(f"System setting '{setting_key}' updated to '{value}' by admin {current_user.username}")
            
            return jsonify({
                'message': f'Setting "{setting_key}" updated successfully',
                'setting': setting.to_dict()
            }), 200
    
    except Exception as e:
        logger.error(f"Admin setting detail error: {str(e)}")
        return jsonify({'error': 'Failed to update setting'}), 500

@bp.route('/admin/database/migrations')
@login_required
@require_admin
def admin_database_migrations():
    """Database migrations management"""
    try:
        from app.database import get_migration_status
        migration_status = get_migration_status()
        
        return render_template('main/admin_migrations.html',
                             migration_status=migration_status)
    
    except Exception as e:
        logger.error(f"Admin migrations error: {str(e)}")
        flash('Error loading migration status', 'error')
        return render_template('main/admin_migrations.html', migration_status={})

@bp.route('/admin/database/migrations/run', methods=['POST'])
@login_required
@require_admin
def admin_run_migrations():
    """Run pending database migrations"""
    try:
        from app.database import run_migrations
        result = run_migrations()
        
        if result['status'] == 'success':
            logger.info(f"Migrations run successfully by admin {current_user.username}: {result['message']}")
            return jsonify({
                'success': True,
                'message': result['message'],
                'applied_count': result['applied_count']
            }), 200
        elif result['status'] == 'partial':
            logger.warning(f"Migrations partially completed by admin {current_user.username}: {result['message']}")
            return jsonify({
                'success': False,
                'message': result['message'],
                'applied_count': result['applied_count'],
                'failed_count': result['failed_count'],
                'failed_migrations': result.get('failed_migrations', [])
            }), 207  # Multi-status
        else:
            logger.error(f"Migration failed by admin {current_user.username}: {result['message']}")
            return jsonify({
                'success': False,
                'message': result['message']
            }), 500
    
    except Exception as e:
        logger.error(f"Admin run migrations error: {str(e)}")
        return jsonify({
            'success': False,
            'message': f'Failed to run migrations: {str(e)}'
        }), 500

@bp.route('/admin/database/migrations/status')
@login_required
@require_admin
def admin_migration_status():
    """Get current migration status"""
    try:
        from app.database import get_migration_status
        migration_status = get_migration_status()
        
        return jsonify({
            'success': True,
            'status': migration_status
        }), 200
    
    except Exception as e:
        logger.error(f"Admin migration status error: {str(e)}")
        return jsonify({
            'success': False,
            'message': f'Failed to get migration status: {str(e)}'
        }), 500

@bp.route('/health')
def health_check():
    """Health check endpoint"""
    try:
        # Test database connection
        from app.database import get_db_manager
        db_manager = get_db_manager()
        db_healthy = db_manager.test_connection()
        
        # Get basic statistics
        stats = db_manager.get_database_stats()
        
        health_status = {
            'status': 'healthy' if db_healthy else 'unhealthy',
            'database': 'connected' if db_healthy else 'disconnected',
            'timestamp': db.func.now(),
            'statistics': stats
        }
        
        status_code = 200 if db_healthy else 503
        return jsonify(health_status), status_code
    
    except Exception as e:
        logger.error(f"Health check error: {str(e)}")
        return jsonify({
            'status': 'unhealthy',
            'error': str(e),
            'timestamp': db.func.now()
        }), 503

@bp.route('/api/dashboard-data')
@login_required
@require_active_user
def api_dashboard_data():
    """API endpoint for dashboard data"""
    try:
        from app.models import Match, FileUpload
        # User statistics
        user_stats = {
            'total_matches': Match.query.filter_by(created_by=current_user.id).count(),
            'active_matches': Match.query.filter_by(
                created_by=current_user.id, active_status=True
            ).count(),
            'total_uploads': FileUpload.query.filter_by(uploaded_by=current_user.id).count(),
            'pending_zip_uploads': Match.query.filter_by(
                created_by=current_user.id, zip_upload_status='pending'
            ).count()
        }
        
        # Recent activity
        recent_matches = Match.query.filter_by(created_by=current_user.id)\
            .order_by(Match.created_at.desc()).limit(5).all()
        
        recent_uploads = FileUpload.query.filter_by(uploaded_by=current_user.id)\
            .order_by(FileUpload.created_at.desc()).limit(5).all()
        
        return jsonify({
            'user_stats': user_stats,
            'recent_matches': [match.to_dict() for match in recent_matches],
            'recent_uploads': [upload.to_dict() for upload in recent_uploads]
        }), 200
    
    except Exception as e:
        logger.error(f"Dashboard API error: {str(e)}")
        return jsonify({'error': 'Failed to load dashboard data'}), 500

# API Token Management Routes

@bp.route('/profile/tokens')
@login_required
@require_active_user
def user_tokens():
    """User API token management page"""
    try:
        from app.models import APIToken
        
        # Get user's API tokens
        tokens = APIToken.query.filter_by(user_id=current_user.id)\
            .order_by(APIToken.created_at.desc()).all()
        
        return render_template('main/user_tokens.html', tokens=tokens)
    
    except Exception as e:
        logger.error(f"User tokens page error: {str(e)}")
        flash('Error loading API tokens', 'error')
        return render_template('main/user_tokens.html', tokens=[])

@bp.route('/profile/tokens/create', methods=['POST'])
@login_required
@require_active_user
def create_api_token():
    """Create a new API token"""
    try:
        data = request.get_json()
        if not data or not data.get('name'):
            return jsonify({'error': 'Token name is required'}), 400
        
        token_name = data['name'].strip()
        if not token_name:
            return jsonify({'error': 'Token name cannot be empty'}), 400
        
        # Check if user already has a token with this name
        from app.models import APIToken
        existing_token = APIToken.query.filter_by(
            user_id=current_user.id,
            name=token_name
        ).first()
        
        if existing_token:
            return jsonify({'error': 'A token with this name already exists'}), 400
        
        # Generate the token
        api_token = current_user.generate_api_token(token_name)
        
        logger.info(f"API token '{token_name}' created by user {current_user.username}")
        
        return jsonify({
            'message': 'API token created successfully',
            'token': api_token.to_dict(include_token=True)
        }), 201
    
    except Exception as e:
        logger.error(f"Create API token error: {str(e)}")
        return jsonify({'error': 'Failed to create API token'}), 500

@bp.route('/profile/tokens/<int:token_id>/delete', methods=['DELETE'])
@login_required
@require_active_user
def delete_api_token(token_id):
    """Delete an API token"""
    try:
        from app.models import APIToken
        
        # Get the token (ensure it belongs to current user)
        token = APIToken.query.filter_by(
            id=token_id,
            user_id=current_user.id
        ).first_or_404()
        
        token_name = token.name
        db.session.delete(token)
        db.session.commit()
        
        logger.info(f"API token '{token_name}' deleted by user {current_user.username}")
        
        return jsonify({
            'message': f'API token "{token_name}" deleted successfully'
        }), 200
    
    except Exception as e:
        logger.error(f"Delete API token error: {str(e)}")
        return jsonify({'error': 'Failed to delete API token'}), 500

@bp.route('/profile/tokens/<int:token_id>/revoke', methods=['POST'])
@login_required
@require_active_user
def revoke_api_token(token_id):
    """Revoke (deactivate) an API token"""
    try:
        from app.models import APIToken
        
        # Get the token (ensure it belongs to current user)
        token = APIToken.query.filter_by(
            id=token_id,
            user_id=current_user.id
        ).first_or_404()
        
        if not token.is_active:
            return jsonify({'error': 'Token is already revoked'}), 400
        
        token.revoke()
        
        logger.info(f"API token '{token.name}' revoked by user {current_user.username}")
        
        return jsonify({
            'message': f'API token "{token.name}" revoked successfully',
            'token': token.to_dict()
        }), 200
    
    except Exception as e:
        logger.error(f"Revoke API token error: {str(e)}")
        return jsonify({'error': 'Failed to revoke API token'}), 500

@bp.route('/profile/tokens/<int:token_id>/extend', methods=['POST'])
@login_required
@require_active_user
def extend_api_token(token_id):
    """Extend API token expiration"""
    try:
        from app.models import APIToken
        
        # Get the token (ensure it belongs to current user)
        token = APIToken.query.filter_by(
            id=token_id,
            user_id=current_user.id
        ).first_or_404()
        
        data = request.get_json()
        days = data.get('days', 365) if data else 365
        
        # Validate days (between 1 and 1095 - 3 years max)
        if not isinstance(days, int) or days < 1 or days > 1095:
            return jsonify({'error': 'Days must be between 1 and 1095'}), 400
        
        token.extend_expiration(days)
        
        logger.info(f"API token '{token.name}' extended by {days} days by user {current_user.username}")
        
        return jsonify({
            'message': f'API token "{token.name}" extended by {days} days',
            'token': token.to_dict()
        }), 200
    
    except Exception as e:
        logger.error(f"Extend API token error: {str(e)}")
        return jsonify({'error': 'Failed to extend API token'}), 500

# API Routes with Token Authentication

@bp.route('/api/matches')
def api_matches():
    """API endpoint to list matches (requires API token)"""
    from app.auth.jwt_utils import require_api_token, get_current_api_user
    
    @require_api_token
    def _api_matches():
        try:
            from app.models import Match
            
            # Get current API user
            api_user = get_current_api_user()
            
            # Pagination
            page = request.args.get('page', 1, type=int)
            per_page = min(request.args.get('per_page', 20, type=int), 100)
            
            # Base query
            if api_user.is_admin:
                query = Match.query
            else:
                query = Match.query.filter_by(created_by=api_user.id)
            
            # Apply filters
            fixture_id = request.args.get('fixture_id')
            if fixture_id:
                query = query.filter_by(fixture_id=fixture_id)
            
            active_only = request.args.get('active_only', '').lower() == 'true'
            if active_only:
                query = query.filter_by(active_status=True)
            
            # Pagination
            matches_pagination = query.order_by(Match.created_at.desc()).paginate(
                page=page, per_page=per_page, error_out=False
            )
            
            return jsonify({
                'matches': [match.to_dict() for match in matches_pagination.items],
                'pagination': {
                    'page': matches_pagination.page,
                    'pages': matches_pagination.pages,
                    'per_page': matches_pagination.per_page,
                    'total': matches_pagination.total,
                    'has_next': matches_pagination.has_next,
                    'has_prev': matches_pagination.has_prev
                }
            }), 200
        
        except Exception as e:
            logger.error(f"API matches error: {str(e)}")
            return jsonify({'error': 'Failed to retrieve matches'}), 500
    
    return _api_matches()

@bp.route('/api/fixtures')
def api_fixtures():
    """API endpoint to list fixtures (requires API token)"""
    from app.auth.jwt_utils import require_api_token, get_current_api_user
    
    @require_api_token
    def _api_fixtures():
        try:
            from app.models import Match
            from sqlalchemy import func
            
            # Get current API user
            api_user = get_current_api_user()
            
            # Base query for fixtures (grouped by fixture_id)
            base_query = db.session.query(
                Match.fixture_id,
                Match.filename,
                func.count(Match.id).label('match_count'),
                func.min(Match.created_at).label('upload_date'),
                func.sum(Match.active_status.cast(db.Integer)).label('active_matches')
            ).group_by(Match.fixture_id, Match.filename)
            
            # Apply user filter
            if not api_user.is_admin:
                base_query = base_query.filter(Match.created_by == api_user.id)
            
            # Get fixtures
            fixtures = base_query.order_by(func.min(Match.created_at).desc()).all()
            
            # Convert to dict format
            fixtures_data = []
            for fixture in fixtures:
                fixtures_data.append({
                    'fixture_id': fixture.fixture_id,
                    'filename': fixture.filename,
                    'match_count': fixture.match_count,
                    'active_matches': fixture.active_matches,
                    'upload_date': fixture.upload_date.isoformat() if fixture.upload_date else None,
                    'status': 'complete' if fixture.active_matches == fixture.match_count else 'partial'
                })
            
            return jsonify({
                'fixtures': fixtures_data,
                'total': len(fixtures_data)
            }), 200
        
        except Exception as e:
            logger.error(f"API fixtures error: {str(e)}")
            return jsonify({'error': 'Failed to retrieve fixtures'}), 500
    
    return _api_fixtures()

@bp.route('/api/match/<int:match_id>')
def api_match_detail(match_id):
    """API endpoint to get match details (requires API token)"""
    from app.auth.jwt_utils import require_api_token, get_current_api_user
    
    @require_api_token
    def _api_match_detail():
        try:
            from app.models import Match
            
            # Get current API user
            api_user = get_current_api_user()
            
            # Get match
            if api_user.is_admin:
                match = Match.query.get_or_404(match_id)
            else:
                match = Match.query.filter_by(id=match_id, created_by=api_user.id).first_or_404()
            
            return jsonify({
                'match': match.to_dict(include_outcomes=True)
            }), 200
        
        except Exception as e:
            logger.error(f"API match detail error: {str(e)}")
            return jsonify({'error': 'Failed to retrieve match details'}), 500
    
    return _api_match_detail()

@bp.route('/download/zip/<int:match_id>')
@login_required
@require_active_user
def download_zip(match_id):
    """Download ZIP file for a match"""
    try:
        from app.models import Match
        from flask import send_file, abort
        
        # Get the match
        if current_user.is_admin:
            match = Match.query.get_or_404(match_id)
        else:
            match = Match.query.filter_by(id=match_id, created_by=current_user.id).first_or_404()
        
        # Check if ZIP file exists and is completed
        if not match.zip_filename or match.zip_upload_status != 'completed':
            flash('ZIP file not available for this match', 'error')
            abort(404)
        
        # Construct file path
        zip_path = os.path.join(current_app.config.get('ZIP_UPLOADS_DIR', current_app.config.get('UPLOAD_FOLDER', 'uploads')), match.zip_filename)
        
        if not os.path.exists(zip_path):
            flash('ZIP file not found on disk', 'error')
            abort(404)
        
        # Log the download
        logger.info(f"ZIP file downloaded: {match.zip_filename} by user {current_user.username}")
        
        return send_file(zip_path, as_attachment=True, download_name=match.zip_filename)
        
    except Exception as e:
        logger.error(f"ZIP download error: {str(e)}")
        flash('Error downloading ZIP file', 'error')
        abort(500)