"""
Comprehensive demo for Widget system
Shows primitive widgets, composition, and nested widgets
"""

from imgui_bundle import imgui, implot, immapp
from imery.frontend.widget_factory import WidgetFactory
from imery.backend.data_tree import DataTree
from imery.backend.kernel import Kernel
from imery.dispatcher import Dispatcher
from imery.types import DataPath
from pathlib import Path

import sys

# Global state
demo_widget = None
kernel_widget = None
implot_widget = None
fastplotlib_widget = None
foreach_key_widget = None
table_widget = None
kernel = None
dispatcher = None
factory = None
data = {
    "metadata": {"label": "Demo Root"},
    "children": {
        # Text widget demos
        "text-single": {"metadata": {"label": "Single dynamic text value"}},
        "text-list": {
            "metadata": {"label": "Text List"},
            "children": {
                "0": {"metadata": {"label": "Text item 1"}},
                "1": {"metadata": {"label": "Text item 2"}},
                "2": {"metadata": {"label": "Text item 3"}}
            }
        },
        "text-dict": {
            "metadata": {"label": "Text Dict"},
            "children": {
                "first": {"metadata": {"label": "First text"}},
                "second": {"metadata": {"label": "Second text"}},
                "third": {"metadata": {"label": "Third text"}}
            }
        },

        # BulletText widget demos
        "bullet-single": {"metadata": {"label": "Single bullet point"}},
        "bullet-list": {
            "metadata": {"label": "Bullet List"},
            "children": {
                "0": {"metadata": {"label": "Bullet A"}},
                "1": {"metadata": {"label": "Bullet B"}},
                "2": {"metadata": {"label": "Bullet C"}}
            }
        },
        "bullet-dict": {
            "metadata": {"label": "Bullet Dict"},
            "children": {
                "feature1": {"metadata": {"label": "Feature One"}},
                "feature2": {"metadata": {"label": "Feature Two"}},
                "feature3": {"metadata": {"label": "Feature Three"}}
            }
        },

        # SeparatorText widget demos
        "separator-single": {"metadata": {"label": "Single Section Title"}},
        "separator-list": {
            "metadata": {"label": "Separator List"},
            "children": {
                "0": {"metadata": {"label": "Section 1"}},
                "1": {"metadata": {"label": "Section 2"}},
                "2": {"metadata": {"label": "Section 3"}}
            }
        },
        "separator-dict": {
            "metadata": {"label": "Separator Dict"},
            "children": {
                "intro": {"metadata": {"label": "Introduction"}},
                "main": {"metadata": {"label": "Main Content"}},
                "conclusion": {"metadata": {"label": "Conclusion"}}
            }
        },

        # Button widget demos
        "button-single": {"metadata": {"label": "Click Me"}},
        "button-list": {
            "metadata": {"label": "Button List"},
            "children": {
                "0": {"metadata": {"label": "Action 1"}},
                "1": {"metadata": {"label": "Action 2"}},
                "2": {"metadata": {"label": "Action 3"}}
            }
        },
        "button-dict": {
            "metadata": {"label": "Button Dict"},
            "children": {
                "save": {"metadata": {"label": "Save"}},
                "load": {"metadata": {"label": "Load"}},
                "delete": {"metadata": {"label": "Delete"}}
            }
        },

        # TreeNode widget demos
        "tree-single": {"metadata": {"label": "Single Tree Node"}},
        "tree-list": {
            "metadata": {"label": "Tree List"},
            "children": {
                "0": {"metadata": {"label": "Tree A"}},
                "1": {"metadata": {"label": "Tree B"}},
                "2": {"metadata": {"label": "Tree C"}}
            }
        },
        "tree-dict": {
            "metadata": {"label": "Tree Dict"},
            "children": {
                "node1": {"metadata": {"label": "First Node"}},
                "node2": {"metadata": {"label": "Second Node"}},
                "node3": {"metadata": {"label": "Third Node"}}
            }
        },

        # CollapsingHeader widget demos
        "collapse-single": {"metadata": {"label": "Single Collapsing Section"}},
        "collapse-list": {
            "metadata": {"label": "Collapse List"},
            "children": {
                "0": {"metadata": {"label": "List Section 1"}},
                "1": {"metadata": {"label": "List Section 2"}},
                "2": {"metadata": {"label": "List Section 3"}}
            }
        },
        "collapse-dict": {
            "metadata": {"label": "Collapse Dict"},
            "children": {
                "settings": {"metadata": {"label": "Settings"}},
                "advanced": {"metadata": {"label": "Advanced"}},
                "debug": {"metadata": {"label": "Debug"}}
            }
        },

        # Menu widget demos
        "menu-single": {"metadata": {"label": "Main Menu"}},
        "menu-list": {
            "metadata": {"label": "Menu List"},
            "children": {
                "0": {"metadata": {"label": "Menu 1"}},
                "1": {"metadata": {"label": "Menu 2"}},
                "2": {"metadata": {"label": "Menu 3"}}
            }
        },
        "menu-dict": {
            "metadata": {"label": "Menu Dict"},
            "children": {
                "file": {"metadata": {"label": "File"}},
                "edit": {"metadata": {"label": "Edit"}},
                "view": {"metadata": {"label": "View"}}
            }
        },

        # MenuItem widget demos
        "menuitem-single": {"metadata": {"label": "Menu Action"}},
        "menuitem-list": {
            "metadata": {"label": "MenuItem List"},
            "children": {
                "0": {"metadata": {"label": "Item A"}},
                "1": {"metadata": {"label": "Item B"}},
                "2": {"metadata": {"label": "Item C"}}
            }
        },
        "menuitem-dict": {
            "metadata": {"label": "MenuItem Dict"},
            "children": {
                "new": {"metadata": {"label": "New"}},
                "open": {"metadata": {"label": "Open"}},
                "close": {"metadata": {"label": "Close"}}
            }
        },

        # Input widgets (require single values)
        "input-text": {"metadata": {"label": "Editable text"}},
        "input-int": {"metadata": {"label": "42"}},
        "slider-int": {"metadata": {"label": "50"}},
        "slider-float": {"metadata": {"label": "0.5"}},
        "combo": {"metadata": {"label": "Option A"}},
        "checkbox": {"metadata": {"label": "True"}}
    }
}


