<template>
  <v-avatar 
    :size="avatarSize" 
    :color="showInitials ? backgroundColor : 'grey-lighten-2'"
    :class="avatarClass"
  >
    <!-- Loading state -->
    <v-progress-circular 
      v-if="loading" 
      :size="iconSize" 
      indeterminate 
      color="white" 
    />
    
    <!-- Profile image -->
    <v-img 
      v-else-if="imageUrl && !imageError && !loading" 
      :src="imageUrl" 
      :alt="altText"
      cover
      @error="handleImageError"
      @load="handleImageLoad"
      :class="imageClass"
    />
    
    <!-- Initials fallback -->
    <span 
      v-else-if="initials && !loading" 
      :class="['text-white font-weight-bold', initialsClass]"
      :style="{ fontSize: initialsSize }"
    >
      {{ initials }}
    </span>
    
    <!-- Icon fallback -->
    <v-icon 
      v-else
      :size="iconSize" 
      color="grey-darken-2"
    >
      mdi-account
    </v-icon>
  </v-avatar>
</template>

<script setup lang="ts">
import { generateInitials, generateAvatarColor } from '~/utils/client-utils';

interface Props {
  memberId?: string;
  memberName?: string;
  firstName?: string;
  lastName?: string;
  size?: 'small' | 'medium' | 'large';
  lazy?: boolean;
  clickable?: boolean;
  showBorder?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  size: 'medium',
  lazy: true,
  clickable: false,
  showBorder: false
});

const emit = defineEmits<{
  click: [];
  imageLoaded: [];
  imageError: [error: string];
}>();

// Reactive state
const loading = ref(false);
const imageError = ref(false);
const imageUrl = ref<string | null>(null);
const isVisible = ref(false);

// Computed properties
const avatarSize = computed(() => {
  switch (props.size) {
    case 'small': return 36;
    case 'medium': return 80;
    case 'large': return 200;
    default: return 80;
  }
});

const iconSize = computed(() => {
  switch (props.size) {
    case 'small': return 20;
    case 'medium': return 40;
    case 'large': return 100;
    default: return 40;
  }
});

const initialsSize = computed(() => {
  switch (props.size) {
    case 'small': return '14px';
    case 'medium': return '28px';
    case 'large': return '72px';
    default: return '28px';
  }
});

const initials = computed(() => {
  if (props.firstName && props.lastName) {
    return generateInitials(props.firstName, props.lastName);
  }
  if (props.memberName) {
    return generateInitials(undefined, undefined, props.memberName);
  }
  return '?';
});

const backgroundColor = computed(() => {
  const name = props.memberName || `${props.firstName} ${props.lastName}`.trim();
  return name ? generateAvatarColor(name) : '#9e9e9e';
});

const showInitials = computed(() => {
  return !loading.value && !imageUrl.value && initials.value !== '?';
});

const altText = computed(() => {
  return props.memberName || `${props.firstName} ${props.lastName}`.trim() || 'Profile';
});

const avatarClass = computed(() => [
  {
    'cursor-pointer': props.clickable,
    'elevation-2': props.showBorder,
    'profile-avatar--border': props.showBorder
  }
]);

const imageClass = computed(() => [
  'profile-avatar__image',
  {
    'profile-avatar__image--loaded': !loading.value
  }
]);

const initialsClass = computed(() => [
  'profile-avatar__initials',
  {
    'text-h6': props.size === 'small',
    'text-h4': props.size === 'medium',
    'text-h1': props.size === 'large'
  }
]);

// Methods
const loadProfileImage = async () => {
  if (!props.memberId || loading.value) {
    return;
  }

  try {
    loading.value = true;
    imageError.value = false;

    const sizeParam = props.size === 'small' ? 'small' : 
                     props.size === 'large' ? 'medium' : 'medium'; // Use medium for both medium and large

    const response = await $fetch(`/api/profile/image/${props.memberId}/${sizeParam}`);
    
    if (response.success && response.imageUrl) {
      // Pre-load the image to ensure it's valid
      const img = new Image();
      img.onload = () => {
        imageUrl.value = response.imageUrl;
        loading.value = false;
        emit('imageLoaded');
      };
      img.onerror = () => {
        handleImageError();
      };
      img.src = response.imageUrl;
    } else {
      loading.value = false;
    }
  } catch (error: any) {
    console.warn(`Profile image not found for member ${props.memberId}:`, error.message);
    loading.value = false;
    imageError.value = true;
  }
};

const handleImageError = () => {
  loading.value = false;
  imageError.value = true;
  imageUrl.value = null;
  emit('imageError', 'Failed to load profile image');
};

const handleImageLoad = () => {
  loading.value = false;
  emit('imageLoaded');
};

const handleClick = () => {
  if (props.clickable) {
    emit('click');
  }
};

// Intersection Observer for lazy loading
let observer: IntersectionObserver | null = null;
const avatarRef = ref<HTMLElement>();

const initIntersectionObserver = () => {
  if (!props.lazy || !avatarRef.value || typeof IntersectionObserver === 'undefined') {
    // Load immediately if not lazy or no intersection observer support
    isVisible.value = true;
    loadProfileImage();
    return;
  }

  observer = new IntersectionObserver(
    (entries) => {
      const entry = entries[0];
      if (entry.isIntersecting && !isVisible.value) {
        isVisible.value = true;
        loadProfileImage();
        
        // Stop observing once visible
        if (observer && avatarRef.value) {
          observer.unobserve(avatarRef.value);
        }
      }
    },
    {
      rootMargin: '50px',
      threshold: 0.1
    }
  );

  observer.observe(avatarRef.value);
};

// Watch for prop changes
watch(
  () => props.memberId,
  (newMemberId) => {
    if (newMemberId) {
      imageUrl.value = null;
      imageError.value = false;
      if (isVisible.value || !props.lazy) {
        loadProfileImage();
      }
    } else {
      imageUrl.value = null;
      imageError.value = false;
      loading.value = false;
    }
  }
);

// Lifecycle
onMounted(() => {
  if (props.memberId) {
    if (props.lazy) {
      nextTick(() => {
        initIntersectionObserver();
      });
    } else {
      loadProfileImage();
    }
  }
});

onUnmounted(() => {
  if (observer && avatarRef.value) {
    observer.unobserve(avatarRef.value);
    observer = null;
  }
});
</script>

<style scoped>
.profile-avatar--border {
  border: 2px solid rgba(255, 255, 255, 0.8);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.profile-avatar__image {
  transition: opacity 0.3s ease-in-out;
  opacity: 0;
}

.profile-avatar__image--loaded {
  opacity: 1;
}

.profile-avatar__initials {
  user-select: none;
  letter-spacing: -0.5px;
}

.cursor-pointer {
  cursor: pointer;
}

.cursor-pointer:hover {
  transform: scale(1.05);
  transition: transform 0.2s ease-in-out;
}
</style>
