import { jsx, jsxs } from 'react/jsx-runtime';
import { useRef, useState, useCallback, useEffect } from 'react';
import { useReducedMotion } from 'motion/react';
import { cn } from '../../../utils/cn.js';
import { springConfigs } from './InteractiveCharacters.animations.js';
import { useMouseTracking } from './hooks/useMouseTracking.js';
import { useIdleAnimation } from './hooks/useIdleAnimation.js';
import { useBlink } from './hooks/useBlink.js';
import { BlobCharacter } from './characters/BlobCharacter.js';
import { TallCharacter } from './characters/TallCharacter.js';
import { SmallCharacter } from './characters/SmallCharacter.js';

const sizeMap = {
    sm: 'w-[200px]',
    md: 'w-[320px]',
    lg: 'w-[400px]',
};
/** Click reaction states per character */
const CLICK_REACTIONS = {
    blob: 'surprised',
    tall: 'love',
    small: 'excited',
};
/** How long click reactions last (ms) */
const CLICK_DURATION = 1500;
const InteractiveCharacters = ({ state = 'idle', trackMouse = true, size = 'md', className, }) => {
    const svgRef = useRef(null);
    const shouldReduceMotion = useReducedMotion();
    const clickTimeoutRef = useRef(null);
    const [clickedChar, setClickedChar] = useState(null);
    const handleCharacterClick = useCallback((character) => {
        if (clickTimeoutRef.current)
            clearTimeout(clickTimeoutRef.current);
        setClickedChar(character);
        clickTimeoutRef.current = setTimeout(() => setClickedChar(null), CLICK_DURATION);
    }, []);
    // Cleanup timeout on unmount
    useEffect(() => {
        return () => {
            if (clickTimeoutRef.current)
                clearTimeout(clickTimeoutRef.current);
        };
    }, []);
    // Determine effective state per character (click overrides form state)
    const blobState = clickedChar === 'blob' ? CLICK_REACTIONS.blob : state;
    const tallState = clickedChar === 'tall' ? CLICK_REACTIONS.tall : state;
    const smallState = clickedChar === 'small' ? CLICK_REACTIONS.small : state;
    const isTrackingEnabled = trackMouse && state !== 'password' && !shouldReduceMotion;
    const isIdleAnimated = !shouldReduceMotion;
    // Mouse tracking — different spring configs per character
    const blobEye = useMouseTracking({
        containerRef: svgRef,
        enabled: isTrackingEnabled,
        ...springConfigs.blob,
    });
    const tallEye = useMouseTracking({
        containerRef: svgRef,
        enabled: isTrackingEnabled,
        ...springConfigs.tall,
    });
    const smallEye = useMouseTracking({
        containerRef: svgRef,
        enabled: isTrackingEnabled,
        ...springConfigs.small,
    });
    // Idle sway/breathing/head — each character at different rates & phase offsets
    const blobIdle = useIdleAnimation({
        enabled: isIdleAnimated,
        swayAmount: 1.5,
        swaySpeed: 0.8,
        breathAmount: 0.008,
        headTiltAmount: 3,
        headNudgeAmount: 1.5,
        phaseOffset: 0,
    });
    const tallIdle = useIdleAnimation({
        enabled: isIdleAnimated,
        swayAmount: 1,
        swaySpeed: 0.6,
        breathAmount: 0.006,
        headTiltAmount: 2,
        headNudgeAmount: 1,
        phaseOffset: 2.5,
    });
    const smallIdle = useIdleAnimation({
        enabled: isIdleAnimated,
        swayAmount: 2.5,
        swaySpeed: 1.2,
        breathAmount: 0.012,
        headTiltAmount: 4,
        headNudgeAmount: 2,
        phaseOffset: 5,
    });
    // Blink — disable during password/peek and click reactions
    const canBlinkBlob = blobState === 'idle' || blobState === 'email';
    const canBlinkTall = tallState === 'idle' || tallState === 'email';
    const canBlinkSmall = smallState === 'idle' || smallState === 'email';
    const blobBlink = useBlink({ enabled: canBlinkBlob, minInterval: 2500, maxInterval: 5000 });
    const tallBlink = useBlink({ enabled: canBlinkTall, minInterval: 3000, maxInterval: 6000 });
    const smallBlink = useBlink({ enabled: canBlinkSmall, minInterval: 1800, maxInterval: 4000 });
    return (jsx("div", { className: cn(sizeMap[size], className), "data-state": state, children: jsxs("svg", { ref: svgRef, viewBox: "0 0 400 180", xmlns: "http://www.w3.org/2000/svg", className: "w-full h-auto", role: "img", "aria-label": "Interactive characters that react to form input", children: [jsx("g", { transform: "translate(200, 170)", className: "cursor-pointer", children: jsx(TallCharacter, { state: tallState, eyeOffset: { x: tallEye.x, y: tallEye.y }, idle: tallIdle, blinkAmount: tallBlink, onClick: () => handleCharacterClick('tall') }) }), jsx("g", { transform: "translate(100, 170)", className: "cursor-pointer", children: jsx(BlobCharacter, { state: blobState, eyeOffset: { x: blobEye.x, y: blobEye.y }, idle: blobIdle, blinkAmount: blobBlink, onClick: () => handleCharacterClick('blob') }) }), jsx("g", { transform: "translate(310, 170)", className: "cursor-pointer", children: jsx(SmallCharacter, { state: smallState, eyeOffset: { x: smallEye.x, y: smallEye.y }, idle: smallIdle, blinkAmount: smallBlink, onClick: () => handleCharacterClick('small') }) })] }) }));
};

export { InteractiveCharacters };
