var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import Adw from 'gi://Adw';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
import Gtk from 'gi://Gtk';
import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
import { DatabaseBackend, getDataPath, getDefaultDatabaseFile } from '../../common/constants.js';
import { registerClass } from '../../common/gjs.js';
import { Icon } from '../../common/icons.js';
import { bind_enum } from '../../common/settings.js';
import { GdaDialog, checkGda } from '../dependencies/dependencies.js';
import { makeResettable } from '../utils.js';
Gio._promisify(Gtk.FileDialog.prototype, 'open', 'open_finish');
let DatabaseBackendItem = class DatabaseBackendItem extends GObject.Object {
    constructor(primary, secondary = '') {
        super();
        this.primary = primary;
        this.secondary = secondary;
    }
};
DatabaseBackendItem = __decorate([
    registerClass({
        Properties: {
            primary: GObject.ParamSpec.string('primary', null, null, GObject.ParamFlags.READWRITE, ''),
            secondary: GObject.ParamSpec.string('secondary', null, null, GObject.ParamFlags.READWRITE, ''),
        },
    })
], DatabaseBackendItem);
let HistorySettings = class HistorySettings extends Adw.PreferencesGroup {
    prefs;
    window;
    _settings;
    _defaultDatabaseLocation;
    _databaseBackend;
    _databaseBackendButton;
    _databaseLocation;
    _clipboardHistory;
    _libgda = false;
    constructor(prefs, window) {
        super({
            title: _('History'),
        });
        this.prefs = prefs;
        this.window = window;
        this._defaultDatabaseLocation = GLib.build_filenamev([getDataPath(prefs).get_path(), 'clipboard.db']);
        const model = new Gio.ListStore({ item_type: DatabaseBackendItem.$gtype });
        model.append(new DatabaseBackendItem(_('Memory')));
        model.append(new DatabaseBackendItem(_('SQLite'), _('(recommended)')));
        model.append(new DatabaseBackendItem(_('JSON')));
        const factory = new Gtk.SignalListItemFactory();
        factory.connect('setup', (_factory, listItem) => (listItem.child = new Gtk.Label()));
        factory.connect('bind', (_factory, listItem) => (listItem.child.label = listItem.get_item().primary));
        const listFactory = new Gtk.SignalListItemFactory();
        listFactory.connect('setup', (_factory, listItem) => {
            const box = new Gtk.Box({ spacing: 6 });
            box.append(new Gtk.Label());
            box.append(new Gtk.Label({ css_classes: ['dim-label'] }));
            listItem.child = box;
        });
        listFactory.connect('bind', (_factory, listItem) => {
            const item = listItem.get_item();
            const box = listItem.child;
            const primaryLabel = box.get_first_child();
            const secondaryLabel = primaryLabel.get_next_sibling();
            primaryLabel.label = item.primary;
            secondaryLabel.label = item.secondary;
        });
        this._databaseBackend = new Adw.ComboRow({
            title: _('Database'),
            subtitle: _('Select which database type to use for storing your clipboard'),
            factory,
            listFactory,
            model,
            sensitive: false,
        });
        this.add(this._databaseBackend);
        const separator = new Gtk.Separator({
            orientation: Gtk.Orientation.VERTICAL,
            margin_top: 9,
            margin_bottom: 9,
            margin_start: 6,
        });
        this._databaseBackend.add_suffix(separator);
        this._databaseBackendButton = new Gtk.Button({
            icon_name: Icon.Undo,
            valign: Gtk.Align.CENTER,
            css_classes: ['flat'],
        });
        this._databaseBackend.add_suffix(this._databaseBackendButton);
        this._databaseBackendButton.connect('clicked', this.databaseBackendButtonClicked.bind(this));
        this._databaseLocation = new Adw.ActionRow({
            title: _('Database Location'),
            activatable: true,
            sensitive: false,
        });
        this._databaseLocation.connect('activated', () => this.openDatabaseLocation(window));
        this.add(this._databaseLocation);
        this._clipboardHistory = new Adw.ComboRow({
            title: _('Clipboard History'),
            subtitle: _('Choose what to do with your clipboard history when you restart, log out, or shut down your system'),
            model: Gtk.StringList.new([_('Clear'), _('Keep Pinned/Tagged'), _('Keep All')]),
            sensitive: false,
        });
        this.add(this._clipboardHistory);
        const historyLength = new Adw.SpinRow({
            title: _('History Length'),
            subtitle: _('Select how many items to keep in the clipboard history'),
            adjustment: new Gtk.Adjustment({ lower: 10, upper: 500, step_increment: 1, page_increment: 5, value: 50 }),
        });
        this.add(historyLength);
        const timeLimit = new Adw.SpinRow({
            title: _('History Time Limit'),
            subtitle: _('Select how many minutes to keep items in the clipboard history. Set to 0 to disable the time limit'),
            adjustment: new Gtk.Adjustment({ lower: 0, upper: 1440, step_increment: 5, page_increment: 15, value: 0 }),
        });
        this.add(timeLimit);
        // Bind properties
        this._settings = prefs.getSettings();
        this._settings.bind('database-location', this, 'database-location', Gio.SettingsBindFlags.DEFAULT);
        bind_enum(this._settings, 'clipboard-history', this._clipboardHistory, 'selected');
        this._settings.bind('history-length', historyLength, 'value', Gio.SettingsBindFlags.DEFAULT);
        this._settings.bind('history-time', timeLimit, 'value', Gio.SettingsBindFlags.DEFAULT);
        makeResettable(this._databaseLocation, this._settings, 'database-location');
        makeResettable(this._clipboardHistory, this._settings, 'clipboard-history');
        makeResettable(historyLength, this._settings, 'history-length');
        makeResettable(timeLimit, this._settings, 'history-time');
        // Check gda
        checkGda(this.prefs)
            .then(this.initializeDatabaseBackend.bind(this))
            .catch(() => { });
    }
    get databaseLocation() {
        if (this._databaseLocation.subtitle === this._defaultDatabaseLocation) {
            return '';
        }
        else {
            return this._databaseLocation.subtitle;
        }
    }
    set databaseLocation(value) {
        if (value === '') {
            this._databaseLocation.subtitle = this._defaultDatabaseLocation;
        }
        else {
            this._databaseLocation.subtitle = value;
        }
        this.notify('database-location');
    }
    initializeDatabaseBackend(gda) {
        this._libgda = gda;
        this._databaseBackend.sensitive = true;
        let backend = this._settings.get_enum('database-backend');
        if (backend === DatabaseBackend.Default) {
            let location = this._settings.get_string('database-location');
            location ||= getDataPath(this.prefs).get_child('clipboard.db').get_path();
            const file = Gio.File.new_for_path(location);
            const dir = file.get_parent();
            const fileName = file.get_basename().replace(/(.db|.json)$/, '');
            const dbFile = dir.get_child(`${fileName}.db`);
            const jsonFile = dir.get_child(`${fileName}.json`);
            if (this._settings.get_boolean('in-memory-database')) {
                backend = DatabaseBackend.Memory;
            }
            else if (dbFile.query_exists(null)) {
                backend = DatabaseBackend.Sqlite;
            }
            else if (jsonFile.query_exists(null)) {
                backend = DatabaseBackend.Json;
            }
            else if (this._libgda) {
                backend = DatabaseBackend.Sqlite;
            }
            else {
                backend = DatabaseBackend.Json;
            }
        }
        this._databaseBackend.selected = backend - 1;
        this._databaseBackend.connect('notify::selected', () => {
            this._settings.set_enum('database-backend', this._databaseBackend.selected + 1);
            this.updateDatabaseBackend(true);
        });
        this.updateDatabaseBackend(false);
    }
    updateDatabaseBackend(update) {
        const backend = this._databaseBackend.selected + 1;
        if (update)
            this._settings.set_enum('database-backend', backend);
        const isDefaultLocation = this.databaseLocation === '';
        this._defaultDatabaseLocation = getDefaultDatabaseFile(this.prefs, backend).get_path();
        if (isDefaultLocation)
            this._databaseLocation.subtitle = this._defaultDatabaseLocation;
        this._databaseLocation.sensitive = backend !== DatabaseBackend.Memory;
        this._clipboardHistory.sensitive = backend !== DatabaseBackend.Memory;
        if (backend === DatabaseBackend.Sqlite) {
            if (this._libgda) {
                this._databaseBackendButton.sensitive = false;
                this._databaseBackendButton.icon_name = Icon.Undo;
            }
            else {
                this._databaseBackendButton.sensitive = true;
                this._databaseBackendButton.icon_name = Icon.Warning;
            }
        }
        else {
            this._databaseBackendButton.sensitive = true;
            this._databaseBackendButton.icon_name = Icon.Undo;
        }
    }
    databaseBackendButtonClicked() {
        const backend = this._databaseBackend.selected + 1;
        if (backend === DatabaseBackend.Sqlite) {
            if (!this._libgda) {
                const gdaDialog = new GdaDialog();
                gdaDialog.present(this.window);
            }
        }
        else {
            this._databaseBackend.selected = DatabaseBackend.Sqlite - 1;
        }
    }
    async openDatabaseLocation(window) {
        const selected = this._databaseBackend.selected;
        const patterns = selected === 0 ? [] : selected === 1 ? ['*.db'] : ['*.json'];
        const dialog = new Gtk.FileDialog({
            initial_file: Gio.File.new_for_path(this.databaseLocation),
            default_filter: new Gtk.FileFilter({ patterns }),
        });
        try {
            const result = await dialog.open(window, null);
            const path = result?.get_path();
            if (path != null) {
                this.databaseLocation = path;
            }
        }
        catch {
            console.error('Failed to open database location');
        }
    }
};
HistorySettings = __decorate([
    registerClass({
        Properties: {
            'database-location': GObject.ParamSpec.string('database-location', null, null, GObject.ParamFlags.READWRITE, ''),
        },
    })
], HistorySettings);
export { HistorySettings };