def demo_main():
    """Main demo loop"""
    global demo_widget, kernel_widget, implot_widget, fastplotlib_widget, foreach_key_widget, table_widget, kernel, dispatcher, factory, data

    # Initialize ImPlot context once
    if not implot.get_current_context():
        implot.create_context()

    # Initialize factory once
    if factory is None:
        layouts_dir = Path(__file__).parent / "layouts"
        factory_res = WidgetFactory.create(layouts_dir = layouts_dir)
        if not factory_res:
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Factory Error: {factory_res}")
            print(factory_res)
            sys.exit(1)
        factory = factory_res.unwrapped

    # Initialize dispatcher once
    if dispatcher is None:
        dispatcher_res = Dispatcher.create()
        if not dispatcher_res:
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Dispatcher Creation Error: {dispatcher_res}")
            print(dispatcher_res)
            sys.exit(1)
        dispatcher = dispatcher_res.unwrapped

    # Initialize kernel once
    if kernel is None:
        kernel_res = Kernel.create(dispatcher=dispatcher)
        if not kernel_res:
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Kernel Creation Error: {kernel_res}")
            sys.exit(1)
        kernel = kernel_res.unwrapped

    imgui.text("Widget System Demo")
    imgui.separator()

    if imgui.tree_node("lalaa"):
        print("lala opened")
        if imgui.button("Test"):
            print("test button pressed")
        imgui.tree_pop()
    # Button to create demo widget
    if imgui.button("Widgets Demo"):
        print(demo_widget)
        if demo_widget is None:
            print("creating Widgets Demo popup")
            data_tree = DataTree(data)
            res = factory.create_widget("demo.widgets-demo-popup", data_tree, DataPath("/"))
            if not res:
                imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Widget Error: {res}")
                print(res)
                sys.exit(1)
            else:
                demo_widget = res.unwrapped

    imgui.same_line()

    # Button to create kernel demo
    if imgui.button("Kernel Demo"):
        if kernel_widget is None:
            # Wrap kernel in DataTree with selection tracking
            kernel_data = {
                "metadata": {
                    "selected": "(none)"
                },
                "children": {
                    "kernel": kernel
                }
            }
            kernel_tree = DataTree(kernel_data)
            res = factory.create_widget("demo.kernel-demo-popup", kernel_tree, DataPath("/"))
            if not res:
                print("demo widget error!", res)
                imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Kernel Widget Error: {res}")
                sys.exit(1)
            else:
                kernel_widget = res.unwrapped


    imgui.same_line()

    # Button to create implot demo
    if imgui.button("Implot Demo"):
        if implot_widget is None:
            # Open waveform devices and create data structure
            implot_data = _create_implot_data()
            if implot_data:
                data_tree = DataTree(implot_data)
                res = factory.create_widget("demo.implot-demo-popup", data_tree, DataPath("/"))
                if not res:
                    print("implot widget error!", res)
                    imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Implot Widget Error: {res}")
                    sys.exit(1)
                else:
                    implot_widget = res.unwrapped

    imgui.same_line()

    # Button to create foreach-key demo
    if imgui.button("Foreach-Key Demo"):
        if foreach_key_widget is None:
            data_tree = DataTree(data)
            res = factory.create_widget("demo.foreach-key-demo-popup", data_tree, DataPath("/"))
            if not res:
                print("foreach-key widget error!", res)
                imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Foreach-Key Widget Error: {res}")
                sys.exit(1)
            else:
                foreach_key_widget = res.unwrapped

    imgui.same_line()

    # Button to create table demo
    if imgui.button("Table Demo"):
        if table_widget is None:
            data_tree = DataTree(data)
            res = factory.create_widget("demo.table-demo-popup", data_tree, DataPath("/"))
            if not res:
                print("table widget error!", res)
                imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Table Widget Error: {res}")
                sys.exit(1)
            else:
                table_widget = res.unwrapped

    # Render demo widget
    if demo_widget:
        res = demo_widget.render()
        if not res:
            # Render failed with error
            print(f"ERROR: Demo widget render failed: {res}")
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Render Error: {res}")
            demo_widget = None
            sys.exit(1)
        elif not res.unwrapped:
            # Render returned False (popup closed)
            print("render demo_widget returned false")
            demo_widget = None

    # Render kernel widget
    if kernel_widget:
        res = kernel_widget.render()
        if not res:
            # Render failed with error
            print(f"ERROR: Kernel widget render failed: {res}")
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Kernel Render Error: {res}")
            kernel_widget = None
            sys.exit(1)
        elif not res.unwrapped:
            # Render returned False (popup closed)
            kernel_widget = None

    # Render implot widget
    if implot_widget:
        res = implot_widget.render()
        if not res:
            # Render failed with error
            print(f"ERROR: Implot widget render failed: {res}")
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Implot Render Error: {res}")
            implot_widget = None
            sys.exit(1)
        elif not res.unwrapped:
            # Render returned False (popup closed)
            implot_widget = None

    # Render foreach-key widget
    if foreach_key_widget:
        res = foreach_key_widget.render()
        if not res:
            # Render failed with error
            print(f"ERROR: Foreach-key widget render failed: {res}")
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Foreach-Key Render Error: {res}")
            foreach_key_widget = None
            sys.exit(1)
        elif not res.unwrapped:
            # Render returned False (popup closed)
            foreach_key_widget = None

    # Render table widget
    if table_widget:
        res = table_widget.render()
        if not res:
            # Render failed with error
            print(f"ERROR: Table widget render failed: {res}")
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Table Render Error: {res}")
            table_widget = None
            sys.exit(1)
        elif not res.unwrapped:
            # Render returned False (popup closed)
            sys.exit(1)
            table_widget = None

    # Show live data
    imgui.separator()
    imgui.text("Live Data (updates as you edit):")
    _render_data(data, indent=0)


