import { useState, useEffect, useRef } from 'react';

interface PupilProps {
    size?: number;
    maxDistance?: number;
    pupilColor?: string;
    forceLookX?: number;
    forceLookY?: number;
}

const Pupil = ({
    size = 12, maxDistance = 5, pupilColor = 'black',
    forceLookX, forceLookY,
}: PupilProps) => {
    const [mouseX, setMouseX] = useState(0);
    const [mouseY, setMouseY] = useState(0);
    const ref = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const h = (e: MouseEvent) => { setMouseX(e.clientX); setMouseY(e.clientY); };
        window.addEventListener('mousemove', h);
        return () => window.removeEventListener('mousemove', h);
    }, []);

    const calc = () => {
        if (!ref.current) return { x: 0, y: 0 };
        if (forceLookX !== undefined && forceLookY !== undefined) return { x: forceLookX, y: forceLookY };
        const r = ref.current.getBoundingClientRect();
        const cx = r.left + r.width / 2, cy = r.top + r.height / 2;
        const dx = mouseX - cx, dy = mouseY - cy;
        const dist = Math.min(Math.sqrt(dx * dx + dy * dy), maxDistance);
        const a = Math.atan2(dy, dx);
        return { x: Math.cos(a) * dist, y: Math.sin(a) * dist };
    };
    const p = calc();
    return (
        <div ref={ref} className="rounded-full" style={{
            width: size, height: size, backgroundColor: pupilColor,
            transform: `translate(${p.x}px, ${p.y}px)`, transition: 'transform 0.1s ease-out',
        }} />
    );
};

interface EyeBallProps {
    size?: number; pupilSize?: number; maxDistance?: number;
    eyeColor?: string; pupilColor?: string; isBlinking?: boolean;
    forceLookX?: number; forceLookY?: number;
}

const EyeBall = ({
    size = 48, pupilSize = 16, maxDistance = 10,
    eyeColor = 'white', pupilColor = 'black', isBlinking = false,
    forceLookX, forceLookY,
}: EyeBallProps) => {
    const [mouseX, setMouseX] = useState(0);
    const [mouseY, setMouseY] = useState(0);
    const ref = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const h = (e: MouseEvent) => { setMouseX(e.clientX); setMouseY(e.clientY); };
        window.addEventListener('mousemove', h);
        return () => window.removeEventListener('mousemove', h);
    }, []);

    const calc = () => {
        if (!ref.current) return { x: 0, y: 0 };
        if (forceLookX !== undefined && forceLookY !== undefined) return { x: forceLookX, y: forceLookY };
        const r = ref.current.getBoundingClientRect();
        const cx = r.left + r.width / 2, cy = r.top + r.height / 2;
        const dx = mouseX - cx, dy = mouseY - cy;
        const dist = Math.min(Math.sqrt(dx * dx + dy * dy), maxDistance);
        const a = Math.atan2(dy, dx);
        return { x: Math.cos(a) * dist, y: Math.sin(a) * dist };
    };
    const p = calc();
    return (
        <div ref={ref} className="rounded-full flex items-center justify-center transition-all duration-150"
            style={{ width: size, height: isBlinking ? 2 : size, backgroundColor: eyeColor, overflow: 'hidden' }}>
            {!isBlinking && (
                <div className="rounded-full" style={{
                    width: pupilSize, height: pupilSize, backgroundColor: pupilColor,
                    transform: `translate(${p.x}px, ${p.y}px)`, transition: 'transform 0.1s ease-out',
                }} />
            )}
        </div>
    );
};

interface Props { isTyping?: boolean; showPassword?: boolean; passwordLength?: number; }

