import React, { useEffect, useRef, useState } from "react";
import { Animated, Easing, Platform, StyleSheet, View } from "react-native";
import Svg, { Circle, Ellipse, Path } from "react-native-svg";

import type { TimmyMood } from "@/context/TimmyContext";

type FaceTarget = {
  eyeScaleY: number;
  pupilScale: number;
  smileAmount: number;
};

const FACE_TARGETS: Record<TimmyMood, FaceTarget> = {
  idle:     { eyeScaleY: 0.44, pupilScale: 0.90, smileAmount: 0.08 },
  thinking: { eyeScaleY: 0.30, pupilScale: 0.72, smileAmount: 0.00 },
  working:  { eyeScaleY: 0.75, pupilScale: 1.05, smileAmount: 0.18 },
  speaking: { eyeScaleY: 0.92, pupilScale: 1.25, smileAmount: 0.38 },
};

const BASE_PUPIL_R = 2.8;
const BASE_EYE_RY = 5;
const SVG_VIEW = 100;
const SVG_CX = SVG_VIEW / 2;
const SVG_CY = SVG_VIEW / 2;
const HEAD_R = 36;
const EYE_L_X = SVG_CX - 11;
const EYE_R_X = SVG_CX + 11;
const EYE_CY = SVG_CY - 4;
const EYE_RX = 5;
const HAT_BRIM_Y = SVG_CY - HEAD_R - 2;

function buildMouthPath(smileAmount: number): string {
  const s = Math.max(-1, Math.min(1, smileAmount));
  const mouthY = SVG_CY + 18;
  const halfW = 18;
  const ctrlDy = -s * 8;
  const x1 = SVG_CX - halfW;
  const x2 = SVG_CX + halfW;
  return `M ${x1} ${mouthY} Q ${SVG_CX} ${mouthY + ctrlDy} ${x2} ${mouthY}`;
}

type Props = {
  mood: TimmyMood;
  size?: number;
};

export function TimmyFace({ mood, size = 220 }: Props) {
  const eyeScaleYAnim = useRef(new Animated.Value(FACE_TARGETS.idle.eyeScaleY)).current;
  const pupilScaleAnim = useRef(new Animated.Value(FACE_TARGETS.idle.pupilScale)).current;
  const smileAnim = useRef(new Animated.Value(FACE_TARGETS.idle.smileAmount)).current;
  const mouthOscAnim = useRef(new Animated.Value(0)).current;
  const bobAnim = useRef(new Animated.Value(0)).current;

  const speakingLoopRef = useRef<Animated.CompositeAnimation | null>(null);
  const bobLoopRef = useRef<Animated.CompositeAnimation | null>(null);

  useEffect(() => {
    const target = FACE_TARGETS[mood];

    Animated.parallel([
      Animated.spring(eyeScaleYAnim, { toValue: target.eyeScaleY, friction: 6, tension: 80, useNativeDriver: false }),
      Animated.spring(pupilScaleAnim, { toValue: target.pupilScale, friction: 6, tension: 80, useNativeDriver: false }),
      Animated.spring(smileAnim, { toValue: target.smileAmount, friction: 6, tension: 80, useNativeDriver: false }),
    ]).start();

    if (mood === "speaking") {
      speakingLoopRef.current?.stop();
      const osc = Animated.loop(
        Animated.sequence([
          Animated.timing(mouthOscAnim, { toValue: 0.3, duration: 250, easing: Easing.inOut(Easing.sin), useNativeDriver: false }),
          Animated.timing(mouthOscAnim, { toValue: -0.1, duration: 250, easing: Easing.inOut(Easing.sin), useNativeDriver: false }),
        ])
      );
      speakingLoopRef.current = osc;
      osc.start();
    } else {
      speakingLoopRef.current?.stop();
      speakingLoopRef.current = null;
      Animated.spring(mouthOscAnim, { toValue: 0, friction: 8, tension: 60, useNativeDriver: false }).start();
    }

    bobLoopRef.current?.stop();
    const speed = mood === "working" ? 400 : mood === "thinking" ? 700 : 1200;
    const amount = mood === "idle" ? 3 : 6;
    const bob = Animated.loop(
      Animated.sequence([
        Animated.timing(bobAnim, { toValue: amount, duration: speed, easing: Easing.inOut(Easing.sin), useNativeDriver: true }),
        Animated.timing(bobAnim, { toValue: -amount, duration: speed, easing: Easing.inOut(Easing.sin), useNativeDriver: true }),
      ])
    );
    bobLoopRef.current = bob;
    bob.start();

    return () => {
      speakingLoopRef.current?.stop();
      bobLoopRef.current?.stop();
    };
  }, [mood]);

  return (
    <Animated.View
      style={[styles.container, { width: size, height: size, transform: [{ translateY: bobAnim }] }]}
    >
      <StaticFaceLayer size={size} mood={mood} />
      <AnimatedMouth smileAnim={smileAnim} mouthOscAnim={mouthOscAnim} size={size} />
      <AnimatedEyelids eyeScaleYAnim={eyeScaleYAnim} size={size} />
      <AnimatedPupils pupilScaleAnim={pupilScaleAnim} size={size} />
    </Animated.View>
  );
}

