import React, { useEffect, useMemo, useRef } from 'react';
import { useWindowDimensions, AppState } from 'react-native';
import Animated, {
    useSharedValue,
    useAnimatedStyle,
    withRepeat,
    withTiming,
    withDelay,
    Easing,
    interpolate
} from 'react-native-reanimated';
import type { SnowflakeData } from './types';
import styles from './styles';
import useChristmasTheme from '../../hooks/useChristmasTheme';
import { useTheme } from '../../branding';

const SNOWFLAKE_COUNT = 30;

const START_DELAY_MAX = 10000;
const SIZE_MIN = 3;
const SIZE_RANGE = 5;
const DURATION_BASE = 8000;
const DURATION_RANGE = 7000;
const SPARKLE_THRESHOLD = 0.7;
const TINT_COOL_THRESHOLD = 0.85;
const TINT_WARM_THRESHOLD = 0.7;

interface SnowflakeProps extends SnowflakeData {
    sparkle?: boolean;
    tint?: string;
    screenHeight: number;
    theme: string;
}

const Snowflake: React.FC<SnowflakeProps> = ({
    startDelay,
    x,
    size,
    duration,
    sparkle = false,
    tint = '#FFFFFF',
    screenHeight,
    theme
}) => {
    const progress = useSharedValue(0);
    const swing = useSharedValue(0);
    const twinkle = useSharedValue(0);

    useEffect(() => {
        progress.value = withDelay(
            startDelay,
            withRepeat(
                withTiming(1, {
                    duration,
                    easing: Easing.linear
                }),
                -1,
                false
            )
        );

        swing.value = withRepeat(
            withTiming(1, {
                duration: 3000 + Math.random() * 2000,
                easing: Easing.inOut(Easing.ease)
            }),
            -1,
            true
        );

        if (sparkle) {
            twinkle.value = withRepeat(
                withTiming(1, {
                    duration: 1000 + Math.random() * 1000,
                    easing: Easing.inOut(Easing.ease)
                }),
                -1,
                true
            );
        }
    }, [sparkle, startDelay, duration, progress, swing, twinkle]);

    const animatedStyle = useAnimatedStyle(() => {
        const translateY = interpolate(
            progress.value,
            [0, 1],
            [-50, screenHeight + 50]
        );

        const translateX = interpolate(swing.value, [0, 1], [x - 30, x + 30]);

        let opacity = interpolate(
            progress.value,
            [0, 0.1, 0.9, 1],
            [0, 0.8, 0.8, 0]
        );

        if (sparkle) {
            const twinkleOpacity = interpolate(
                twinkle.value,
                [0, 0.5, 1],
                [0.4, 1, 0.4]
            );
            opacity = opacity * twinkleOpacity;
        }

        const rotate = interpolate(swing.value, [0, 1], [0, 360]);

        return {
            transform: [
                { translateY },
                { translateX },
                { rotate: `${rotate}deg` }
            ],
            opacity
        };
    });

    return (
        <Animated.View
            style={[
                styles[theme].snowflake,
                {
                    width: size,
                    height: size,
                    borderRadius: size / 2,
                    backgroundColor: tint
                },
                animatedStyle
            ]}
        />
    );
};

const ChristmasTheme: React.FC = () => {
    const { isEnabled: hasChristmasTheme, showSnow } = useChristmasTheme();
    const { width: screenWidth, height: screenHeight } = useWindowDimensions();
    const { colors, theme } = useTheme();
    const opacity = useSharedValue(1);
    const isAppActive = useRef(true);

    useEffect(() => {
        if (!showSnow) {
            opacity.value = withTiming(0, {
                duration: 2000,
                easing: Easing.inOut(Easing.ease)
            });
        } else {
            opacity.value = withTiming(1, {
                duration: 500,
                easing: Easing.inOut(Easing.ease)
            });
        }
    }, [showSnow, opacity]);

    useEffect(() => {
        const subscription = AppState.addEventListener(
            'change',
            nextAppState => {
                if (nextAppState === 'active' && !isAppActive.current) {
                    isAppActive.current = true;
                    if (showSnow) {
                        opacity.value = withTiming(1, {
                            duration: 300,
                            easing: Easing.inOut(Easing.ease)
                        });
                    }
                } else if (
                    nextAppState.match(/inactive|background/) &&
                    isAppActive.current
                ) {
                    isAppActive.current = false;
                    opacity.value = 0;
                }
            }
        );

        return () => {
            subscription.remove();
        };
    }, [showSnow, opacity]);

    const containerStyle = useAnimatedStyle(() => ({
        opacity: opacity.value
    }));

    const snowflakes = useMemo(() => {
        const flakes: (SnowflakeData & { sparkle?: boolean; tint?: string })[] =
            [];

        const tints = [
            colors.snowflakeWhite,
            colors.snowflakeWarm,
            colors.snowflakeCool
        ];

        for (let i = 0; i < SNOWFLAKE_COUNT; i++) {
            const rand = Math.random();
            let tint = colors.snowflakeWhite;

            if (rand > TINT_COOL_THRESHOLD) {
                tint = tints[2];
            } else if (rand > TINT_WARM_THRESHOLD) {
                tint = tints[1];
            }

            flakes.push({
                index: i,
                startDelay: Math.random() * START_DELAY_MAX,
                x: Math.random() * screenWidth,
                size: SIZE_MIN + Math.random() * SIZE_RANGE,
                duration: DURATION_BASE + Math.random() * DURATION_RANGE,
                sparkle: Math.random() > SPARKLE_THRESHOLD,
                tint
            });
        }

        return flakes;
    }, [screenWidth, colors]);

    if (!hasChristmasTheme) {
        return null;
    }

    return (
        <Animated.View
            style={[styles[theme].container, containerStyle]}
            pointerEvents="none"
        >
            {snowflakes.map(flake => (
                <Snowflake
                    key={flake.index}
                    index={flake.index}
                    startDelay={flake.startDelay}
                    x={flake.x}
                    size={flake.size}
                    duration={flake.duration}
                    sparkle={flake.sparkle}
                    tint={flake.tint}
                    screenHeight={screenHeight}
                    theme={theme}
                />
            ))}
        </Animated.View>
    );
};

export default ChristmasTheme;
