# app/__init__.py
from app.models.planfix_models import PlanfixToken
from app.services.planfix_jobs import reschedule_job

from flask import Flask, render_template, request
from .config import Config
from .extensions import logger_init, db_init, ext_init
from .blueprints.main.routes  import main_bp
from .blueprints.auth.routes  import auth_bp
from .blueprints.admin.routes import admin_bp
from .blueprints.bank.routes  import bank_bp
from .filters import datetime_local_format, split_filter
from app.blueprints.planfix.routes import planfix_bp
from flask_limiter.errors import RateLimitExceeded
from flask import Flask
from app.extensions import db, init_extensions
def create_app() -> Flask:
    app = Flask(__name__, template_folder="templates", static_folder="static")
    app.config.from_object(Config)

    # 1. логгер + база
    logger_init(app)
    db_init(app)

    # 2. security-extensions (Flask-Session, Flask-Limiter, CSRF, Flask-Login, Talisman)
    ext_init(app)

    # 3. jinja-фильтры
    app.jinja_env.filters["datetime_local_format"] = datetime_local_format
    app.jinja_env.filters["split"] = split_filter
    init_extensions(app)
    # 4. blueprints
    app.register_blueprint(main_bp)                       # главная страница и инструкции
    app.register_blueprint(auth_bp,   url_prefix="/auth") # /auth/login, /auth/logout
    app.register_blueprint(admin_bp,  url_prefix="/auth/admin") # панель администратора
    app.register_blueprint(bank_bp,   url_prefix="/1")    # /1/…, эндпоинты банковских выписок
    app.register_blueprint(planfix_bp)
    # 5. глобальные обработчики ошибок

    register_error_handlers(app)
    with app.app_context():
        token = PlanfixToken.query.first()
        if token:
            reschedule_job(token, app=app)

    return app


def register_error_handlers(app: Flask) -> None:
    """
    Регистрируем пользовательские страницы ошибок:
      • 429 Too Many Requests (Flask-Limiter)
      • 404 Not Found
      • 500 Internal Server Error
    """

    # 401 Unauthorized
    @app.errorhandler(401)
    def unauthorized_handler(e):
        # Отлавливает ошибки 401 (в том числе при использовании @login_required)
        return render_template("errors/401.html"), 401

    # 403 Forbidden
    @app.errorhandler(403)
    def forbidden_handler(e):
        return render_template("errors/403.html"), 403
    @app.errorhandler(RateLimitExceeded)        # «429 Too Many Requests»
    def ratelimit_handler(e):
        return (
            render_template(
                "errors/429.html",
                message="Забагато спроб. Спробуйте знову пізніше.",
                detail=e.description  # e.description — строка «10 per 1 minute» и т. д.
            ),
            429
        )

    @app.errorhandler(404)                      # «404 Not Found»
    def not_found_error(e):
        return (
            render_template(
                "errors/404.html",
                path=request.path  # текущий путь, который не найден
            ),
            404
        )

    @app.errorhandler(500)                      # «500 Internal Server Error»
    def internal_error(e):
        # Здесь можно, при желании, логировать e, отправлять email-уведомления и т. п.
        return (
            render_template(
                "errors/500.html",
                error=str(e)  # (в продакшн лучше не показывать подробности пользователю)
            ),
            500
        )
