from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
import logging
from app.config.config import config, current_env
import os


db = SQLAlchemy()

def create_app():
    """Create and configure the Flask application"""
    app = Flask(__name__)
    
    # 加载配置
    app.config.from_object(config[current_env])
    
    # 初始化扩展
    CORS(app)
    db.init_app(app)
    
    # 注册蓝图
    from app.api.meta_data import bp as meta_bp
    from app.api.data_resource import bp as resource_bp
    from app.api.data_model import bp as data_model_bp
    from app.api.data_interface import bp as data_interface_bp
    from app.api.data_metric import bp as data_metric_bp
    from app.api.production_line import bp as production_line_bp
    from app.api.graph import bp as graph_bp
    from app.api.system import bp as system_bp
    from app.api.data_source import bp as data_source_bp
    from app.api.data_parse import bp as data_parse_bp
    from app.api.data_flow import bp as data_flow_bp

    app.register_blueprint(meta_bp, url_prefix='/api/meta')
    app.register_blueprint(resource_bp, url_prefix='/api/resource')
    app.register_blueprint(data_model_bp, url_prefix='/api/model')
    app.register_blueprint(data_interface_bp, url_prefix='/api/interface')
    app.register_blueprint(data_metric_bp, url_prefix='/api/metric')
    app.register_blueprint(production_line_bp, url_prefix='/api/pipeline')
    app.register_blueprint(graph_bp, url_prefix='/api/graph')
    app.register_blueprint(system_bp, url_prefix='/api/system')
    app.register_blueprint(data_source_bp, url_prefix='/api/datasource')
    app.register_blueprint(data_parse_bp, url_prefix='/api/parse')
    app.register_blueprint(data_flow_bp, url_prefix='/api/dataflow')
    
    # Configure global response headers
    configure_response_headers(app)
    
    # Configure logging
    configure_logging(app)
    
    # 添加全局异常处理器
    configure_error_handlers(app)
    
    # 输出启动信息
    app.logger.info(f"Starting server in {current_env} mode on port {app.config['PORT']}")
    
    return app

def configure_response_headers(app):
    """Configure global response headers for JSON content"""
    
    @app.after_request
    def after_request(response):
        from flask import request
        
        # 检查是否是API路径
        if request.path.startswith('/api/'):
            # 排除文件下载和特殊响应类型
            if (response.content_type and 
                any(ct in response.content_type for ct in [
                    'application/octet-stream', 
                    'application/pdf', 
                    'image/', 
                    'text/csv',
                    'application/vnd.ms-excel',
                    'application/vnd.openxmlformats-officedocument'
                ])):
                # 保持原有的文件类型不变
                pass
            elif response.content_type and 'application/json' in response.content_type:
                # 确保JSON响应设置正确的Content-Type和charset
                response.headers['Content-Type'] = 'application/json; charset=utf-8'
            elif (not response.content_type or 
                  response.content_type == 'text/html; charset=utf-8' or
                  response.content_type == 'text/plain'):
                # 对于API路由，如果没有明确设置Content-Type或设置为HTML，默认设置为JSON
                response.headers['Content-Type'] = 'application/json; charset=utf-8'
        
        return response

def configure_logging(app):
    """Configure logging for the application"""
    if not app.config.get('LOG_ENABLED', True):
        return None
    
    log_file = app.config.get('LOG_FILE', f'flask_{app.config["FLASK_ENV"]}.log')
    log_level_name = app.config.get('LOG_LEVEL', 'INFO')
    log_level = getattr(logging, log_level_name)
    log_format = app.config.get('LOG_FORMAT', '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
    log_encoding = app.config.get('LOG_ENCODING', 'UTF-8')
    log_to_console = app.config.get('LOG_TO_CONSOLE', True)
    
    # 配置根日志器
    root_logger = logging.getLogger()
    root_logger.setLevel(log_level)
    
    # 清除所有现有处理器
    root_logger.handlers.clear()
    
    # 文件处理器 - 只添加到根日志器
    file_handler = logging.FileHandler(log_file, encoding=log_encoding)
    file_handler.setLevel(log_level)
    logging_format = logging.Formatter(log_format)
    file_handler.setFormatter(logging_format)
    root_logger.addHandler(file_handler)
    
    # 控制台处理器 - 只添加到根日志器
    if log_to_console:
        console = logging.StreamHandler()
        console.setLevel(log_level)
        console.setFormatter(logging_format)
        root_logger.addHandler(console)
    
    # 确保Flask内部日志器使用我们的配置
    app.logger.handlers.clear()  # 移除Flask默认处理器
    
    # 配置app日志器，但禁止传播到根日志器
    logger = logging.getLogger("app")
    logger.setLevel(log_level)
    logger.handlers.clear()  # 清除现有处理器
    logger.propagate = True  # 通过根日志器处理
    
    app.logger.info(f"日志配置完成: 级别={log_level_name}, 文件={log_file}")
    return logger

def configure_error_handlers(app):
    """Configure global error handlers for the application"""
    
    @app.errorhandler(Exception)
    def handle_exception(e):
        """全局异常处理器，捕获所有未处理的异常"""
        # 记录详细的错误信息
        app.logger.error(f"未处理的异常: {str(e)}", exc_info=True)
        
        # 返回标准化的错误响应
        error_response = {
            'success': False,
            'message': f'服务器内部错误: {str(e)}',
            'data': None
        }
        
        return jsonify(error_response), 500
    
    @app.errorhandler(404)
    def handle_not_found(e):
        """处理404错误"""
        app.logger.warning(f"404错误: {str(e)}")
        return jsonify({
            'success': False,
            'message': '请求的资源不存在',
            'data': None
        }), 404
    
    @app.errorhandler(500)
    def handle_internal_error(e):
        """处理500错误"""
        app.logger.error(f"500错误: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': '服务器内部错误',
            'data': None
        }), 500