export default function LoginCharacters({ isTyping = false, showPassword = false, passwordLength = 0 }: Props) {
    const [mouseX, setMouseX] = useState(0);
    const [mouseY, setMouseY] = useState(0);
    const [isPrimaryBlink, setIsPrimaryBlink] = useState(false);
    const [isDarkBlink, setIsDarkBlink] = useState(false);
    const [isLooking, setIsLooking] = useState(false);
    const [isPrimaryPeek, setIsPrimaryPeek] = useState(false);
    const primaryRef = useRef<HTMLDivElement>(null);
    const darkRef = useRef<HTMLDivElement>(null);
    const yellowRef = useRef<HTMLDivElement>(null);
    const orangeRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const h = (e: MouseEvent) => { setMouseX(e.clientX); setMouseY(e.clientY); };
        window.addEventListener('mousemove', h);
        return () => window.removeEventListener('mousemove', h);
    }, []);

    useEffect(() => {
        const schedule = (): ReturnType<typeof setTimeout> => setTimeout(() => {
            setIsPrimaryBlink(true);
            setTimeout(() => { setIsPrimaryBlink(false); schedule(); }, 150);
        }, Math.random() * 4000 + 3000);
        const t = schedule(); return () => clearTimeout(t);
    }, []);

    useEffect(() => {
        const schedule = (): ReturnType<typeof setTimeout> => setTimeout(() => {
            setIsDarkBlink(true);
            setTimeout(() => { setIsDarkBlink(false); schedule(); }, 150);
        }, Math.random() * 4000 + 3000);
        const t = schedule(); return () => clearTimeout(t);
    }, []);

    useEffect(() => {
        if (isTyping) { setIsLooking(true); const t = setTimeout(() => setIsLooking(false), 800); return () => clearTimeout(t); }
        else setIsLooking(false);
    }, [isTyping]);

    useEffect(() => {
        if (passwordLength > 0 && showPassword) {
            const t = setTimeout(() => {
                setIsPrimaryPeek(true);
                setTimeout(() => setIsPrimaryPeek(false), 800);
            }, Math.random() * 3000 + 2000);
            return () => clearTimeout(t);
        } else setIsPrimaryPeek(false);
    }, [passwordLength, showPassword, isPrimaryPeek]);

    const calcPos = (ref: React.RefObject<HTMLDivElement | null>) => {
        if (!ref.current) return { faceX: 0, faceY: 0, bodySkew: 0 };
        const r = ref.current.getBoundingClientRect();
        const cx = r.left + r.width / 2, cy = r.top + r.height / 3;
        const dx = mouseX - cx, dy = mouseY - cy;
        return {
            faceX: Math.max(-15, Math.min(15, dx / 20)),
            faceY: Math.max(-10, Math.min(10, dy / 30)),
            bodySkew: Math.max(-6, Math.min(6, -dx / 120)),
        };
    };

    const pp = calcPos(primaryRef), bp = calcPos(darkRef);
    const yp = calcPos(yellowRef), op = calcPos(orangeRef);
    const hiding = passwordLength > 0 && !showPassword;
    const showing = passwordLength > 0 && showPassword;

    return (
        <div className="relative w-full" style={{ height: 300 }}>
            {/* Primary tall - back */}
            <div ref={primaryRef} className="absolute bottom-0 transition-all duration-700 ease-in-out" style={{
                left: '12%', width: '33%', height: (isTyping || hiding) ? '110%' : '100%',
                backgroundColor: '#10b981', borderRadius: '10px 10px 0 0', zIndex: 1,
                transform: showing ? 'skewX(0deg)' : (isTyping || hiding)
                    ? `skewX(${(pp.bodySkew || 0) - 12}deg) translateX(40px)` : `skewX(${pp.bodySkew || 0}deg)`,
                transformOrigin: 'bottom center',
            }}>
                <div className="absolute flex gap-8 transition-all duration-700 ease-in-out" style={{
                    left: showing ? 20 : isLooking ? 55 : 45 + pp.faceX,
                    top: showing ? 35 : isLooking ? 65 : 40 + pp.faceY,
                }}>
                    <EyeBall size={18} pupilSize={7} maxDistance={5} eyeColor="white" pupilColor="#064e3b"
                        isBlinking={isPrimaryBlink}
                        forceLookX={showing ? (isPrimaryPeek ? 4 : -4) : isLooking ? 3 : undefined}
                        forceLookY={showing ? (isPrimaryPeek ? 5 : -4) : isLooking ? 4 : undefined} />
                    <EyeBall size={18} pupilSize={7} maxDistance={5} eyeColor="white" pupilColor="#064e3b"
                        isBlinking={isPrimaryBlink}
                        forceLookX={showing ? (isPrimaryPeek ? 4 : -4) : isLooking ? 3 : undefined}
                        forceLookY={showing ? (isPrimaryPeek ? 5 : -4) : isLooking ? 4 : undefined} />
                </div>
            </div>

            {/* Dark - middle */}
            <div ref={darkRef} className="absolute bottom-0 transition-all duration-700 ease-in-out" style={{
                left: '44%', width: '22%', height: '77%',
                backgroundColor: '#0f766e', borderRadius: '8px 8px 0 0', zIndex: 2,
                transform: showing ? 'skewX(0deg)' : isLooking
                    ? `skewX(${(bp.bodySkew || 0) * 1.5 + 10}deg) translateX(20px)`
                    : (isTyping || hiding) ? `skewX(${(bp.bodySkew || 0) * 1.5}deg)` : `skewX(${bp.bodySkew || 0}deg)`,
                transformOrigin: 'bottom center',
            }}>
                <div className="absolute flex gap-6 transition-all duration-700 ease-in-out" style={{
                    left: showing ? 10 : isLooking ? 32 : 26 + bp.faceX,
                    top: showing ? 28 : isLooking ? 12 : 32 + bp.faceY,
                }}>
                    <EyeBall size={16} pupilSize={6} maxDistance={4} eyeColor="white" pupilColor="#042f2e"
                        isBlinking={isDarkBlink}
                        forceLookX={showing ? -4 : isLooking ? 0 : undefined}
                        forceLookY={showing ? -4 : isLooking ? -4 : undefined} />
                    <EyeBall size={16} pupilSize={6} maxDistance={4} eyeColor="white" pupilColor="#042f2e"
                        isBlinking={isDarkBlink}
                        forceLookX={showing ? -4 : isLooking ? 0 : undefined}
                        forceLookY={showing ? -4 : isLooking ? -4 : undefined} />
                </div>
            </div>

            {/* Orange semi-circle - front left */}
            <div ref={orangeRef} className="absolute bottom-0 transition-all duration-700 ease-in-out" style={{
                left: '0%', width: '44%', height: '50%', backgroundColor: '#f59e0b',
                borderRadius: '120px 120px 0 0', zIndex: 3,
                transform: showing ? 'skewX(0deg)' : `skewX(${op.bodySkew || 0}deg)`,
                transformOrigin: 'bottom center',
            }}>
                <div className="absolute flex gap-8 transition-all duration-200 ease-out" style={{
                    left: showing ? '20%' : `calc(34% + ${op.faceX || 0}px)`,
                    top: showing ? '42%' : `calc(45% + ${op.faceY || 0}px)`,
                }}>
                    <Pupil size={12} maxDistance={5} pupilColor="#78350f"
                        forceLookX={showing ? -5 : undefined} forceLookY={showing ? -4 : undefined} />
                    <Pupil size={12} maxDistance={5} pupilColor="#78350f"
                        forceLookX={showing ? -5 : undefined} forceLookY={showing ? -4 : undefined} />
                </div>
            </div>

            {/* Yellow rounded - front right */}
            <div ref={yellowRef} className="absolute bottom-0 transition-all duration-700 ease-in-out" style={{
                left: '56%', width: '26%', height: '58%', backgroundColor: '#84cc16',
                borderRadius: '70px 70px 0 0', zIndex: 4,
                transform: showing ? 'skewX(0deg)' : `skewX(${yp.bodySkew || 0}deg)`,
                transformOrigin: 'bottom center',
            }}>
                <div className="absolute flex gap-6 transition-all duration-200 ease-out" style={{
                    left: showing ? '14%' : `calc(37% + ${yp.faceX || 0}px)`,
                    top: showing ? '15%' : `calc(17% + ${yp.faceY || 0}px)`,
                }}>
                    <Pupil size={12} maxDistance={5} pupilColor="#3f6212"
                        forceLookX={showing ? -5 : undefined} forceLookY={showing ? -4 : undefined} />
                    <Pupil size={12} maxDistance={5} pupilColor="#3f6212"
                        forceLookX={showing ? -5 : undefined} forceLookY={showing ? -4 : undefined} />
                </div>
                <div className="absolute w-16 h-[4px] bg-[#3f6212] rounded-full transition-all duration-200 ease-out"
                    style={{
                        left: showing ? '7%' : `calc(28% + ${yp.faceX || 0}px)`,
                        top: showing ? '38%' : `calc(38% + ${yp.faceY || 0}px)`,
                    }} />
            </div>
        </div>
    );
}
