#!/usr/bin/env python3

import glob
import os

from fenrirscreenreader.core import debug


class DynamicKeyboardLayoutCommand:
    """Dynamic command class for keyboard layout selection"""

    def __init__(self, layoutName, layoutPath, env):
        self.layoutName = layoutName
        self.layoutPath = layoutPath
        # Extract just the base name without extension for comparison
        self.layoutBaseName = layoutName
        self.env = env

    def initialize(self, environment):
        self.env = environment

    def shutdown(self):
        pass

    def get_description(self):
        return f"Set keyboard layout to {self.layoutName}"

    def run(self):
        try:
            settingsManager = self.env["runtime"]["SettingsManager"]
            currentLayout = settingsManager.get_setting(
                "keyboard", "keyboard_layout"
            )

            # Check if already set (compare both full path and base name)
            currentBaseName = os.path.splitext(os.path.basename(currentLayout))[0] if currentLayout else ""
            if currentBaseName.lower() == self.layoutBaseName.lower() or currentLayout.lower() == self.layoutPath.lower():
                self.env["runtime"]["OutputManager"].present_text(
                    f"Keyboard layout already set to {self.layoutName}"
                )
                return

            # Set the new layout in the config file using full path
            try:
                # Update the setting in memory
                settingsManager.set_setting(
                    "keyboard", "keyboard_layout", self.layoutPath
                )

                # Save to the actual config file
                settingsManager.save_settings()

                self.env["runtime"]["OutputManager"].present_text(
                    f"Keyboard layout set to {self.layoutName}. Please restart Fenrir for this change to take effect."
                )
                # Play accept sound
                self.env["runtime"]["OutputManager"].present_text(
                    "", sound_icon="Accept", interrupt=False
                )
            except Exception as e:
                self.env["runtime"]["OutputManager"].present_text(
                    f"Failed to change keyboard layout to {self.layoutName}"
                )
                self.env["runtime"]["DebugManager"].write_debug_out(
                    f"DynamicKeyboardLayout: Error setting layout {self.layoutName}: {e}",
                    debug.DebugLevel.ERROR,
                )
                # Play error sound
                self.env["runtime"]["OutputManager"].present_text(
                    "", sound_icon="ErrorSound", interrupt=False
                )

        except Exception as e:
            self.env["runtime"]["OutputManager"].present_text(
                f"Keyboard layout change error: {str(e)}", interrupt=True
            )
            self.env["runtime"]["DebugManager"].write_debug_out(
                f"DynamicKeyboardLayout: Unexpected error for {self.layoutName}: {e}",
                debug.DebugLevel.ERROR,
            )

    def set_callback(self, callback):
        pass


def add_dynamic_keyboard_layout_menus(VmenuManager):
    """Add dynamic keyboard layout menus to vmenu system"""
    try:
        env = VmenuManager.env

        # Get keyboard layout files
        layouts = get_keyboard_layouts(env)
        if not layouts:
            return

        # Create keyboard layouts submenu
        layoutMenu = {}

        # Add layout commands
        for layoutName, layoutPath in layouts:
            layoutCommand = DynamicKeyboardLayoutCommand(
                layoutName, layoutPath, env
            )
            layoutMenu[f"{layoutName} Action"] = layoutCommand

        # Find keyboard menu in existing vmenu structure
        # If fenrir menu exists, add layouts under it
        if "fenrir Menu" in VmenuManager.menuDict:
            fenrirMenu = VmenuManager.menuDict["fenrir Menu"]
            if "keyboard Menu" in fenrirMenu:
                # Add dynamic layouts to existing keyboard menu
                keyboardMenu = fenrirMenu["keyboard Menu"]
                keyboardMenu["Keyboard Layouts Menu"] = layoutMenu
            else:
                # Create keyboard menu with layouts
                fenrirMenu["keyboard Menu"] = {
                    "Keyboard Layouts Menu": layoutMenu
                }
        else:
            # Create standalone keyboard layouts menu
            VmenuManager.menuDict["Keyboard Layouts Menu"] = layoutMenu

    except Exception as e:
        # Use debug manager for error logging
        if "DebugManager" in env.get("runtime", {}):
            env["runtime"]["DebugManager"].write_debug_out(
                f"Error creating dynamic keyboard layout menus: {e}",
                debug.DebugLevel.ERROR,
            )
        else:
            print(f"Error creating dynamic keyboard layout menus: {e}")


def get_keyboard_layouts(env):
    """Get available keyboard layouts from keyboard directory"""
    layouts = []

    try:
        # Get keyboard directory paths
        keyboardDirs = []

        # Check system installation path
        systemKeyboardPath = "/etc/fenrirscreenreader/keyboard/"
        if os.path.exists(systemKeyboardPath):
            keyboardDirs.append(systemKeyboardPath)

        # Check source/development path
        try:
            import fenrirscreenreader

            fenrirPath = os.path.dirname(fenrirscreenreader.__file__)
            devKeyboardPath = os.path.join(
                fenrirPath, "..", "..", "config", "keyboard"
            )
            devKeyboardPath = os.path.abspath(devKeyboardPath)
            if os.path.exists(devKeyboardPath):
                keyboardDirs.append(devKeyboardPath)
        except Exception:
            pass

        # Get current layout setting path
        try:
            currentLayoutSetting = env["runtime"]["SettingsManager"].get_setting(
                "keyboard", "keyboard_layout"
            )
            if currentLayoutSetting and os.path.exists(currentLayoutSetting):
                currentLayoutDir = os.path.dirname(currentLayoutSetting)
                if currentLayoutDir not in keyboardDirs:
                    keyboardDirs.append(currentLayoutDir)
        except Exception:
            pass

        # Scan for .conf files
        seenLayouts = set()
        for keyboardDir in keyboardDirs:
            try:
                confFiles = glob.glob(os.path.join(keyboardDir, "*.conf"))
                for confFile in confFiles:
                    layoutName = os.path.splitext(os.path.basename(confFile))[
                        0
                    ]
                    if layoutName not in seenLayouts:
                        seenLayouts.add(layoutName)
                        layouts.append((layoutName, confFile))
            except Exception as e:
                if "DebugManager" in env.get("runtime", {}):
                    env["runtime"]["DebugManager"].write_debug_out(
                        f"Error scanning keyboard directory {keyboardDir}: {e}",
                        debug.DebugLevel.WARNING,
                    )

        # Sort layouts alphabetically
        layouts.sort(key=lambda x: x[0].lower())

    except Exception as e:
        if "DebugManager" in env.get("runtime", {}):
            env["runtime"]["DebugManager"].write_debug_out(
                f"Error getting keyboard layouts: {e}",
                debug.DebugLevel.ERROR,
            )

    return layouts
