import logging

from flask import Flask
from flask_login import LoginManager

from .config import Config
from .db import init_db, user_exists, create_user, get_all_settings


class _SuppressPreviewPoll(logging.Filter):
    """Drop werkzeug access-log lines for the noisy label-preview poll endpoint."""
    def filter(self, record):
        return '/print/preview/labels' not in record.getMessage()

logging.getLogger('werkzeug').addFilter(_SuppressPreviewPoll())


login_manager = LoginManager()


def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialise DB schema
    init_db(app.config['DATABASE_PATH'])

    # Override config with any values stored in the DB (set via Settings UI)
    _load_db_settings(app)

    # Flask-Login
    login_manager.init_app(app)
    login_manager.login_view = 'auth.login'
    login_manager.login_message = 'Please log in to access the warehouse app.'
    login_manager.login_message_category = 'warning'

    @login_manager.user_loader
    def load_user(user_id):
        from .db import get_user_by_id
        from .models import User
        row = get_user_by_id(int(user_id), app.config['DATABASE_PATH'])
        return User(row) if row else None

    # Seed initial user if no accounts exist yet
    _seed_initial_user(app)

    # Register blueprints
    from .routes.orders import orders_bp
    from .routes.settings import settings_bp
    from .routes.auth import auth_bp
    from .routes.print_preview import preview_bp
    from .routes.label_templates import label_templates_bp
    from .routes.products import products_bp
    from .routes.sync import sync_bp

    app.register_blueprint(orders_bp)
    app.register_blueprint(settings_bp)
    app.register_blueprint(auth_bp)
    app.register_blueprint(preview_bp)
    app.register_blueprint(label_templates_bp)
    app.register_blueprint(products_bp)
    app.register_blueprint(sync_bp)

    @app.context_processor
    def inject_globals():
        return {
            'print_mode':      app.config.get('PRINT_MODE', 'api'),
            'app_version':     _read_version(),
            'make_test_mode':  app.config.get('MAKE_TEST_MODE', '') == '1',
        }

    return app


def _read_version() -> str:
    """Read VERSION file from the project root."""
    import pathlib
    vfile = pathlib.Path(__file__).parent.parent / 'VERSION'
    try:
        return vfile.read_text().strip()
    except Exception:
        return ''


def _load_db_settings(app):
    """Overlay Flask config with values persisted in the settings table."""
    db_settings = get_all_settings(app.config['DATABASE_PATH'])
    for key, value in db_settings.items():
        if value:
            app.config[key] = value


def _seed_initial_user(app):
    """Create robert@soldered.com on first run if no users exist."""
    from werkzeug.security import generate_password_hash

    db_path = app.config['DATABASE_PATH']
    if not user_exists(db_path):
        initial_password = 'Soldered2026!'
        create_user(
            email='robert@soldered.com',
            password_hash=generate_password_hash(initial_password),
            db_path=db_path,
        )
        app.logger.info(
            'Seeded initial user robert@soldered.com — '
            'default password: Soldered2026!'
        )
