/** Avatar with optional VIP frame ring, online dot and speaking glow. */
import React, {useEffect, useRef} from 'react';
import {Animated, Image, StyleSheet, Text, View} from 'react-native';
import {COLORS} from '../theme/colors';
import {RADIUS, SHADOW} from '../theme/spacing';
import {initials} from '../utils/formatters';

interface Props {
  uri?: string | null;
  name: string;
  size?: number;
  frameUrl?: string | null;
  vip?: string | null; // vip_badge
  online?: boolean;
  speaking?: boolean;
  glowColor?: string;
  style?: object;
}

export function Avatar({
  uri,
  name,
  size = 48,
  frameUrl,
  vip,
  online,
  speaking,
  glowColor = COLORS.pink,
  style,
}: Props): React.JSX.Element {
  const glow = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    if (speaking) {
      Animated.loop(
        Animated.sequence([
          Animated.timing(glow, {toValue: 1, duration: 420, useNativeDriver: true}),
          Animated.timing(glow, {toValue: 0.35, duration: 420, useNativeDriver: true}),
        ]),
      ).start();
    } else {
      glow.stopAnimation();
      glow.setValue(0);
    }
  }, [speaking, glow]);

  const framePad = frameUrl ? 3 : 0;

  return (
    <View style={[{width: size + framePad * 2, height: size + framePad * 2}, style]}>
      {speaking && (
        <Animated.View
          pointerEvents="none"
          style={[
            styles.speakingGlow,
            {
              borderRadius: size,
              shadowColor: glowColor,
              opacity: glow,
              shadowOpacity: glow.interpolate({inputRange: [0, 1], outputRange: [0.3, 0.95]}),
            },
          ]}
        />
      )}
      <View
        style={[
          styles.frame,
          frameUrl ? styles.frameRing : null,
          {borderRadius: size},
        ]}>
        {uri ? (
          <Image source={{uri}} style={{width: size, height: size, borderRadius: size}} />
        ) : (
          <View
            style={[
              styles.placeholder,
              {width: size, height: size, borderRadius: size},
            ]}>
            <Text style={[styles.initials, {fontSize: Math.max(10, size * 0.34)}]}>
              {initials(name)}
            </Text>
          </View>
        )}
      </View>
      {vip ? (
        <View style={[styles.vip, {top: -4, right: -4}]}>
          <Text style={styles.vipText}>{vip}</Text>
        </View>
      ) : null}
      {online ? <View style={[styles.dot, {width: size * 0.24, height: size * 0.24}]} /> : null}
    </View>
  );
}

const styles = StyleSheet.create({
  frame: {
    borderWidth: 0,
    overflow: 'visible',
  },
  frameRing: {
    borderWidth: 2,
    borderColor: COLORS.gold,
    padding: 1,
  },
  placeholder: {
    backgroundColor: COLORS.cardBgLight,
    alignItems: 'center',
    justifyContent: 'center',
  },
  initials: {color: COLORS.purple, fontWeight: '800'},
  dot: {
    position: 'absolute',
    bottom: 0,
    right: 0,
    borderRadius: 99,
    backgroundColor: COLORS.success,
    borderWidth: 2,
    borderColor: COLORS.darkBg,
  },
  vip: {
    position: 'absolute',
    backgroundColor: COLORS.goldDeep,
    borderRadius: 8,
    paddingHorizontal: 4,
    paddingVertical: 1,
  },
  vipText: {color: COLORS.white, fontSize: 8, fontWeight: '800'},
  speakingGlow: {
    ...SHADOW.glowSpeaking,
    position: 'absolute',
    top: -4,
    left: -4,
    right: -4,
    bottom: -4,
  },
});
