<template>
    <div v-if="isEmpty(field.connections)">No connections set.</div>

    <div v-else-if="isEmpty(drivers)">No valid drivers.</div>

    <div v-else class="uk-inline uk-width-1-1" @click.self.prevent="empty ? add() : select()">
        <div class="uk-position-center-right uk-position-small">
            <ul class="uk-iconnav uk-flex-nowrap">
                <li v-if="authorizationRequired">
                    <a
                        tabindex="-1"
                        :title="$t('Insufficient Scope Access')"
                        class="uk-icon-link uk-preserve-width uk-text-danger"
                        uk-icon="warning"
                        uk-tooltip="delay: 500"
                        @click.prevent="edit()"
                    ></a>
                </li>
                <li v-else-if="value">
                    <a
                        tabindex="-1"
                        :title="$t('Edit')"
                        class="uk-icon-link uk-preserve-width"
                        uk-icon="pencil"
                        uk-tooltip="delay: 500"
                        @click.prevent="edit()"
                    ></a>
                </li>
                <li>
                    <a
                        tabindex="-1"
                        :title="$t('Pick')"
                        class="uk-icon-link uk-preserve-width"
                        uk-icon="album"
                        uk-tooltip="delay: 500"
                        @click.prevent="empty ? add() : select()"
                    ></a>
                </li>
            </ul>
        </div>

        <div
            class="uk-input uk-cursor-default uk-disabled"
            :title="attributes.title"
            :class="[
                attributes.class,
                {
                    'uk-form-danger': authorizationRequired,
                },
            ]"
        >
            <template v-if="selectedAuth && driver">
                <!-- icon -->
                <img
                    v-if="driver.icon"
                    :alt="driver.title"
                    :src="driver.icon"
                    uk-svg
                    width="20"
                    height="20"
                />
                <span v-else uk-icon="lock"></span>

                <!-- name -->
                <span class="uk-text-emphasis uk-margin-small-left uk-text-baseline">{{
                    selectedAuth.name ||
                    selectedAuth.account ||
                    selectedAuth.username ||
                    driver.name
                }}</span>

                <!-- meta -->
                <span class="uk-text-meta uk-margin-small-left uk-text-baseline">{{
                    driver.title
                }}</span>
            </template>
        </div>
    </div>
</template>

<script>
import fields from '@yootheme/fields';
import { AuthDropdown, AuthModal } from '../components';
import { includes, isEmpty } from 'uikit-util';

export default {
    name: 'ConnectedAuthField',

    filters: {
        date(timestamp) {
            const date = new Date(timestamp).toLocaleString();
            return date.split(',')[0];
        },
    },

    extends: fields.components.FieldText,

    inject: {
        AuthsManager: {
            from: 'EssentialsAuths',
        },
    },

    computed: {
        selectedAuth() {
            return this.AuthsManager.auths.find((auth) => auth.id === this.value);
        },

        authorizationRequired() {
            if (this.driver?.type !== 'oauth') {
                return false;
            }

            const auth = this.selectedAuth;
            const scopes = this.field.connections?.[auth?.driver];

            if (!auth) {
                return false;
            }

            return !this.AuthsManager.validateScopes(auth, scopes);
        },

        empty() {
            return this.drivers.length === 1 && isEmpty(this.auths);
        },

        driver() {
            return this.AuthsManager.drivers?.[this.selectedAuth?.driver];
        },

        drivers() {
            return Object.keys(this.field.connections ?? {})
                .map((driver) => this.AuthsManager.drivers?.[driver]?.name)
                .filter(Boolean);
        },

        auths() {
            return this.AuthsManager.auths.filter((auth) => includes(this.drivers, auth.driver));
        },
    },

    mounted() {
        // reset value if selected auth is not valid
        if (!this.selectedAuth) {
            this.value = '';
        }
    },

    methods: {
        isEmpty,

        add(driver) {
            driver = driver || this.drivers[0];

            return this.edit({ driver }).then((auth) => {
                if (auth?.id) {
                    this.value = auth.id;
                }
            });
        },

        edit(auth = this.selectedAuth) {
            const driver = this.AuthsManager.drivers[auth.driver];
            const scopes = this.field.connections[auth.driver];

            return this.$modal(AuthModal, { driver, scopes, values: auth })
                .show()
                .then((auth) => {
                    return auth;
                });
        },

        select() {
            const drop = this.$dropdown({
                functional: true,
                render: (h) =>
                    h(AuthDropdown, {
                        props: {
                            auths: this.auths,
                            drivers: this.AuthsManager.drivers,
                            connections: this.field.connections,
                        },
                        on: {
                            add: (driver) => {
                                drop.hide();
                                this.add(driver).then(() => {
                                    drop.$forceUpdate();
                                });
                            },
                            edit: (auth) => {
                                drop.hide();
                                this.edit(auth).then(() => {
                                    drop.$forceUpdate();
                                });
                            },
                            remove: (auth) => {
                                const driver = this.AuthsManager.drivers?.[auth.driver];
                                const predeleteEndpoint = driver?.endpoints.predelete;

                                this.AuthsManager.remove(auth, predeleteEndpoint);

                                drop.$forceUpdate();
                                if (auth.id === this.value) {
                                    this.value = '';
                                }
                                if (isEmpty(this.auths)) {
                                    drop.hide();
                                }
                            },
                            resolve: (auth) => {
                                drop.hide();
                                this.value = auth.id;
                                drop.$forceUpdate();
                            },
                        },
                    }),
            });

            drop.show(this.$el, { classes: 'yo-dropdown' });
        },
    },
};
</script>
