import { idle, readFile, Process } from 'astal';
import { App, Astal, Gtk, Widget } from 'astal/gtk3';

import AstalGreet from 'gi://AstalGreet';

import { centerCursor } from '../../lib';


export default (hyprpaper: InstanceType<typeof Process>) => {
    const DEFAULT_NAME = 'matt';
    const PARSED_INDEX = {
        name: 0,
        uid: 2,
        gid: 3,
        desc: 4,
        home: 5,
        shell: 6,
    };

    const parsePasswd = (fileContent: string) => {
        const splitUsers = fileContent.split('\n');
        const parsedUsers = splitUsers.map((u) => {
            const user = u.split(':');

            return {
                name: user[PARSED_INDEX.name],
                uid: Number(user[PARSED_INDEX.uid]),
                gid: Number(user[PARSED_INDEX.gid]),
                desc: user[PARSED_INDEX.desc],
                home: user[PARSED_INDEX.home],
                shell: user[PARSED_INDEX.shell],
            };
        });

                // Filter out system users, nixbld users and nobody
        return parsedUsers.filter((u) => {
            return u.uid >= 1000 &&
                    !u.name.includes('nixbld') &&
                    u.name !== 'nobody';
        });
    };

    const users = parsePasswd(readFile('/etc/passwd'));

    const dropdown = new Gtk.ComboBoxText();

    dropdown.show_all();

    users.forEach((u) => {
        dropdown.append(null, u.name);
    });

    const response = <label /> as Widget.Label;

    const password = (
        <entry
            placeholderText="Password"
            visibility={false}

            setup={(self) => idle(() => {
                self.grab_focus();
            })}

            onActivate={(self) => {
                AstalGreet.login(
                    dropdown.get_active_text() ?? '',
                    self.get_text() || '',
                    'Hyprland',
                    (_, res) => {
                        try {
                            AstalGreet.login_finish(res);
                            App.get_window('greeter')?.set_visible(false);
                            hyprpaper.kill();

                            setTimeout(() => {
                                App.quit();
                            }, 500);
                        }
                        catch (error) {
                            response.set_label(JSON.stringify(error));
                        }
                    },
                );
            }}
        />
    );

    return (
        <window
            name="greeter"
            application={App}
            keymode={Astal.Keymode.ON_DEMAND}
            visible={false}
            setup={(self) => {
                centerCursor();
                setTimeout(() => {
                    self.set_visible(true);
                    password.grab_focus();
                }, 1000);
            }}
        >
            <box
                vertical
                halign={Gtk.Align.CENTER}
                valign={Gtk.Align.CENTER}
                hexpand
                vexpand
                className="base"
            >
                <box
                    vertical
                    halign={Gtk.Align.CENTER}
                    valign={Gtk.Align.CENTER}
                    hexpand
                    vexpand
                    className="linked"

                    setup={() => {
                        idle(() => {
                            const usernames = users.map((u) => u.name);

                            if (usernames.includes(DEFAULT_NAME)) {
                                dropdown.set_active(usernames.indexOf(DEFAULT_NAME));
                            }
                        });
                    }}
                >
                    {dropdown}
                    {password}
                </box>

                {response}
            </box>
        </window>
    );
};