import logging
import os
from flask import Flask, jsonify, url_for
from flask_security import SQLAlchemyUserDatastore
from flask_security.signals import user_authenticated
from werkzeug.middleware.proxy_fix import ProxyFix
import logging.config

from common.extensions import (db, migrate, bootstrap, security, login_manager, cors, csrf, session,
                               minio_client, simple_encryption, metrics, cache_manager, content_manager)
from common.models.user import User, Role, Tenant, TenantDomain
import common.models.interaction
import common.models.entitlements
import common.models.document
from common.utils.security_utils import enforce_tenant_consent_ui
from config.logging_config import configure_logging
from common.utils.security import set_tenant_session_data
from common.utils.errors import register_error_handlers
from common.utils.celery_utils import make_celery, init_celery
from common.utils.template_filters import register_filters
from config.config import get_config
from eveai_app.views.security_forms import ResetPasswordForm, ForgotPasswordForm


def create_app(config_file=None):
    app = Flask(__name__, static_url_path='/static')

    # Ensure all necessary headers are handled
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)

    environment = os.getenv('FLASK_ENV', 'development')

    match environment:
        case 'development':
            app.config.from_object(get_config('dev'))
        case 'test':
            app.config.from_object(get_config('test'))
        case 'staging':
            app.config.from_object(get_config('staging'))
        case 'production':
            app.config.from_object(get_config('prod'))
        case _:
            app.config.from_object(get_config('dev'))

    app.config['SESSION_KEY_PREFIX'] = 'eveai_app_'
    app.config['SECURITY_RESET_PASSWORD_FORM'] = ResetPasswordForm
    app.config['SECURITY_FORGOT_PASSWORD_FORM'] = ForgotPasswordForm

    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    # Configureer logging op basis van de omgeving (K8s of traditioneel)
    try:
        configure_logging()
        logger = logging.getLogger(__name__)
        # Test dat logging werkt
        logger.debug("Logging test in eveai_app")
    except Exception as e:
        print(f"Critical Error Initialising Error: {str(e)}")
        import traceback
        traceback.print_exc()

    logger.info("eveai_app starting up")

    # Register extensions

    register_extensions(app)

    # Configure CSRF protection
    app.config['WTF_CSRF_CHECK_DEFAULT'] = False  # Disable global CSRF protection
    app.config['WTF_CSRF_TIME_LIMIT'] = None  # Remove time limit for CSRF tokens

    app.celery = make_celery(app.name, app.config)
    init_celery(app.celery, app)

    # Setup Flask-Security-Too
    user_datastore = SQLAlchemyUserDatastore(db, User, Role)
    security.init_app(app, user_datastore)
    user_authenticated.connect(set_tenant_session_data, app)

    # Register Blueprints
    register_blueprints(app)

    # Register Error Handlers
    register_error_handlers(app)

    # Register Cache Handlers
    register_cache_handlers(app)

    # Custom url_for function for templates
    @app.context_processor
    def override_url_for():
        return dict(url_for=_url_for)

    def _url_for(endpoint, **values):
        static_url = app.config.get('STATIC_URL')
        if endpoint == 'static' and static_url:
            filename = values.get('filename', '')
            return f"{static_url}/{filename}"
        return url_for(endpoint, **values)

    # Debugging settings
    if app.config['DEBUG'] is True:
        app.logger.setLevel(logging.DEBUG)
        security_logger = logging.getLogger('flask_security')
        security_logger.setLevel(logging.DEBUG)
        sqlalchemy_logger = logging.getLogger('sqlalchemy.engine')
        sqlalchemy_logger.setLevel(logging.DEBUG)
        # log_request_middleware(app)   # Add this when debugging nginx or another proxy

    # Register global consent guard via extension
    @app.before_request
    def enforce_tenant_consent():
        return enforce_tenant_consent_ui()

    # @app.before_request
    # def before_request():
    #     # app.logger.debug(f"Before request - Session ID: {session.sid}")
    #     app.logger.debug(f"Before request - Session data: {session}")
    #     app.logger.debug(f"Before request - Request headers: {request.headers}")

    @app.before_request
    def before_request():
        from flask import session, request
        from flask_login import current_user
        import datetime

        if request.path.startswith('/healthz'):
            return

        app.logger.debug(f"Before request - URL: {request.url}")
        app.logger.debug(f"Before request - PATH: {request.path}")
        app.logger.debug(f"Before request - Session permanent: {session.permanent}")

    @app.route('/debug/session')
    def debug_session():
        from flask import session
        from flask_security import current_user
        import datetime

        if current_user.is_authenticated:
            info = {
                'session_permanent': session.permanent,
                'session_lifetime_minutes': app.permanent_session_lifetime.total_seconds() / 60,
                'session_refresh_enabled': app.config.get('SESSION_REFRESH_EACH_REQUEST'),
                'current_time': datetime.datetime.now().isoformat(),
                'session_data_keys': list(session.keys())
            }
            return jsonify(info)
        else:
            return jsonify({'error': 'Not authenticated'})

    # Register template filters
    register_filters(app)

    # Let all initialization complete before using cache
    # @app.before_first_request
    # def initialize_cache_data():
    #     # Cache testing
    #     agent_types = cache_manager.agent_config_cache.get_types()
    #     app.logger.debug(f"Agent types: {agent_types}")
    #     agent_config = cache_manager.agent_config_cache.get_config('RAG_AGENT')
    #     app.logger.debug(f"Agent config: {agent_config}")

    app.logger.info(f"EveAI App Server Started Successfully (PID: {os.getpid()})")
    app.logger.info("-------------------------------------------------------------------------------------------------")
    return app


def register_extensions(app):
    db.init_app(app)
    migrate.init_app(app, db)
    bootstrap.init_app(app)
    csrf.init_app(app)
    login_manager.init_app(app)
    cors.init_app(app)
    simple_encryption.init_app(app)
    session.init_app(app)
    minio_client.init_app(app)
    cache_manager.init_app(app)
    metrics.init_app(app)
    content_manager.init_app(app)


def register_blueprints(app):
    from .views.user_views import user_bp
    app.register_blueprint(user_bp)
    from .views.basic_views import basic_bp
    app.register_blueprint(basic_bp)
    from .views.document_views import document_bp
    app.register_blueprint(document_bp)
    from .views.security_views import security_bp
    app.register_blueprint(security_bp)
    from .views.interaction_views import interaction_bp
    app.register_blueprint(interaction_bp)
    from .views.entitlements_views import entitlements_bp
    app.register_blueprint(entitlements_bp)
    from .views.partner_views import partner_bp
    app.register_blueprint(partner_bp)
    from .views.healthz_views import healthz_bp
    app.register_blueprint(healthz_bp)


def register_cache_handlers(app):
    from common.utils.cache.config_cache import register_config_cache_handlers
    register_config_cache_handlers(cache_manager)
    from common.utils.cache.crewai_processed_config_cache import register_specialist_cache_handlers
    register_specialist_cache_handlers(cache_manager)
    from common.utils.cache.license_cache import register_license_cache_handlers
    register_license_cache_handlers(cache_manager)
