<template>
    <ListInput v-model="v" :prototype="prototype()" :group="group" :readonly="readonly" :maxitems="maxitems">
        <template #default="s">
            <input
                v-model="s.val.username"
                type="text"
                class="form-control"
                :placeholder="`@${$t('user.account.changeUsername.header').toLowerCase()}`"
                required
                @input="validateUser(s.val.username)"
                @keyup="validateUser(s.val.username)"
            >
            <button v-if="s.val.username" :key="updateKey" type="button" :class="['btn', accountStatus(s.val.username).btn]" @click.prevent>
                <Tooltip v-if="accountStatus(s.val.username).text" :text="$t(accountStatus(s.val.username).text)">
                    <Icon :v="accountStatus(s.val.username).icon" />
                </Tooltip>
                <Icon v-else :v="accountStatus(s.val.username).icon" />
            </button>
            <input
                v-model="s.val.relationship"
                type="text"
                class="form-control"
                :placeholder="$t('profile.circles.relationship')"
                required
                maxlength="64"
            >
        </template>
        <template #validation="s">
            <p v-if="validation(s.val)" class="small text-danger">
                <Icon v="exclamation-triangle" />
                <span class="ml-1">{{ $t(validation(s.val)) }}</span>
            </p>
        </template>
    </ListInput>
</template>

<script>
// TODO remove duplication
const normalise = (s) => decodeURIComponent(s.trim().toLowerCase());
const normaliseWithLink = (s) => normalise(s.replace(/^@/, '').replace(new RegExp('^https://.*?/@'), ''));

export default {
    props: {
        modelValue: {},
        group: {},
        readonly: { type: Boolean },
        maxitems: { default: null, type: Number },
    },
    emits: ['update:modelValue'],
    data() {
        const validateUserCache = {};
        for (const connection of this.modelValue) {
            validateUserCache[connection.username] = [connection.locale];
        }

        return {
            v: this.modelValue,
            validateUserHandle: undefined,
            validateUserCache,
            updateKey: 0,
        };
    },
    watch: {
        v() {
            this.$emit('update:modelValue', this.v);
        },
        modelValue(v) {
            this.v = v;
        },
    },
    methods: {
        prototype() {
            return { username: '', relationship: '' };
        },
        validation(v) {
            if (JSON.stringify(v) === JSON.stringify(this.prototype())) {
                return null;
            }

            if (this.accountStatus(v.username).value === false) {
                return 'profile.circles.validation.userNotFound';
            }

            if (!v.relationship) {
                return 'profile.circles.validation.required';
            }

            return null;
        },
        validateUser(v) {
            if (this.validateUserHandle) {
                clearTimeout(this.validateUserHandle);
            }
            if (!v || Object.hasOwn(this.validateUserCache, v)) {
                return;
            }
            this.validateUserHandle = setTimeout(async () => {
                let res = await $fetch(`/api/profile/versions/${encodeURIComponent(normaliseWithLink(v))}`);
                if (!Array.isArray(res)) {
                    console.error(res);
                    res = [];
                }
                this.validateUserCache[v] = res;
                this.updateKey++;
            }, 500);
        },
        accountStatus(v) {
            if (this.validateUserCache[v] === undefined) {
                return {
                    value: undefined,
                    btn: 'btn-secondary text-white border',
                    icon: 'spinner',
                };
            }
            if (this.validateUserCache[v].length) {
                return {
                    value: true,
                    btn: 'btn-outline-success',
                    icon: 'check-circle',
                };
            }
            return {
                value: false,
                btn: 'btn-outline-danger',
                icon: 'times-circle',
                text: 'profile.circles.validation.userNotFound',
            };
        },
    },
};
</script>
