import dash
import dash_bootstrap_components as dbc
from .config.settings import AppSettings
from .ui.layout import AppLayout
from .ui.callbacks.data_processing import DataProcessingCallbacks
from .ui.callbacks.visualization import VisualizationCallbacks
from .ui.callbacks.interactions import InteractionCallbacks


def create_app():
    import os

    # Get the project root directory (two levels up from this file)
    project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    assets_path = os.path.join(project_root, "assets")

    app = dash.Dash(
        __name__, external_stylesheets=[dbc.themes.BOOTSTRAP], assets_folder=assets_path
    )

    # Allow callbacks to components that are dynamically created in tabs
    app.config.suppress_callback_exceptions = True

    layout_manager = AppLayout()
    app.layout = layout_manager.create_layout()

    DataProcessingCallbacks()
    VisualizationCallbacks()
    InteractionCallbacks()

    # Register client-side callback for embedding generation
    _register_client_side_callbacks(app)

    return app


def _register_client_side_callbacks(app):
    """Register client-side callbacks for browser-based processing."""
    from dash import Input, Output, State

    # Client-side callback for embedding generation
    app.clientside_callback(
        """
        function(nClicks, textContent, modelName, tokenizationMethod, batchSize, category, subcategory) {
            if (!nClicks || !textContent || !textContent.trim()) {
                return window.dash_clientside.no_update;
            }
            
            console.log('🔍 Checking for Transformers.js...');
            console.log('window.dash_clientside:', typeof window.dash_clientside);
            console.log('window.dash_clientside.transformers:', typeof window.dash_clientside?.transformers);
            console.log('generateEmbeddings function:', typeof window.dash_clientside?.transformers?.generateEmbeddings);
            
            if (typeof window.dash_clientside !== 'undefined' && 
                typeof window.dash_clientside.transformers !== 'undefined' &&
                typeof window.dash_clientside.transformers.generateEmbeddings === 'function') {
                
                console.log('✅ Calling Transformers.js generateEmbeddings...');
                return window.dash_clientside.transformers.generateEmbeddings(
                    nClicks, textContent, modelName, tokenizationMethod, category, subcategory
                );
            }
            
            // More detailed error information
            let errorMsg = '❌ Transformers.js not available. ';
            if (typeof window.dash_clientside === 'undefined') {
                errorMsg += 'dash_clientside not found.';
            } else if (typeof window.dash_clientside.transformers === 'undefined') {
                errorMsg += 'transformers module not found.';
            } else if (typeof window.dash_clientside.transformers.generateEmbeddings !== 'function') {
                errorMsg += 'generateEmbeddings function not found.';
            }
            
            console.error(errorMsg);
            
            return [
                { error: 'Transformers.js not loaded. Please refresh the page and try again.' },
                errorMsg + ' Please refresh the page.',
                'danger',
                false
            ];
        }
        """,
        [
            Output("embeddings-generated-trigger", "data"),
            Output("text-input-status-immediate", "children"),
            Output("text-input-status-immediate", "color"),
            Output("generate-embeddings-btn", "disabled", allow_duplicate=True),
        ],
        [Input("generate-embeddings-btn", "n_clicks")],
        [
            State("text-input-area", "value"),
            State("model-selection", "value"),
            State("tokenization-method", "value"),
            State("batch-size", "value"),
            State("text-category", "value"),
            State("text-subcategory", "value"),
        ],
        prevent_initial_call=True,
    )


def run_app(app=None, debug=None, host=None, port=None):
    if app is None:
        app = create_app()

    app.run(
        debug=debug if debug is not None else AppSettings.DEBUG,
        host=host if host is not None else AppSettings.HOST,
        port=port if port is not None else AppSettings.PORT,
    )


if __name__ == "__main__":
    app = create_app()
    run_app(app)
