"""
Public Web Frontend - Flask Application Factory

This is a lightweight web frontend that provides HTML/HTMX UI for the Code of Conquest game.
All business logic is handled by the API backend - this frontend only renders views and
makes HTTP requests to the API.
"""

from flask import Flask
from flask import render_template
import structlog
import yaml
import os
from pathlib import Path
from datetime import datetime, timezone


logger = structlog.get_logger(__name__)


def load_config():
    """Load configuration from YAML file based on environment."""
    env = os.getenv("FLASK_ENV", "development")
    config_path = Path(__file__).parent.parent / "config" / f"{env}.yaml"

    with open(config_path, 'r') as f:
        config = yaml.safe_load(f)

    logger.info("configuration_loaded", env=env, config_path=str(config_path))
    return config


def create_app():
    """Create and configure the Flask application."""
    app = Flask(__name__,
                template_folder="../templates",
                static_folder="../static")

    # Load configuration
    config = load_config()
    app.config.update(config)

    # Configure secret key from environment
    app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production')

    # Context processor to make API config and user available in templates
    @app.context_processor
    def inject_template_globals():
        """Make API base URL and current user available to all templates."""
        from .utils.auth import get_current_user
        return {
            'api_base_url': app.config.get('api', {}).get('base_url', 'http://localhost:5000'),
            'current_user': get_current_user()
        }

    # Register blueprints
    from .views.auth_views import auth_bp
    from .views.character_views import character_bp
    from .views.game_views import game_bp

    app.register_blueprint(auth_bp)
    app.register_blueprint(character_bp)
    app.register_blueprint(game_bp)

    # Register Jinja filters
    def format_timestamp(iso_string: str) -> str:
        """Convert ISO timestamp to relative time (e.g., '2 mins ago')"""
        if not iso_string:
            return ""
        try:
            timestamp = datetime.fromisoformat(iso_string.replace('Z', '+00:00'))
            now = datetime.now(timezone.utc)
            diff = now - timestamp

            seconds = diff.total_seconds()
            if seconds < 60:
                return "Just now"
            elif seconds < 3600:
                mins = int(seconds / 60)
                return f"{mins} min{'s' if mins != 1 else ''} ago"
            elif seconds < 86400:
                hours = int(seconds / 3600)
                return f"{hours} hr{'s' if hours != 1 else ''} ago"
            else:
                days = int(seconds / 86400)
                return f"{days} day{'s' if days != 1 else ''} ago"
        except Exception as e:
            logger.warning("timestamp_format_failed", iso_string=iso_string, error=str(e))
            return iso_string

    app.jinja_env.filters['format_timestamp'] = format_timestamp

    # Register dev blueprint only in development
    env = os.getenv("FLASK_ENV", "development")
    if env == "development":
        from .views.dev import dev_bp
        app.register_blueprint(dev_bp)
        logger.info("dev_blueprint_registered", message="Dev testing routes available at /dev")

    # Error handlers
    @app.errorhandler(404)
    def not_found(error):
        return render_template('errors/404.html'), 404

    @app.errorhandler(500)
    def internal_error(error):
        logger.error("internal_server_error", error=str(error))
        return render_template('errors/500.html'), 500

    logger.info("flask_app_created", blueprints=["auth", "character", "game"])

    return app
