import os
import logging
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_jwt_extended import JWTManager
from config import config
import colorlog

# Initialize extensions
db = SQLAlchemy()
login_manager = LoginManager()
jwt = JWTManager()

def create_app(config_name=None):
    """Application factory pattern"""
    if config_name is None:
        config_name = os.environ.get('FLASK_ENV', 'default')
    
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    
    # Initialize extensions
    db.init_app(app)
    login_manager.init_app(app)
    jwt.init_app(app)
    
    # Configure login manager
    login_manager.login_view = 'auth.login'
    login_manager.login_message = 'Please log in to access this page.'
    login_manager.login_message_category = 'info'
    
    # Register user loader
    @login_manager.user_loader
    def load_user(user_id):
        """Load user for Flask-Login"""
        from app.models import User
        return User.query.get(int(user_id))
    
    # Configure logging
    setup_logging(app)
    
    # Register blueprints
    from app.auth import bp as auth_bp
    app.register_blueprint(auth_bp, url_prefix='/auth')
    
    from app.api import bp as api_bp
    app.register_blueprint(api_bp, url_prefix='/api')
    
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)
    
    from app.upload import bp as upload_bp
    app.register_blueprint(upload_bp, url_prefix='/upload')
    
    # Create database tables and run migrations (handle missing database gracefully)
    with app.app_context():
        try:
            db.create_all()
            
            # Run database migrations
            from app.database import run_migrations
            migration_result = run_migrations()
            
            if migration_result['status'] == 'success':
                app.logger.info(f"Database migrations completed: {migration_result['message']}")
            elif migration_result['status'] == 'partial':
                app.logger.warning(f"Database migrations partially completed: {migration_result['message']}")
            elif migration_result['status'] == 'error':
                app.logger.error(f"Database migrations failed: {migration_result['message']}")
            
        except Exception as e:
            app.logger.warning(f"Database initialization failed: {str(e)}")
            app.logger.warning("Database may not exist or be accessible. Please check database configuration.")
    
    return app

def setup_logging(app):
    """Setup application logging with colors for development"""
    if not app.debug and not app.testing:
        # Production logging
        from logging import handlers as logging_handlers
        if not os.path.exists('logs'):
            os.mkdir('logs')
        
        file_handler = logging_handlers.RotatingFileHandler(
            'logs/fixture-daemon.log', maxBytes=10240, backupCount=10
        )
        file_handler.setFormatter(logging.Formatter(
            '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
        ))
        file_handler.setLevel(logging.INFO)
        app.logger.addHandler(file_handler)
        app.logger.setLevel(logging.INFO)
        app.logger.info('Fixture Daemon startup')
    else:
        # Development logging with colors
        handler = colorlog.StreamHandler()
        handler.setFormatter(colorlog.ColoredFormatter(
            '%(log_color)s%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
            log_colors={
                'DEBUG': 'cyan',
                'INFO': 'green',
                'WARNING': 'yellow',
                'ERROR': 'red',
                'CRITICAL': 'red,bg_white',
            }
        ))
        
        app.logger.addHandler(handler)
        app.logger.setLevel(logging.DEBUG)
