from nicegui import ui

from nemo_library_etl.adapter.migman.enums import MigManExtractAdapter, MigManLoadAdapter
from nemo_library_etl.adapter.migman.migmanutils import MigManUtils

from ..render_context import UIRenderContext


def render_setup(ctx: UIRenderContext) -> None:
    runtime = ctx.runtime
    global_config = runtime.global_config
    local_config = runtime.local_config
    merged_config = runtime.merged_config
    form_state = runtime.form_state
    state = runtime.state
    has_changes = runtime.has_changes
    active = runtime.active
    nav_buttons = runtime.nav_buttons
    controller = ctx.controller
    content_container = ctx.content_container
    transform_tab_state = ctx.transform_tab_state
    convenience_hooks = ctx.convenience_hooks
    migmanprojects = ctx.migmanprojects
    get_tip = ctx.get_tip
    mark_changed = ctx.mark_changed
    mark_saved = ctx.mark_saved
    set_active = ctx.set_active
    save_config = ctx.save_config
    reset_config = ctx.reset_config
    renderers = ctx.renderers
    self = ctx.ui_app

    def render_setup():
        if not content_container:
            return

        content_container.clear()
        with content_container:
            ui.label("Setup").classes("text-2xl font-semibold")
            ui.separator()
            ui.label("Configure system setup and connection parameters.")

            # Setup configuration
            setup_config = form_state["data"].setdefault("setup", {})

            # --- Adapter Selection (Side by Side) ---
            with ui.row().classes("mt-4 w-full gap-4 flex items-stretch"):
                # --- Data Source Adapter ---
                with ui.card().classes("flex-1 self-stretch flex flex-col"):
                    ui.label("Data Source Adapter").classes(
                        "text-lg font-semibold mb-2"
                    )
                    ui.label(
                        "Select which data source adapter to use for extraction."
                    ).classes("text-sm mb-4")

                    def on_adapter_change(e):
                        adapter_key = e.value
                        setup_config["source_adapter"] = adapter_key

                        # Prefill tables if empty (so INFORCOM behaves like PROALPHA)
                        extract_cfg = form_state["data"].setdefault("extract", {})
                        adapter_cfg = extract_cfg.setdefault(adapter_key, {})

                        default_tables = (
                            global_config.get("extract", {})
                            .get(adapter_key, {})
                            .get("tables", [])
                            or []
                        )

                        # Only prefill when user has no tables configured ([], None, missing)
                        if default_tables and not adapter_cfg.get("tables"):
                            adapter_cfg["tables"] = list(default_tables)

                        mark_changed()

                        if active["value"] == "Extract":
                            ctx.renderers["Extract"]()

                    current_adapter = setup_config.get(
                        "source_adapter", MigManExtractAdapter.GENERICODBC.value
                    )

                    adapter_select = (
                        ui.select(
                            label="Adapter",
                            options=[
                                MigManExtractAdapter.GENERICODBC.value,
                                MigManExtractAdapter.INFORCOM.value,
                                MigManExtractAdapter.INFORIGF.value,
                                MigManExtractAdapter.INFORAS.value,
                                # MigManExtractAdapter.SAPECC.value,
                                MigManExtractAdapter.PROALPHA.value,
                                MigManExtractAdapter.SAGEKHK.value,
                                MigManExtractAdapter.SAPTENANT.value,
                                # MigManExtractAdapter.SAPSYSTEMDB.value,
                            ],
                            value=current_adapter,
                            on_change=on_adapter_change,
                        )
                        .props("dense")
                        .classes("w-full").tooltip(get_tip("setup.source_adapter"))
                    )

                    ui.label(
                        "Configure the specific adapter settings in the Extract section."
                    ).classes("text-sm text-gray-600 mt-2")

                # --- Target Adapter ---
                with ui.card().classes("flex-1 self-stretch flex flex-col"):
                    ui.label("Target Adapter").classes(
                        "text-lg font-semibold mb-2"
                    )
                    ui.label(
                        "Select which target adapter to use for loading data."
                    ).classes("text-sm mb-4")

                    def on_target_adapter_change(e):
                        setup_config["target_adapter"] = e.value
                        mark_changed()

                    current_target_adapter = setup_config.get(
                        "target_adapter",
                        MigManLoadAdapter.PROALPHA_MIGMAN.value,
                    )

                    target_adapter_select = (
                        ui.select(
                            label="Target Adapter",
                            options=[
                                MigManLoadAdapter.PROALPHA_MIGMAN.value,
                                MigManLoadAdapter.NEMO_BUSINESS_PROCESSES.value,
                            ],
                            value=current_target_adapter,
                            on_change=on_target_adapter_change,
                        )
                        .props("dense")
                        .classes("w-full").tooltip(get_tip("setup.target_adapter"))
                    )

                    ui.label(
                        "Configure the specific target settings in the Load section."
                    ).classes("text-sm text-gray-600 mt-2")

            # --- Project Status File ---
            with ui.card().classes("mt-4 h-full flex flex-col"):
                ui.label("Project Status File").classes(
                    "text-lg font-semibold mb-2"
                )

                def on_project_status_file_change(e):
                    setup_config["project_status_file"] = (
                        e.value if e.value.strip() else None
                    )
                    mark_changed()

                current_project_status_file = setup_config.get(
                    "project_status_file", ""
                )
                if current_project_status_file is None:
                    current_project_status_file = ""

                with ui.row().classes("gap-2 items-end"):
                    project_status_file_input = (
                        ui.input(
                            label="Path to project status file",
                            value=current_project_status_file,
                            placeholder="e.g. ./etl/migman/status/project_status.xlsx",
                            on_change=on_project_status_file_change,
                        )
                        .props("dense")
                        .classes("w-[36rem]").tooltip(get_tip("setup.project_status_file"))
                    )

                    def import_projects_from_file():
                        """Import projects from the specified Excel file."""
                        file_path = project_status_file_input.value
                        if not file_path or not file_path.strip():
                            ui.notify(
                                "Please enter a file path first.",
                                type="warning",
                            )
                            return

                        try:
                            # Check if file exists
                            import os

                            if not os.path.exists(file_path):
                                ui.notify(
                                    f"File not found: {file_path}",
                                    type="negative",
                                )
                                return

                            imported_projects = (
                                MigManUtils.get_migman_projects_from_excel(
                                    file_path
                                )
                            )

                            # Filter imported projects to only include those that exist in migmanprojects
                            valid_projects = [
                                p
                                for p in imported_projects
                                if p in migmanprojects
                            ]
                            invalid_projects = [
                                p
                                for p in imported_projects
                                if p not in migmanprojects
                            ]

                            if valid_projects:
                                # Update the projects selection
                                setup_config["projects"] = valid_projects
                                projects_select.value = valid_projects
                                mark_changed()
                                update_selection_count()

                                message = f"Imported {len(valid_projects)} projects successfully!"
                                if invalid_projects:
                                    message += f" ({len(invalid_projects)} projects not found in database)"
                                ui.notify(message, type="positive")
                            else:
                                ui.notify(
                                    "No valid projects found in the file.",
                                    type="warning",
                                )
                                if invalid_projects:
                                    ui.notify(
                                        f"Invalid projects: {', '.join(invalid_projects[:5])}",
                                        type="info",
                                    )

                        except Exception as e:
                            ui.notify(
                                f"Error importing file: {str(e)}",
                                type="negative",
                            )

                    ui.button(
                        "Import",
                        icon="upload_file",
                        on_click=import_projects_from_file,
                    ).props("size=sm outline").classes("mb-1").tooltip(get_tip("setup.import_projects"))

                ui.label(
                    "Optional file path to track project status and progress. Use the Import button to load projects from this Excel file."
                ).classes("text-sm")

            # --- Projects Selection ---
            with ui.card().classes("mt-4"):
                ui.label("Projects").classes("text-lg font-semibold mb-2")

                current_projects = setup_config.get("projects", [])

                # Display selection count (will be updated via function)
                selection_count = ui.label(
                    f"Selected: {len(current_projects)}"
                ).classes("text-sm font-medium")

                def update_selection_count():
                    current_selection = setup_config.get("projects", [])
                    selection_count.text = f"Selected: {len(current_selection)}"

                def on_projects_change(e):
                    setup_config["projects"] = e.value if e.value else []
                    mark_changed()
                    update_selection_count()

                projects_select = (
                    ui.select(
                        options=migmanprojects,
                        value=current_projects,
                        multiple=True,
                        label="Select projects",
                        on_change=on_projects_change,
                    )
                    .props("use-chips clearable use-input input-debounce=0")
                    .classes("w-[48rem]")
                    .tooltip(get_tip("setup.projects"))
                )

                # Add helper text
                ui.label(
                    f"Select one or more projects from the list. Search functionality is available."
                ).classes("text-sm mt-2")

                # Add buttons for quick selection
                with ui.row().classes("gap-2 mt-3"):

                    def select_all():
                        setup_config["projects"] = migmanprojects.copy()
                        projects_select.value = migmanprojects.copy()
                        mark_changed()
                        update_selection_count()

                    def select_none():
                        setup_config["projects"] = []
                        projects_select.value = []
                        mark_changed()
                        update_selection_count()

                    ui.button("Select All", on_click=select_all).props(
                        "size=sm outline"
                    ).tooltip(get_tip("setup.projects.select_all"))
                    ui.button("Select None", on_click=select_none).props(
                        "size=sm outline"
                    ).tooltip(get_tip("setup.projects.select_none"))

            # --- Multi-Project List for Feature Assignments ---
            with ui.card().classes("mt-4"):
                ui.label("Multi-Project List for Feature Assignments").classes(
                    "text-lg font-semibold mb-2"
                )

                current_feature_assignments = setup_config.get(
                    "mult_project_list_feature_assignments", []
                )

                # Display selection count for feature assignments
                feature_assignments_count = ui.label(
                    f"Keys: {len(current_feature_assignments)}"
                ).classes("text-sm font-medium")

                def update_feature_assignments_count():
                    current_selection = setup_config.get(
                        "mult_project_list_feature_assignments", []
                    )
                    feature_assignments_count.text = (
                        f"Keys: {len(current_selection)}"
                    )

                def on_feature_assignments_change(e):
                    # Split by comma, strip whitespace, and filter out empty strings
                    keys = [key.strip() for key in (e.value or "").split(",") if key.strip()]
            
                    if keys:
                        setup_config["mult_project_list_feature_assignments"] = keys
                    else:
                        setup_config.pop("mult_project_list_feature_assignments", None)
            
                    mark_changed()
                    update_feature_assignments_count()

                feature_assignments_input = (
                    ui.input(
                        label="Feature assignment keys (comma-separated)",
                        value=", ".join(current_feature_assignments),
                        placeholder="key1, key2, key3",
                        on_change=on_feature_assignments_change,
                    )
                    .props("dense")
                    .classes("w-[48rem]").tooltip(get_tip("setup.mult_project_list_feature_assignments"))
                )

                ui.label(
                    "Enter comma-separated keys for feature assignments. Each key should be a single word."
                ).classes("text-sm mt-2")

            # --- Multi-Project List for Texts ---
            with ui.card().classes("mt-4"):
                ui.label("Multi-Project List for Texts").classes(
                    "text-lg font-semibold mb-2"
                )

                current_texts = setup_config.get("mult_project_list_texts", [])

                # Display selection count for texts
                texts_count = ui.label(f"Keys: {len(current_texts)}").classes(
                    "text-sm font-medium"
                )

                def update_texts_count():
                    current_selection = setup_config.get(
                        "mult_project_list_texts", []
                    )
                    texts_count.text = f"Keys: {len(current_selection)}"

                def on_texts_change(e):
                    # Split by comma, strip whitespace, and filter out empty strings
                    keys = [key.strip() for key in (e.value or "").split(",") if key.strip()]
                    if keys:
                        setup_config["mult_project_list_texts"] = keys
                    else:
                        setup_config.pop("mult_project_list_texts", None)

                    mark_changed()
                    update_texts_count()
                texts_input = (
                    ui.input(
                        label="Text keys (comma-separated)",
                        value=", ".join(current_texts),
                        placeholder="text1, text2, text3",
                        on_change=on_texts_change,
                    )
                    .props("dense")
                    .classes("w-[48rem]").tooltip(get_tip("setup.mult_project_list_text"))
                )

                ui.label(
                    "Enter comma-separated keys for texts. Each key should be a single word."
                ).classes("text-sm mt-2")

    render_setup()
