from flask import request, session
import time
from flask_security import current_user
import json


def log_request_middleware(app):

    @app.before_request
    def log_session_state_before():
        pass

    @app.after_request
    def log_session_state_after(response):
        return response


def register_request_debugger(app):
    @app.before_request
    def debug_request_info():
        """Log consolidated request information for debugging"""
        # Skip health check endpoints
        if request.path.startswith('/_healthz') or request.path.startswith('/healthz'):
            return

        # Gather all request information in a structured way
        debug_info = {
            "basic_info": {
                "method": request.method,
                "path": request.path,
                "content_type": request.content_type,
                "content_length": request.content_length
            },
            "environment": {
                "remote_addr": request.remote_addr,
                "user_agent": str(request.user_agent)
            }
        }

        # Add headers (excluding sensitive ones)
        safe_headers = {k: v for k, v in request.headers.items()
                       if k.lower() not in ('authorization', 'cookie', 'x-api-key')}
        debug_info["headers"] = safe_headers

        # Add authentication info (presence only)
        auth_header = request.headers.get('Authorization', '')
        debug_info["auth_info"] = {
            "has_auth_header": bool(auth_header),
            "auth_type": auth_header.split(' ')[0] if auth_header else None,
            "token_length": len(auth_header.split(' ')[1]) if auth_header and len(auth_header.split(' ')) > 1 else 0,
            "header_format": 'Valid format' if auth_header.startswith('Bearer ') else 'Invalid format',
            "raw_header": auth_header[:10] + '...' if auth_header else None  # Show first 10 chars only
        }

        # Add request data based on type
        if request.is_json:
            try:
                json_data = request.get_json()
                if isinstance(json_data, dict):
                    # Remove sensitive fields from logging
                    safe_json = {k: v for k, v in json_data.items()
                               if not any(sensitive in k.lower()
                                        for sensitive in ['password', 'token', 'secret', 'key'])}
                    debug_info["request_data"] = {
                        "type": "json",
                        "content": safe_json
                    }
            except Exception as e:
                debug_info["request_data"] = {
                    "type": "json",
                    "error": str(e)
                }
        elif request.form:
            safe_form = {k: v for k, v in request.form.items()
                        if not any(sensitive in k.lower()
                                 for sensitive in ['password', 'token', 'secret', 'key'])}
            debug_info["request_data"] = {
                "type": "form",
                "content": safe_form
            }

        # Add file information if present
        if request.files:
            debug_info["files"] = {
                name: {
                    "filename": f.filename,
                    "content_type": f.content_type,
                    "content_length": f.content_length if hasattr(f, 'content_length') else None
                }
                for name, f in request.files.items()
            }

        # Add CORS information if present
        cors_headers = {
            "origin": request.headers.get('Origin'),
            "request_method": request.headers.get('Access-Control-Request-Method'),
            "request_headers": request.headers.get('Access-Control-Request-Headers')
        }
        if any(cors_headers.values()):
            debug_info["cors"] = {k: v for k, v in cors_headers.items() if v is not None}

        # Format the debug info as a pretty-printed JSON string with indentation
        formatted_debug_info = json.dumps(debug_info, indent=2, sort_keys=True)

