<template>
    <img
        v-if="iconSource"
        :src="iconSource"
        :style="`height: ${size}em; width: ${size}em; display: inline;`"
        alt=""
        class="icon"
        @error="fallBack"
    >
    <span v-else :class="[`fa${iconSet}`, `fa-${icon}`, 'fa-fw', hover ? 'fa-hover' : '']" :style="style"></span>
</template>

<script lang="ts">
import Vue from 'vue';
import type { PropType } from 'vue';

const buildQueue = (v: string | string[]): { value: string, fallbacks: string[] } => {
    let values = Array.isArray(v) ? v : [v];
    values = values.filter((x) => !!x);

    if (!values.length) {
        values = ['spacer'];
    }

    return {
        value: values.shift()!,
        fallbacks: values,
    };
};

export default Vue.extend({
    props: {
        v: { required: true, type: [String, Array] as PropType<string | string[]> },
        set: { default: 'l', type: String as PropType<'l' | 's' | 'b'> },
        size: { default: 1, type: Number },
        inverse: { type: Boolean },
        hover: { type: Boolean },
    },
    data() {
        return buildQueue(this.v);
    },
    computed: {
        valueParts(): string[] {
            return this.value.split(':');
        },
        icon(): string {
            const icon = this.valueParts[this.valueParts.length - 1];
            if (icon === 'neutrum') {
                return 'neuter';
            }
            return icon;
        },
        iconSet(): string {
            return this.valueParts.length > 1 ? this.valueParts[0] : this.set;
        },
        iconSource(): string | null {
            if (this.value.startsWith('https://')) {
                return this.value;
            }
            if (this.value.endsWith('.svg')) {
                return `/img/${this.inverse ? this.value.replace('.svg', '-inverse.svg') : this.value}`;
            }
            if (this.value.endsWith('.png')) {
                return `/img/${this.inverse ? this.value.replace('.png', '-inverse.png') : this.value}`;
            }
            return null;
        },
        style(): string {
            const properties = [];
            if (this.size !== 1) {
                properties.push(`font-size: ${this.size}em`);
            }
            if (this.v === 'neutrum') {
                properties.push('transform: rotate(225deg)');
            }
            return properties.join(';');
        },
    },
    watch: {
        v(v) {
            const { value, fallbacks } = buildQueue(v);

            this.value = value;
            this.fallbacks = fallbacks;
        },
    },
    methods: {
        fallBack() {
            if (!this.fallbacks.length) {
                return;
            }

            this.value = this.fallbacks.shift()!;
        },
    },
});
</script>

<style lang="scss">
.fa-hover:hover {
    font-weight: 900;
}
</style>
