import os

from flask import Flask, jsonify, render_template, request
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFError, CSRFProtect

db = SQLAlchemy()
migrate = Migrate()
csrf = CSRFProtect()

MIGRATIONS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "migrations")


def create_app(config_class=None):
    app = Flask(__name__)

    if config_class is None:
        from app.config import Config
        config_class = Config

    app.config.from_object(config_class)

    from app.config import check_access_config, check_database_config, check_secrets_config
    check_database_config(app.config)
    check_secrets_config(app.config)
    check_access_config(app.config)

    if app.config["SQLALCHEMY_DATABASE_URI"].startswith("sqlite:///"):
        db_dir = os.path.dirname(app.config.get("DATABASE_PATH") or "")
        if db_dir:
            os.makedirs(db_dir, exist_ok=True)

    @app.template_filter("tiktok_date")
    def tiktok_date(value):
        """A TikTok create_time (Unix seconds, UTC) as YYYY-MM-DD; blank when missing."""
        from datetime import datetime, timezone
        try:
            return datetime.fromtimestamp(int(value), tz=timezone.utc).strftime("%Y-%m-%d")
        except (TypeError, ValueError, OverflowError, OSError):
            return ""

    db.init_app(app)
    migrate.init_app(app, db, directory=MIGRATIONS_DIR, render_as_batch=True)
    csrf.init_app(app)

    from app import models  # noqa: F401
    from app.routes.auth_routes import auth_bp
    from app.routes.account_routes import account_bp
    from app.routes.post_routes import post_bp
    from app.routes.insights_routes import insights_bp
    from app.routes.api_routes import api_bp

    app.register_blueprint(auth_bp)
    app.register_blueprint(account_bp)
    app.register_blueprint(post_bp)
    app.register_blueprint(insights_bp)
    app.register_blueprint(api_bp)
    csrf.exempt(api_bp)

    @app.errorhandler(CSRFError)
    def handle_csrf_error(error):
        message = "Security token missing or expired. Reload the page and try again."
        if request.headers.get("X-Requested-With") == "XMLHttpRequest":
            return jsonify({"success": False, "error": message}), 400
        return render_template("csrf_error.html", message=message), 400

    return app
