import { toId } from "../components/TreeNode.js";

import type { TreeNodeProps } from "../components/TreeNode.js";
import type { Tree, TreeState } from "../index.js";
import type { KeyboardEvent } from "react";

export function handleSearch(this: Tree, e: any) {
    const searchTerm = (typeof e === "string" ? e : e.target.value).toLowerCase().trim();
    const { tree, onSearchResult } = this.props;
    const resultTree: TreeNodeProps[] = [];
    const filter = (node: TreeNodeProps) => {
        node.title.toLowerCase().indexOf(searchTerm) > -1 && resultTree.push(node);
        node.childNodes && node.childNodes.forEach(filter);
    };

    clearTimeout(this.searchTimeout);
    if (searchTerm) {
        this.setState({
            searchTerm,
            resultTreeBusy: true,
            resultSelectedNodeIdx: undefined,
        });

        // Delay for searching
        this.searchTimeout = setTimeout(() => {
            tree.forEach(filter);
            const resultTreeSliced = resultTree.slice(0, 19);
            this.setState({
                resultSelectedNodeIdx: -1,
                resultTreeBusy: false,
                resultTree: resultTreeSliced,
            });

            onSearchResult && onSearchResult(resultTreeSliced);
        }, 700);
    } else {
        this.setState({
            searchTerm,
            resultSelectedNodeIdx: undefined,
            resultTreeBusy: false,
            resultTree: undefined,
        });

        onSearchResult && onSearchResult(undefined);
    }
}

export function handleSearchKeyDown(this: Tree, e: KeyboardEvent) {
    const { onSelect } = this.props;
    if (typeof this.state.resultSelectedNodeIdx === "number" && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
        const addition = e.key === "ArrowDown" ? 1 : -1;
        this.setState((state: TreeState) => ({ resultSelectedNodeIdx: state.resultSelectedNodeIdx + addition }));
        e.preventDefault();
        return false;
    } else if (e.key === "Enter" && onSelect) {
        // Handle select
        const searchSelected = document.getElementById(this.id()).querySelectorAll(".aiot-search-selected");
        if (onSelect && searchSelected.length) {
            const id = (searchSelected[0].attributes as any)["data-id"].value;
            onSelect(toId(id));
        }
        e.preventDefault();
        return false;
    } else if (e.key === "Escape") {
        this.handleSearch("");
        e.preventDefault();
        return false;
    }
    return true;
}

export function handleSearchClose(this: Tree) {
    this.handleSearch("");
}

export function handleSearchBlur(this: Tree) {
    const { resultSelectedNodeIdx } = this.state;
    this.setState({
        resultSelectedNodeIdx: typeof resultSelectedNodeIdx === "number" ? -1 : undefined,
    });
}