def _create_implot_data():
    """Create data structure for implot demo by opening waveform devices"""
    global kernel

    if not kernel:
        print("ERROR: Kernel not initialized")
        return None

    # Open three waveform devices: sine, square, triangle
    # Path format: /providers/waveform/available/sine
    waveforms = ["sine", "square", "triangle"]
    children = {}

    for waveform in waveforms:
        # Open channel 0 of the waveform device through kernel
        # This will open the device and return the mediated buffer
        channel_path = DataPath(f"/providers/waveform/available/{waveform}/0")
        config = {
            "frequency": 440.0,
            "sample_rate": 48000,
            "period_size": 10240
        }

        res = kernel.open(channel_path, config)
        if not res:
            print(f"ERROR: Failed to open {waveform}/0: {res}")
            continue

        # The result should be the mediated buffer
        mediated_buffer = res.unwrapped
        children[waveform] = {
            "metadata": {
                "label": waveform.capitalize(),
                "buffer": mediated_buffer
            }
        }

    if not children:
        print("ERROR: No buffers created")
        return None

    # Create implot data structure with new format
    return {"children": children}


def _render_data(data_dict, indent=0):
    """Recursively render data dictionary"""
    indent_str = "  " * indent
    for key, value in data_dict.items():
        if isinstance(value, dict):
            imgui.text(f"{indent_str}{key}:")
            _render_data(value, indent + 1)
        else:
            imgui.text(f"{indent_str}{key}: {value}")