function StaticFaceLayer({ size, mood }: { size: number; mood: TimmyMood }) {
  const glowColors: Record<TimmyMood, string> = {
    idle: "#6B7280",
    thinking: "#3B82F6",
    working: "#F59E0B",
    speaking: "#7C3AED",
  };
  const glowColor = glowColors[mood];

  return (
    <Svg width={size} height={size} viewBox={`0 0 ${SVG_VIEW} ${SVG_VIEW}`}>
      {/* Hat brim */}
      <Ellipse cx={SVG_CX} cy={HAT_BRIM_Y} rx={28} ry={4} fill="#3a0880" stroke="#7C3AED" strokeWidth={0.5} />
      {/* Hat cone */}
      <Path d={`M ${SVG_CX - 18} ${HAT_BRIM_Y} L ${SVG_CX} ${HAT_BRIM_Y - 22} L ${SVG_CX + 18} ${HAT_BRIM_Y} Z`} fill="#3a0880" stroke="#7C3AED" strokeWidth={0.5} />
      {/* Hat band */}
      <Ellipse cx={SVG_CX} cy={HAT_BRIM_Y - 1} rx={18} ry={2.5} fill="#FFD700" opacity={0.9} />
      {/* Star */}
      <Circle cx={SVG_CX} cy={HAT_BRIM_Y - 22} r={2.5} fill="#FFD700" />
      {/* Head */}
      <Circle cx={SVG_CX} cy={SVG_CY} r={HEAD_R} fill="#d8a878" stroke="#c89060" strokeWidth={0.5} />
      {/* Robe */}
      <Path d={`M ${SVG_CX - 18} ${SVG_CY + HEAD_R} Q ${SVG_CX - 28} ${SVG_CY + HEAD_R + 30} ${SVG_CX - 22} ${SVG_CY + HEAD_R + 50} L ${SVG_CX + 22} ${SVG_CY + HEAD_R + 50} Q ${SVG_CX + 28} ${SVG_CY + HEAD_R + 30} ${SVG_CX + 18} ${SVG_CY + HEAD_R} Z`} fill="#5c14b0" stroke="#7C3AED" strokeWidth={0.5} />
      {/* Belt */}
      <Ellipse cx={SVG_CX} cy={SVG_CY + HEAD_R + 28} rx={19} ry={3} fill="#FFD700" opacity={0.9} />
      {/* Beard */}
      <Ellipse cx={SVG_CX} cy={SVG_CY + HEAD_R - 4} rx={13} ry={7} fill="#aaa8a0" opacity={0.9} />
      <Path d={`M ${SVG_CX - 10} ${SVG_CY + HEAD_R} Q ${SVG_CX} ${SVG_CY + HEAD_R + 18} ${SVG_CX} ${SVG_CY + HEAD_R + 22} Q ${SVG_CX} ${SVG_CY + HEAD_R + 18} ${SVG_CX + 10} ${SVG_CY + HEAD_R} Z`} fill="#aaa8a0" opacity={0.85} />
      {/* Side hair */}
      <Circle cx={SVG_CX - 32} cy={SVG_CY - 4} r={8} fill="#c8c4bc" opacity={0.8} />
      <Circle cx={SVG_CX + 32} cy={SVG_CY - 4} r={8} fill="#c8c4bc" opacity={0.8} />
      {/* Eye whites */}
      <Ellipse cx={EYE_L_X} cy={EYE_CY} rx={EYE_RX} ry={BASE_EYE_RY} fill="#f5f2e8" />
      <Ellipse cx={EYE_R_X} cy={EYE_CY} rx={EYE_RX} ry={BASE_EYE_RY} fill="#f5f2e8" />
      {/* Magic orb */}
      <Circle cx={SVG_CX + HEAD_R - 2} cy={SVG_CY + 5} r={5} fill="#ff8800" opacity={0.9} />
      <Circle cx={SVG_CX + HEAD_R - 2} cy={SVG_CY + 5} r={3} fill="#ffcc00" opacity={0.8} />
    </Svg>
  );
}

