import App from 'resource:///com/github/Aylur/ags/app.js';
import Applications from 'resource:///com/github/Aylur/ags/service/applications.js';
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
// TODO: find cleaner way to import this
import { Fzf } from '../../node_modules/fzf/dist/fzf.es.js';

import { Box, Entry, Icon, Label, ListBox, Scrollable } from 'resource:///com/github/Aylur/ags/widget.js';

import PopupWindow from '../misc/popup.js';
import AppItem from './app-item.js';


const Applauncher = ({ window_name = 'applauncher' } = {}) => {
    let fzfResults;
    const list = ListBox();

    const setSort = (text) => {
        const fzf = new Fzf(Applications.list, {
            selector: (app) => app.name,
            tiebreakers: [(a, b) => b._frequency -
                a._frequency],
        });

        fzfResults = fzf.find(text);
        list.set_sort_func((a, b) => {
            const row1 = a.get_children()[0]?.app.name;
            const row2 = b.get_children()[0]?.app.name;

            if (!row1 || !row2) {
                return 0;
            }

            return fzfResults.indexOf(row1) -
            fzfResults.indexOf(row1) || 0;
        });
    };

    const makeNewChildren = () => {
        list.get_children().forEach((ch) => {
            ch.destroy();
        });

        const children = Applications.query('')
            .flatMap((app) => AppItem(app));

        children.forEach((ch) => {
            list.add(ch);
        });
        list.show_all();
    };

    makeNewChildren();

    const placeholder = Label({
        label: "   Couldn't find a match",
        className: 'placeholder',
    });

    const entry = Entry({
        // Set some text so on-change works the first time
        text: '-',
        hexpand: true,

        on_accept: ({ text }) => {
            const appList = Applications.query(text || '');

            if (appList[0]) {
                App.closeWindow(window_name);
                Hyprland.sendMessage(`dispatch exec sh -c
                    ${appList[0].executable}`);
                ++appList[0].frequency;
            }
        },

        on_change: ({ text }) => {
            setSort(text);
            let visibleApps = 0;

            list.get_children().forEach((row) => {
                row.changed();

                const item = row.get_children()[0];

                if (item?.app) {
                    const isMatching = fzfResults.find((r) => {
                        return r.item.name === item.app.name;
                    });

                    row.visible = isMatching;

                    if (isMatching) {
                        ++visibleApps;
                    }
                }
            });
            placeholder.visible = visibleApps <= 0;
        },
    });

    return Box({
        className: 'applauncher',
        vertical: true,

        children: [
            Box({
                className: 'header',
                children: [
                    Icon('preferences-system-search-symbolic'),
                    entry,
                ],
            }),

            Scrollable({
                hscroll: 'never',
                child: Box({
                    vertical: true,
                    children: [list, placeholder],
                }),
            }),
        ],

        connections: [[App, (_, name, visible) => {
            if (name !== window_name) {
                return;
            }

            entry.text = '';

            if (visible) {
                entry.grab_focus();
            }
            else {
                makeNewChildren();
            }
        }]],
    });
};

export default () => PopupWindow({
    name: 'applauncher',
    focusable: true,
    child: Applauncher(),
});