// uiComponents.js
// UI du mini gestionnaire de mots de passe.

import St from 'gi://St';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import * as ExtensionUtils from 'resource:///org/gnome/shell/misc/extensionUtils.js';

const Clutter = imports.gi.Clutter;
const Clipboard = St.Clipboard.get_default();
const ClipboardType = St.ClipboardType.CLIPBOARD;

function copyToClipboard(text) {
    if (text)
        Clipboard.set_text(ClipboardType, text);
}

export class PasswordEntryRow extends PopupMenu.PopupBaseMenuItem {
    constructor(entry) {
        super({ reactive: true });

        const box = new St.BoxLayout({ vertical: false, x_expand: true });

        let labelWidget;
        if (entry.url) {
            labelWidget = new St.Label({
                text: entry.label,
                style_class: 'password-applet-label-link',
                x_expand: true
            });
            labelWidget.clutter_text.underline = true;
            labelWidget.connect('button-press-event', () => {
                Gio.AppInfo.launch_default_for_uri(entry.url, null);
            });
        } else {
            labelWidget = new St.Label({ text: entry.label, x_expand: true });
        }

        box.add_child(labelWidget);

        box.add_child(new St.Label({ text: entry.username, x_expand: true }));
        box.add_child(new St.Label({ text: '••••••••' }));

        const uBtn = new St.Button({ label: 'U' });
        uBtn.connect('clicked', () => copyToClipboard(entry.username));
        box.add_child(uBtn);

        const pBtn = new St.Button({ label: 'P' });
        pBtn.connect('clicked', () => copyToClipboard(entry.password_enc));
        box.add_child(pBtn);

        this.actor.add_child(box);
    }
}

export class PasswordListSection extends PopupMenu.PopupMenuSection {
    setEntries(entries) {
        this.removeAll();

        if (!entries.length) {
            this.addMenuItem(new PopupMenu.PopupMenuItem(
                'Aucune entrée', { reactive: false }
            ));
            return;
        }

        for (const e of entries)
            this.addMenuItem(new PasswordEntryRow(e));
    }
}

export class AddEntrySection extends PopupMenu.PopupMenuSection {
    constructor(repo, refreshCb) {
        super();
        this._repo = repo;
        this._refreshCb = refreshCb;
        this._showAddButton();
    }

    _showAddButton() {
        this.removeAll();
        const item = new PopupMenu.PopupMenuItem('➕ Ajouter une entrée');
        item.connect('activate', () => this._showForm());
        this.addMenuItem(item);
    }

    _showForm() {
        this.removeAll();
        const wrapper = new PopupMenu.PopupBaseMenuItem({ reactive: false });
        const box = new St.BoxLayout({ vertical: true });

        const mkEntry = hint =>
            new St.Entry({ hint_text: hint, style_class: 'password-applet-entry' });

        const label = mkEntry("Label");
        const user = mkEntry("User");
        const pwd = mkEntry("Password");
        const url = mkEntry("URL");
        const notes = mkEntry("Notes");

        const mkRow = (name, widget) => {
            const row = new St.BoxLayout();
            row.add_child(new St.Label({ text: name + " : " }));
            row.add_child(widget);
            return row;
        };

        box.add_child(mkRow("Label", label));
        box.add_child(mkRow("User", user));
        box.add_child(mkRow("Password", pwd));
        box.add_child(mkRow("URL", url));
        box.add_child(mkRow("Notes", notes));

        const btnRow = new St.BoxLayout();

        const save = new St.Button({ label: "Enregistrer" });
        save.connect('clicked', () => {
            const entry = {
                label: label.get_text().trim(),
                username: user.get_text().trim(),
                password: pwd.get_text().trim(),
                url: url.get_text().trim(),
                notes: notes.get_text().trim()
            };

            if (!entry.label || !entry.username || !entry.password) {
                Main.notify("Password Applet", "Champs obligatoires manquants");
                return;
            }

            this._repo.addEntry(entry);
            this._refreshCb();
            this._showAddButton();
        });

        const cancel = new St.Button({ label: "Annuler" });
        cancel.connect('clicked', () => this._showAddButton());

        btnRow.add_child(save);
        btnRow.add_child(cancel);

        box.add_child(btnRow);
        wrapper.actor.add_child(box);

        this.addMenuItem(wrapper);
    }
}

export class PasswordApplet extends PanelMenu.Button {
    constructor(repo) {
        super(0.0, 'PasswordApplet', false);

        this._repo = repo;

        this.add_child(new St.Icon({
            icon_name: 'dialog-password-symbolic',
            style_class: 'system-status-icon'
        }));

        this._list = new PasswordListSection();
        this.menu.addMenuItem(this._list);

        this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());

        this._add = new AddEntrySection(repo, () => this._reload());
        this.menu.addMenuItem(this._add);

        this._reload();
    }

    _reload() {
        const entries = this._repo.listEntries();
        this._list.setEntries(entries);
    }
}