function AnimatedMouth({
  smileAnim,
  mouthOscAnim,
  size,
}: {
  smileAnim: Animated.Value;
  mouthOscAnim: Animated.Value;
  size: number;
}) {
  const [path, setPath] = useState(buildMouthPath(FACE_TARGETS.idle.smileAmount));

  useEffect(() => {
    const combined = Animated.add(smileAnim, mouthOscAnim);
    const id = combined.addListener(({ value }) => {
      setPath(buildMouthPath(value));
    });
    return () => combined.removeListener(id);
  }, [smileAnim, mouthOscAnim]);

  return (
    <View style={[StyleSheet.absoluteFill, { pointerEvents: "none" }]}>
      <Svg width={size} height={size} viewBox={`0 0 ${SVG_VIEW} ${SVG_VIEW}`}>
        <Path d={path} stroke="#8a4a28" strokeWidth={2.5} fill="none" strokeLinecap="round" />
      </Svg>
    </View>
  );
}

function AnimatedEyelids({
  eyeScaleYAnim,
  size,
}: {
  eyeScaleYAnim: Animated.Value;
  size: number;
}) {
  const [lidRy, setLidRy] = useState(BASE_EYE_RY * (1 - FACE_TARGETS.idle.eyeScaleY));
  const [lidCyOffset, setLidCyOffset] = useState(0);

  useEffect(() => {
    const id = eyeScaleYAnim.addListener(({ value }) => {
      const newLidRy = BASE_EYE_RY * (1 - value);
      setLidRy(newLidRy);
      setLidCyOffset(-(BASE_EYE_RY - newLidRy));
    });
    return () => eyeScaleYAnim.removeListener(id);
  }, [eyeScaleYAnim]);

  return (
    <View style={[StyleSheet.absoluteFill, { pointerEvents: "none" }]}>
      <Svg width={size} height={size} viewBox={`0 0 ${SVG_VIEW} ${SVG_VIEW}`}>
        <Ellipse cx={EYE_L_X} cy={EYE_CY + lidCyOffset} rx={EYE_RX + 0.5} ry={lidRy + 0.5} fill="#d8a878" />
        <Ellipse cx={EYE_R_X} cy={EYE_CY + lidCyOffset} rx={EYE_RX + 0.5} ry={lidRy + 0.5} fill="#d8a878" />
      </Svg>
    </View>
  );
}

function AnimatedPupils({
  pupilScaleAnim,
  size,
}: {
  pupilScaleAnim: Animated.Value;
  size: number;
}) {
  const [pupilR, setPupilR] = useState(BASE_PUPIL_R * FACE_TARGETS.idle.pupilScale);

  useEffect(() => {
    const id = pupilScaleAnim.addListener(({ value }) => {
      setPupilR(BASE_PUPIL_R * value);
    });
    return () => pupilScaleAnim.removeListener(id);
  }, [pupilScaleAnim]);

  return (
    <View style={[StyleSheet.absoluteFill, { pointerEvents: "none" }]}>
      <Svg width={size} height={size} viewBox={`0 0 ${SVG_VIEW} ${SVG_VIEW}`}>
        {/* Pupils */}
        <Circle cx={EYE_L_X} cy={EYE_CY + 1} r={pupilR} fill="#07070f" />
        <Circle cx={EYE_R_X} cy={EYE_CY + 1} r={pupilR} fill="#07070f" />
        {/* Highlights */}
        <Circle cx={EYE_L_X + 1.5} cy={EYE_CY - 0.5} r={0.8} fill="#ffffff" opacity={0.85} />
        <Circle cx={EYE_R_X + 1.5} cy={EYE_CY - 0.5} r={0.8} fill="#ffffff" opacity={0.85} />
      </Svg>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    alignItems: "center",
    justifyContent: "center",
    position: "relative",
  },
});
