from __future__ import annotations

import os
from datetime import timedelta

from flask import Flask, request
from flask_wtf.csrf import CSRFProtect
from werkzeug.middleware.proxy_fix import ProxyFix

from .config import UPLOAD_DIR, ensure_directories, load_or_create_secret
from .db import init_db
from .services.log_service import configure_file_logging
from .ui import t

csrf = CSRFProtect()


def create_app(test_config: dict | None = None) -> Flask:
    ensure_directories()
    init_db()
    configure_file_logging()

    app = Flask(__name__)
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)
    app.config.update(
        SECRET_KEY=load_or_create_secret(),
        MAX_CONTENT_LENGTH=25 * 1024 * 1024,
        SESSION_COOKIE_HTTPONLY=True,
        SESSION_COOKIE_SAMESITE='Lax',
        SESSION_COOKIE_SECURE=False,
        PERMANENT_SESSION_LIFETIME=timedelta(hours=8),
        WTF_CSRF_TIME_LIMIT=timedelta(hours=8),
    )
    if test_config:
        app.config.update(test_config)

    csrf.init_app(app)

    from .routes import bp
    app.register_blueprint(bp)

    @app.context_processor
    def inject_globals():
        return {'t': t}

    @app.before_request
    def secure_cookie_when_https():
        app.config['SESSION_COOKIE_SECURE'] = bool(request.is_secure)

    @app.after_request
    def security_headers(response):
        response.headers.setdefault('X-Content-Type-Options', 'nosniff')
        response.headers.setdefault('X-Frame-Options', 'SAMEORIGIN')
        response.headers.setdefault('Referrer-Policy', 'strict-origin-when-cross-origin')
        response.headers.setdefault('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
        response.headers.setdefault('Content-Security-Policy', "default-src 'self' https://cdn.jsdelivr.net; img-src 'self' data: https:; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net")
        return response

    return app
