/**
 * PuppetView - Interactive blue spirit avatar (React Native).
 * Port of airi---interactive-ai-puppet Puppet with same actions:
 * idle, wave, nod, shake, jump, think; mouth reflects isTalking.
 * Code isolated so FlowScreen stays unchanged except composition.
 */

import React, { useEffect, useRef } from 'react';
import { View, StyleSheet, Animated, Easing } from 'react-native';
import { PuppetViewProps } from './types';

const PUPPET_SIZE = 160;

export function PuppetView({ action, isTalking }: PuppetViewProps) {
  const floatAnim = useRef(new Animated.Value(0)).current;
  const bounceAnim = useRef(new Animated.Value(0)).current;
  const shakeAnim = useRef(new Animated.Value(0)).current;
  const thinkScale = useRef(new Animated.Value(1)).current;
  const thinkOpacity = useRef(new Animated.Value(1)).current;
  const smileScale = useRef(new Animated.Value(1)).current;

  // Idle: gentle float
  useEffect(() => {
    if (action !== 'idle') return;
    const loop = Animated.loop(
      Animated.sequence([
        Animated.timing(floatAnim, {
          toValue: 1,
          duration: 2000,
          useNativeDriver: true,
          easing: Easing.inOut(Easing.ease),
        }),
        Animated.timing(floatAnim, {
          toValue: 0,
          duration: 2000,
          useNativeDriver: true,
          easing: Easing.inOut(Easing.ease),
        }),
      ])
    );
    loop.start();
    return () => loop.stop();
  }, [action, floatAnim]);

  // Smile: exaggerated smile scale pulse
  useEffect(() => {
    if (action !== 'smile') {
      smileScale.setValue(1);
      return;
    }
    const loop = Animated.loop(
      Animated.sequence([
        Animated.timing(smileScale, {
          toValue: 1.12,
          duration: 400,
          useNativeDriver: true,
          easing: Easing.out(Easing.ease),
        }),
        Animated.timing(smileScale, {
          toValue: 1,
          duration: 400,
          useNativeDriver: true,
          easing: Easing.in(Easing.ease),
        }),
      ]),
      { iterations: 3 }
    );
    loop.start();
    return () => loop.stop();
  }, [action, smileScale]);

  // Wave / Jump: bounce
  useEffect(() => {
    if (action !== 'wave' && action !== 'jump') return;
    const loop = Animated.loop(
      Animated.sequence([
        Animated.timing(bounceAnim, {
          toValue: 1,
          duration: 400,
          useNativeDriver: true,
          easing: Easing.out(Easing.ease),
        }),
        Animated.timing(bounceAnim, {
          toValue: 0,
          duration: 400,
          useNativeDriver: true,
          easing: Easing.in(Easing.ease),
        }),
      ])
    );
    loop.start();
    return () => loop.stop();
  }, [action, bounceAnim]);

  // Shake: wiggle
  useEffect(() => {
    if (action !== 'shake') return;
    const loop = Animated.loop(
      Animated.sequence([
        Animated.timing(shakeAnim, {
          toValue: 1,
          duration: 150,
          useNativeDriver: true,
        }),
        Animated.timing(shakeAnim, {
          toValue: 0,
          duration: 150,
          useNativeDriver: true,
        }),
      ])
    );
    loop.start();
    return () => loop.stop();
  }, [action, shakeAnim]);

  // Think: scale + opacity pulse
  useEffect(() => {
    if (action !== 'think') {
      thinkScale.setValue(1);
      thinkOpacity.setValue(1);
      return;
    }
    const loop = Animated.loop(
      Animated.sequence([
        Animated.parallel([
          Animated.timing(thinkScale, {
            toValue: 0.92,
            duration: 600,
            useNativeDriver: true,
            easing: Easing.inOut(Easing.ease),
          }),
          Animated.timing(thinkOpacity, {
            toValue: 0.85,
            duration: 600,
            useNativeDriver: true,
          }),
        ]),
        Animated.parallel([
          Animated.timing(thinkScale, {
            toValue: 1,
            duration: 600,
            useNativeDriver: true,
            easing: Easing.inOut(Easing.ease),
          }),
          Animated.timing(thinkOpacity, {
            toValue: 1,
            duration: 600,
            useNativeDriver: true,
          }),
        ]),
      ])
    );
    loop.start();
    return () => loop.stop();
  }, [action, thinkScale, thinkOpacity]);

  const floatY = floatAnim.interpolate({
    inputRange: [0, 1],
    outputRange: [0, -8],
  });
  const bounceY = bounceAnim.interpolate({
    inputRange: [0, 1],
    outputRange: [0, -20],
  });
  const shakeRotate = shakeAnim.interpolate({
    inputRange: [0, 1],
    outputRange: ['0deg', '8deg'],
  });

  const isBounce = action === 'wave' || action === 'jump';
  const isShake = action === 'shake';
  const isSmile = action === 'smile';

  const mouthStyle = isTalking
    ? [styles.mouth, styles.mouthOpen]
    : isSmile
      ? [styles.mouth, styles.mouthBigSmile]
      : [styles.mouth, styles.mouthSmile];

  return (
    <Animated.View
      style={[
        styles.container,
        action === 'idle' && {
          transform: [{ translateY: floatY }],
        },
        isBounce && {
          transform: [{ translateY: bounceY }],
        },
        isShake && {
          transform: [{ rotate: shakeRotate }],
        },
        action === 'think' && {
          transform: [{ scale: thinkScale }],
          opacity: thinkOpacity,
        },
        isSmile && {
          transform: [{ scale: smileScale }],
        },
      ]}
    >
      {/* Aura glow */}
      <View style={styles.aura} />
      {/* Body (droplet-like rounded rect) */}
      <View style={styles.body}>
        {/* Gloss */}
        <View style={styles.gloss} />
        {/* Cheeks */}
        <View style={[styles.cheek, styles.cheekLeft]} />
        <View style={[styles.cheek, styles.cheekRight]} />
        {/* Eyes */}
        <View style={styles.eyes}>
          <View style={[styles.eye, styles.eyeLeft]}>
            <View style={styles.eyeSparkle} />
          </View>
          <View style={[styles.eye, styles.eyeRight]}>
            <View style={styles.eyeSparkle} />
          </View>
        </View>
        {/* Mouth - default smile; open when talking; big smile when smile action */}
        <View style={mouthStyle} />
      </View>
    </Animated.View>
  );
}

