import { defineStore } from 'pinia'
import useConnectionStore from './connections.js'

/**
 * connection dialog type
 * @enum {number}
 */
export const ConnDialogType = {
    NEW: 0,
    EDIT: 1,
}

const useDialogStore = defineStore('dialog', {
    state: () => ({
        connDialogVisible: false,
        /** @type {ConnDialogType} **/
        connType: ConnDialogType.NEW,
        connParam: null,

        groupDialogVisible: false,
        editGroup: '',

        /**
         * @property {string} prefix
         * @property {string} server
         * @property {int} db
         */
        newKeyParam: {
            prefix: '',
            server: '',
            db: 0,
        },
        newKeyDialogVisible: false,

        keyFilterParam: {
            server: '',
            db: 0,
            type: '',
            pattern: '*',
        },
        keyFilterDialogVisible: false,

        addFieldParam: {
            server: '',
            db: 0,
            key: '',
            keyCode: null,
            type: null,
        },
        addFieldsDialogVisible: false,

        renameKeyParam: {
            server: '',
            db: 0,
            key: '',
        },
        renameDialogVisible: false,

        deleteKeyParam: {
            server: '',
            db: 0,
            key: '',
        },
        deleteKeyDialogVisible: false,

        exportKeyParam: {
            server: '',
            db: 0,
            keys: [],
        },
        exportKeyDialogVisible: false,

        importKeyParam: {
            server: '',
            db: 0,
        },
        importKeyDialogVisible: false,

        flushDBParam: {
            server: '',
            db: 0,
        },
        flushDBDialogVisible: false,

        ttlDialogVisible: false,
        ttlParam: {
            server: '',
            db: 0,
            key: '',
            keys: [],
            ttl: 0,
        },

        decodeDialogVisible: false,
        decodeParam: {
            name: '',
            auto: true,
            decodePath: '',
            decodeArgs: [],
            encodePath: '',
            encodeArgs: [],
        },

        preferencesDialogVisible: false,
        preferencesTag: '',

        aboutDialogVisible: false,
    }),
    actions: {
        openNewDialog() {
            this.connParam = null
            this.connType = ConnDialogType.NEW
            this.connDialogVisible = true
        },
        closeConnDialog() {
            this.connDialogVisible = false
        },

        async openEditDialog(name) {
            const connStore = useConnectionStore()
            const profile = await connStore.getConnectionProfile(name)
            this.connParam = connStore.mergeConnectionProfile(connStore.newDefaultConnection(name), profile)
            this.connType = ConnDialogType.EDIT
            this.connDialogVisible = true
        },

        async openDuplicateDialog(name) {
            const connStore = useConnectionStore()
            this.connParam = {}
            let profile
            let suffix = 1
            do {
                let profileName = name
                if (suffix > 1) {
                    profileName += suffix
                }
                profile = await connStore.getConnectionProfile(profileName)
                if (profile != null) {
                    suffix += 1
                    if (profileName === name) {
                        this.connParam = profile
                    }
                } else {
                    this.connParam = connStore.mergeConnectionProfile(
                        connStore.newDefaultConnection(profileName),
                        this.connParam,
                    )
                    this.connParam.name = profileName
                    break
                }
            } while (true)
            this.connType = ConnDialogType.NEW
            this.connDialogVisible = true
        },

        openNewGroupDialog() {
            this.editGroup = ''
            this.groupDialogVisible = true
        },
        closeNewGroupDialog() {
            this.groupDialogVisible = false
        },

        /**
         *
         * @param {string} server
         * @param {number} db
         * @param {string} [pattern]
         * @param {string} [type]
         */
        openKeyFilterDialog(server, db, pattern, type) {
            this.keyFilterParam.server = server
            this.keyFilterParam.db = db
            this.keyFilterParam.type = type || ''
            this.keyFilterParam.pattern = pattern || '*'
            this.keyFilterDialogVisible = true
        },
        closeKeyFilterDialog() {
            this.keyFilterDialogVisible = false
        },

        /**
         *
         * @param {string} name
         */
        openRenameGroupDialog(name) {
            this.editGroup = name
            this.groupDialogVisible = true
        },
        closeRenameGroupDialog() {
            this.groupDialogVisible = false
        },

        /**
         *
         * @param {string} server
         * @param {number} db
         * @param {string} key
         */
        openRenameKeyDialog(server, db, key) {
            this.renameKeyParam.server = server
            this.renameKeyParam.db = db
            this.renameKeyParam.key = key
            this.renameDialogVisible = true
        },
        closeRenameKeyDialog() {
            this.renameDialogVisible = false
        },

        /**
         *
         * @param {string} server
         * @param {number} db
         * @param {string|string[]} [key]
         */
        openDeleteKeyDialog(server, db, key = '*') {
            this.deleteKeyParam.server = server
            this.deleteKeyParam.db = db
            this.deleteKeyParam.key = key
            this.deleteKeyDialogVisible = true
        },
        closeDeleteKeyDialog() {
            this.deleteKeyDialogVisible = false
        },

        /**
         *
         * @param {string} server
         * @param {number} db
         * @param {string|string[]} keys
         */
        openExportKeyDialog(server, db, keys) {
            this.exportKeyParam.server = server
            this.exportKeyParam.db = db
            this.exportKeyParam.keys = keys
            this.exportKeyDialogVisible = true
        },
        closeExportKeyDialog() {
            this.exportKeyDialogVisible = false
        },

        /**
         *
         * @param {string} server
         * @param {number} db
         */
        openImportKeyDialog(server, db) {
            this.importKeyParam.server = server
            this.importKeyParam.db = db
            this.importKeyDialogVisible = true
        },
        closeImportKeyDialog() {
            this.importKeyDialogVisible = false
        },

        openFlushDBDialog(server, db) {
            this.flushDBParam.server = server
            this.flushDBParam.db = db
            this.flushDBDialogVisible = true
        },
        closeFlushDBDialog() {
            this.flushDBDialogVisible = false
        },

        /**
         *
         * @param {string} prefix
         * @param {string} server
         * @param {number} db
         */
        openNewKeyDialog(prefix, server, db) {
            this.newKeyParam.prefix = prefix
            this.newKeyParam.server = server
            this.newKeyParam.db = db
            this.newKeyDialogVisible = true
        },
        closeNewKeyDialog() {
            this.newKeyDialogVisible = false
        },

        /**
         *
         * @param {string} server
         * @param {number} db
         * @param {string} key
         * @param {number[]|null} keyCode
         * @param {string} type
         */
        openAddFieldsDialog(server, db, key, keyCode, type) {
            this.addFieldParam.server = server
            this.addFieldParam.db = db
            this.addFieldParam.key = key
            this.addFieldParam.keyCode = keyCode
            this.addFieldParam.type = type
            this.addFieldsDialogVisible = true
        },
        closeAddFieldsDialog() {
            this.addFieldsDialogVisible = false
        },

        /**
         *
         * @param {string} server
         * @param {number} db
         * @param {string|number[]} [key]
         * @param {string[]|number[][]} [keys]
         * @param {number} [ttl]
         */
        openTTLDialog({ server, db, key, keys, ttl = -1 }) {
            this.ttlDialogVisible = true
            this.ttlParam.server = server
            this.ttlParam.db = db
            this.ttlParam.key = key
            this.ttlParam.keys = keys
            this.ttlParam.ttl = ttl
        },
        closeTTLDialog() {
            this.ttlDialogVisible = false
        },

        /**
         *
         * @param {string} name
         * @param {boolean} auto
         * @param {string} decodePath
         * @param {string[]} decodeArgs
         * @param {string} encodePath
         * @param {string[]} encodeArgs
         */
        openDecoderDialog({
            name = '',
            auto = true,
            decodePath = '',
            decodeArgs = [],
            encodePath = '',
            encodeArgs = [],
        } = {}) {
            this.decodeDialogVisible = true
            this.decodeParam.name = name
            this.decodeParam.auto = auto !== false
            this.decodeParam.decodePath = decodePath
            this.decodeParam.decodeArgs = decodeArgs || []
            this.decodeParam.encodePath = encodePath
            this.decodeParam.encodeArgs = encodeArgs || []
        },

        closeDecoderDialog() {
            this.decodeDialogVisible = false
        },

        openPreferencesDialog(tag = '') {
            this.preferencesDialogVisible = true
            this.preferencesTag = tag
        },
        closePreferencesDialog() {
            this.preferencesDialogVisible = false
            this.preferencesTag = ''
        },

        openAboutDialog() {
            this.aboutDialogVisible = true
        },
        closeAboutDialog() {
            this.aboutDialogVisible = false
        },
    },
})

export default useDialogStore
