import { createEffect, createSignal, onCleanup } from "solid-js";
import { isModifierKey } from "../utils/isModifierKey";
import { normalizeKey } from "../utils/normalizeKey";
import { sortKeys } from "../utils/sortKeys";

export type Shortcut = string[];

const RESERVED_SHORTCUTS = [
    ["Command", "C"],
    ["Command", "V"],
    ["Command", "X"],
    ["Command", "A"],
    ["Command", "Z"],
    ["Command", "Q"],
    // Windows/Linux
    ["Control", "C"],
    ["Control", "V"],
    ["Control", "X"],
    ["Control", "A"],
    ["Control", "Z"],
];

export function useShortcutEditor(
    shortcut: Shortcut,
    onChange: (shortcut: Shortcut) => void,
) {
    console.log("DBG: ", shortcut);

    const [isEditing, setIsEditing] = createSignal(false);
    const [currentKeys, setCurrentKeys] = createSignal<string[]>([]);
    const pressedKeys = new Set<string>();

    const startEditing = () => {
        setIsEditing(true);
        setCurrentKeys([]);
    };

    const saveShortcut = async () => {
        if (!isEditing() || currentKeys().length < 2) return;

        const hasModifier = currentKeys().some(isModifierKey);
        const hasNonModifier = currentKeys().some((key) => !isModifierKey(key));

        if (!hasModifier || !hasNonModifier) return;

        const isReserved = RESERVED_SHORTCUTS.some(
            (reserved) =>
                reserved.length === currentKeys().length &&
                reserved.every(
                    (key, index) =>
                        key.toLowerCase() ===
                        currentKeys()[index].toLowerCase(),
                ),
        );

        if (isReserved) {
            console.error("This is a system reserved shortcut");
            return;
        }

        // Sort keys to ensure consistent order (modifiers first)
        const sortedKeys = sortKeys(currentKeys());

        onChange(sortedKeys);
        setIsEditing(false);
        setCurrentKeys([]);
    };

    const cancelEditing = () => {
        setIsEditing(false);
        setCurrentKeys([]);
    };

    const handleKeyDown = (e: KeyboardEvent) => {
        if (!isEditing()) return;

        e.preventDefault();
        e.stopPropagation();

        const key = normalizeKey(e.code);

        // Update pressed keys
        pressedKeys.add(key);

        setCurrentKeys(() => {
            const keys = Array.from(pressedKeys);
            let modifiers = keys.filter(isModifierKey);
            let nonModifiers = keys.filter((k) => !isModifierKey(k));

            if (modifiers.length > 2) {
                modifiers = modifiers.slice(0, 2);
            }

            if (nonModifiers.length > 2) {
                nonModifiers = nonModifiers.slice(0, 2);
            }

            // Combine modifiers and non-modifiers
            return [...modifiers, ...nonModifiers];
        });
    };

    const handleKeyUp = (e: KeyboardEvent) => {
        if (!isEditing()) return;
        const key = normalizeKey(e.code);
        pressedKeys.delete(key);
    };

    // Use createEffect to handle event listeners based on editing state
    createEffect(() => {
        if (isEditing()) {
            window.addEventListener("keydown", handleKeyDown);
            window.addEventListener("keyup", handleKeyUp);
        } else {
            window.removeEventListener("keydown", handleKeyDown);
            window.removeEventListener("keyup", handleKeyUp);
            pressedKeys.clear();
        }
    });

    // Clean up event listeners on unmount
    onCleanup(() => {
        window.removeEventListener("keydown", handleKeyDown);
        window.removeEventListener("keyup", handleKeyUp);
    });

    return {
        isEditing,
        currentKeys,
        startEditing,
        saveShortcut,
        cancelEditing,
    };
}
