/**
 * Floating Call Bubble Component
 *
 * Shows a floating bubble during active voice calls.
 * Can be dragged around the screen.
 * Tapping it returns to the full voice call screen.
 */

import React, { useEffect, useRef, useState } from 'react';
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  Animated,
  PanResponder,
  Dimensions,
  Platform,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { AppColors, FontSizes, Spacing } from '@/constants/theme';
import { useVoiceCall } from '@/contexts/VoiceCallContext';

const BUBBLE_SIZE = 70;
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');

export function FloatingCallBubble() {
  const { callState, maximizeCall, endCall } = useVoiceCall();
  const insets = useSafeAreaInsets();

  // Animation values
  const pan = useRef(new Animated.ValueXY({
    x: SCREEN_WIDTH - BUBBLE_SIZE - 16,
    y: insets.top + 100,
  })).current;
  const scale = useRef(new Animated.Value(0)).current;
  const pulseAnim = useRef(new Animated.Value(1)).current;

  // Local duration state (updates from context)
  const [displayDuration, setDisplayDuration] = useState(callState.callDuration);

  // Update display duration when context changes
  useEffect(() => {
    setDisplayDuration(callState.callDuration);
  }, [callState.callDuration]);

  // Duration timer (local increment for smooth display)
  useEffect(() => {
    if (callState.isActive && callState.isMinimized) {
      const interval = setInterval(() => {
        setDisplayDuration(prev => prev + 1);
      }, 1000);
      return () => clearInterval(interval);
    }
  }, [callState.isActive, callState.isMinimized]);

  // Show/hide animation
  useEffect(() => {
    if (callState.isActive && callState.isMinimized) {
      // Show bubble
      Animated.spring(scale, {
        toValue: 1,
        friction: 5,
        tension: 40,
        useNativeDriver: true,
      }).start();
    } else {
      // Hide bubble
      Animated.timing(scale, {
        toValue: 0,
        duration: 200,
        useNativeDriver: true,
      }).start();
    }
  }, [callState.isActive, callState.isMinimized, scale]);

  // Pulse animation
  useEffect(() => {
    if (callState.isActive && callState.isMinimized) {
      const pulse = Animated.loop(
        Animated.sequence([
          Animated.timing(pulseAnim, {
            toValue: 1.1,
            duration: 1000,
            useNativeDriver: true,
          }),
          Animated.timing(pulseAnim, {
            toValue: 1,
            duration: 1000,
            useNativeDriver: true,
          }),
        ])
      );
      pulse.start();
      return () => pulse.stop();
    }
  }, [callState.isActive, callState.isMinimized, pulseAnim]);

  // Pan responder for dragging
  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponder: () => true,
      onPanResponderGrant: () => {
        pan.extractOffset();
      },
      onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }], {
        useNativeDriver: false,
      }),
      onPanResponderRelease: (_, gestureState) => {
        pan.flattenOffset();

        // Snap to edge
        const currentX = (pan.x as any)._value;
        const currentY = (pan.y as any)._value;

        const snapToLeft = currentX < SCREEN_WIDTH / 2;
        const targetX = snapToLeft ? 16 : SCREEN_WIDTH - BUBBLE_SIZE - 16;

        // Clamp Y within screen bounds
        const minY = insets.top + 16;
        const maxY = SCREEN_HEIGHT - BUBBLE_SIZE - insets.bottom - 100;
        const targetY = Math.max(minY, Math.min(currentY, maxY));

        Animated.spring(pan, {
          toValue: { x: targetX, y: targetY },
          friction: 7,
          useNativeDriver: false,
        }).start();
      },
    })
  ).current;

  // Format duration as mm:ss
  const formatDuration = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
  };

  // Don't render if not showing
  if (!callState.isActive || !callState.isMinimized) {
    return null;
  }

  return (
    <Animated.View
      style={[
        styles.container,
        {
          transform: [
            { translateX: pan.x },
            { translateY: pan.y },
            { scale },
          ],
        },
      ]}
      {...panResponder.panHandlers}
    >
      {/* Pulse ring */}
      <Animated.View
        style={[
          styles.pulseRing,
          {
            transform: [{ scale: pulseAnim }],
          },
        ]}
      />

      {/* Main bubble */}
      <TouchableOpacity
        style={styles.bubble}
        onPress={maximizeCall}
        activeOpacity={0.9}
      >
        <View style={styles.avatarContainer}>
          <Text style={styles.avatarText}>J</Text>
        </View>
        <View style={styles.durationBadge}>
          <Text style={styles.durationText}>{formatDuration(displayDuration)}</Text>
        </View>
      </TouchableOpacity>

      {/* End call button */}
      <TouchableOpacity style={styles.endButton} onPress={endCall}>
        <Ionicons name="call" size={14} color={AppColors.white} style={{ transform: [{ rotate: '135deg' }] }} />
      </TouchableOpacity>
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    zIndex: 9999,
    width: BUBBLE_SIZE,
    height: BUBBLE_SIZE,
  },
  pulseRing: {
    position: 'absolute',
    width: BUBBLE_SIZE,
    height: BUBBLE_SIZE,
    borderRadius: BUBBLE_SIZE / 2,
    backgroundColor: 'rgba(90, 200, 168, 0.3)',
  },
  bubble: {
    width: BUBBLE_SIZE,
    height: BUBBLE_SIZE,
    borderRadius: BUBBLE_SIZE / 2,
    backgroundColor: AppColors.success,
    justifyContent: 'center',
    alignItems: 'center',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.3,
    shadowRadius: 8,
    elevation: 10,
  },
  avatarContainer: {
    width: 44,
    height: 44,
    borderRadius: 22,
    backgroundColor: 'rgba(255, 255, 255, 0.2)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  avatarText: {
    fontSize: FontSizes.xl,
    fontWeight: '600',
    color: AppColors.white,
  },
  durationBadge: {
    position: 'absolute',
    bottom: -4,
    backgroundColor: 'rgba(0, 0, 0, 0.7)',
    paddingHorizontal: 6,
    paddingVertical: 2,
    borderRadius: 8,
  },
  durationText: {
    fontSize: 10,
    fontWeight: '600',
    color: AppColors.white,
    fontVariant: ['tabular-nums'],
  },
  endButton: {
    position: 'absolute',
    top: -4,
    right: -4,
    width: 24,
    height: 24,
    borderRadius: 12,
    backgroundColor: AppColors.error,
    justifyContent: 'center',
    alignItems: 'center',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 4,
    elevation: 5,
  },
});