const BODY_SIZE = PUPPET_SIZE * 0.9;
const EYE_SIZE = 10;
const EYE_OFFSET_X = 18;
const EYE_OFFSET_Y = -8;

const styles = StyleSheet.create({
  container: {
    width: PUPPET_SIZE,
    height: PUPPET_SIZE,
    alignItems: 'center',
    justifyContent: 'center',
  },
  aura: {
    position: 'absolute',
    width: PUPPET_SIZE + 40,
    height: PUPPET_SIZE + 40,
    borderRadius: (PUPPET_SIZE + 40) / 2,
    backgroundColor: 'rgba(14, 165, 233, 0.15)',
  },
  body: {
    width: BODY_SIZE,
    height: BODY_SIZE,
    borderRadius: BODY_SIZE / 2,
    backgroundColor: '#0ea5e9',
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 0,
    overflow: 'hidden',
    shadowColor: '#0c4a6e',
    shadowOffset: { width: 0, height: 8 },
    shadowOpacity: 0.35,
    shadowRadius: 12,
    elevation: 8,
  },
  gloss: {
    position: 'absolute',
    top: BODY_SIZE * 0.12,
    left: BODY_SIZE * 0.2,
    right: BODY_SIZE * 0.2,
    height: 4,
    borderRadius: 2,
    backgroundColor: 'rgba(255,255,255,0.35)',
  },
  cheek: {
    position: 'absolute',
    width: 14,
    height: 14,
    borderRadius: 7,
    backgroundColor: 'rgba(59, 130, 246, 0.35)',
  },
  cheekLeft: {
    left: BODY_SIZE * 0.15,
    top: BODY_SIZE * 0.42,
  },
  cheekRight: {
    right: BODY_SIZE * 0.15,
    top: BODY_SIZE * 0.42,
  },
  eyes: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    top: BODY_SIZE * 0.34,
  },
  eye: {
    width: EYE_SIZE,
    height: EYE_SIZE,
    borderRadius: EYE_SIZE / 2,
    backgroundColor: '#0c4a6e',
    alignItems: 'center',
    justifyContent: 'center',
  },
  eyeLeft: { marginRight: EYE_OFFSET_X },
  eyeRight: { marginLeft: EYE_OFFSET_X },
  eyeSparkle: {
    width: 3,
    height: 3,
    borderRadius: 1.5,
    backgroundColor: '#fff',
    position: 'absolute',
    top: 1,
    left: 2,
  },
  mouth: {
    position: 'absolute',
    top: BODY_SIZE * 0.52,
    backgroundColor: '#0c4a6e',
  },
  mouthSmile: {
    width: 22,
    height: 6,
    borderBottomLeftRadius: 11,
    borderBottomRightRadius: 11,
    borderTopLeftRadius: 0,
    borderTopRightRadius: 0,
  },
  mouthOpen: {
    width: 18,
    height: 6,
    top: BODY_SIZE * 0.51,
    borderRadius: 3,
    backgroundColor: 'rgba(12, 74, 110, 0.9)',
  },
  mouthBigSmile: {
    width: 32,
    height: 10,
    top: BODY_SIZE * 0.51,
    borderBottomLeftRadius: 16,
    borderBottomRightRadius: 16,
    borderTopLeftRadius: 0,
    borderTopRightRadius: 0,
  },
});