def demo_all_primitives():
    """Demo showing all primitive widgets"""
    global widget, factory, data

    # Initialize factory once
    if factory is None:
        factory_res = WidgetFactory.create()
        if not factory_res:
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Factory Error: {factory_res}")
            return
        factory = factory_res.unwrapped

    imgui.text("All Primitives Demo")
    imgui.separator()

    # Button to create widget
    if imgui.button("Create All Primitives"):
        primitives_data = {
            "children": {
                "text-input": {"metadata": {"label": "Hello"}},
                "int-input": {"metadata": {"label": "42"}},
                "linear-slider": {"metadata": {"label": "50"}},
                "log-slider": {"metadata": {"label": "1000"}},
                "float-slider": {"metadata": {"label": "5.0"}},
                "combo-select": {"metadata": {"label": "Option 1"}},
                "checkbox-val": {"metadata": {"label": "True"}}
            }
        }

        data_tree = DataTree(primitives_data)
        res = factory.create_widget("demo.all-primitives", data_tree, DataPath("/"))
        if res:
            widget = res.unwrapped
            data = primitives_data

    imgui.separator()

    if widget:
        res = widget.render()
        if not res:
            imgui.text_colored(imgui.ImVec4(1.0, 0.0, 0.0, 1.0), f"Render Error: {res}")

    imgui.separator()
    imgui.text("Live Data:")
    _render_data(data, indent=0)


if __name__ == "__main__":
    # Run demo_main by default with maximum refresh rate for ImPlot
    immapp.run(
        gui_function=demo_main,
        window_title="Widget Demo - Composition",
        window_size=(1000, 700),
        fps_idle=0  # Maximum refresh rate (no idle FPS limit)
    )

    # Uncomment to run all primitives demo:
    # immapp.run(
    #     gui_function=demo_all_primitives,
    #     window_title="Widget Demo - All Primitives",
    #     window_size=(1000, 700)
    # )
