<script setup lang="ts">
import { computedAsync } from '@vueuse/core';

import { fallbackAvatar, gravatar } from '~/src/helpers.ts';
import type { User } from '~/src/user.ts';

interface AvatarUser extends Pick<User, 'username' | 'emailHash'> {
    email?: User['email'];
    avatar?: string;
    avatarSource?: User['avatarSource'];
}

const props = withDefaults(defineProps<{
    user: AvatarUser;
    src?: string;
    size?: number;
    dsize?: string;
    validate?: boolean;
}>(), {
    size: 128,
    dsize: '6rem',
});

const failedToLoad = ref(false);

const resolvedSrc = computedAsync(async () => {
    return props.src ||
        props.user.avatar ||
        (props.user.avatarSource === 'gravatar' && props.user.email !== undefined
            ? await gravatar(props.user as AvatarUser & Required<Pick<AvatarUser, 'email'>>, props.size)
            : fallbackAvatar(props.user, props.size));
});
</script>

<template>
    <span>
        <img
            :src="resolvedSrc"
            alt=""
            class="rounded-circle"
            :style="`width: ${dsize};height: ${dsize};`"
            @error="failedToLoad = true"
        >
        <small v-if="validate && failedToLoad" class="failed-to-load small text-danger"><T>user.avatar.failed</T></small>
    </span>
</template>

<style lang="scss" scoped>
.failed-to-load {
    max-width: 200px;
    display: inline-block;
}
</style>
