/**
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import React, {useEffect, useState} from 'react';
import {Animated, ScrollView, Text, TextInput, View} from 'react-native';
import {Button} from '../components';

export function AnimationsExample() {
  const [isIntervalRunning, setIsIntervalRunning] = useState(false);
  const [isTogglingComponent, setIsTogglingComponent] = useState(false);
  const [isComponentVisible, setIsComponentVisible] = useState(false);
  const xAnim = React.useRef(new Animated.Value(0)).current;
  const xAnimNative = React.useRef(new Animated.Value(0)).current;
  const yAnimNative = React.useRef(new Animated.Value(0)).current;
  const fadeAnim = React.useRef(new Animated.Value(1)).current;
  const [numberOfComponents, setNumberOfComponents] = useState(100);

  useEffect(() => {
    const timerId = isIntervalRunning
      ? setInterval(() => {
          setTimeout(() => {}, 1);
        }, 1)
      : undefined;
    return () => {
      if (timerId) {
        clearInterval(timerId);
      }
    };
  }, [isIntervalRunning]);

  useEffect(() => {
    let timerId: any;
    if (isTogglingComponent) {
      timerId = setInterval(() => {
        setIsComponentVisible(prev => !prev);
      }, 1000);
    }
    return () => {
      if (timerId) {
        clearInterval(timerId);
      }
    };
  }, [isTogglingComponent]);

  useEffect(() => {
    const x = Animated.loop(
      Animated.sequence([
        Animated.timing(xAnim, {
          toValue: 0,
          duration: 1000,
          useNativeDriver: false,
        }),
        Animated.timing(xAnim, {
          toValue: 100,
          duration: 1000,
          useNativeDriver: false,
        }),
        Animated.timing(xAnim, {
          toValue: 0,
          duration: 1000,
          useNativeDriver: false,
        }),
      ]),
    );
    x.start();

    const xNative = Animated.loop(
      Animated.sequence([
        Animated.timing(xAnimNative, {
          toValue: 0,
          duration: 1000,
          useNativeDriver: true,
        }),
        Animated.timing(xAnimNative, {
          toValue: 100,
          duration: 1000,
          useNativeDriver: true,
        }),
        Animated.timing(xAnimNative, {
          toValue: 0,
          duration: 1000,
          useNativeDriver: true,
        }),
      ]),
    );
    xNative.start();

    const yNative = Animated.loop(
      Animated.sequence([
        Animated.timing(yAnimNative, {
          toValue: 0,
          duration: 1000,
          useNativeDriver: true,
        }),
        Animated.timing(yAnimNative, {
          toValue: 2,
          duration: 1000,
          useNativeDriver: true,
        }),
        Animated.timing(yAnimNative, {
          toValue: 0,
          duration: 1000,
          useNativeDriver: true,
        }),
      ]),
    );
    yNative.start();

    const fade = Animated.loop(
      Animated.sequence([
        Animated.timing(fadeAnim, {
          toValue: 0,
          duration: 1000,
          useNativeDriver: true,
        }),
        Animated.timing(fadeAnim, {
          toValue: 1,
          duration: 1000,
          useNativeDriver: true,
        }),
      ]),
    );
    fade.start();

    return () => {
      x.stop();
      xNative.stop();
      fade.stop();
    };
  }, []);

  const spin = xAnimNative.interpolate({
    inputRange: [0, 100],
    outputRange: ['0deg', '180deg'],
  });

  return (
    <ScrollView>
      <View style={{flexDirection: 'row'}}>
        <Button
          label={isIntervalRunning ? 'Stop running interval' : 'Run interval'}
          onPress={() => {
            setIsIntervalRunning(prev => !prev);
          }}
        />
        <Button
          label={
            isTogglingComponent
              ? 'Stop toggling component'
              : 'Start toggling component'
          }
          onPress={() => {
            setIsTogglingComponent(prev => !prev);
          }}
        />
      </View>
      <TextInput
        style={{
          backgroundColor: 'white',
          width: '100%',
          height: 36,
          color: 'black',
        }}
        value={numberOfComponents.toString()}
        onChangeText={value => {
          setNumberOfComponents(parseInt(value) || 0);
        }}
      />
      <View style={{width: '100%'}}>
        {new Array(numberOfComponents).fill(0).map((_, idx) => {
          return (
            <View
              key={idx}
              style={{
                position: 'absolute',
                top: Math.random() * 500,
                left: Math.random() * 300,
                width: 25,
                height: 25,
                backgroundColor: Math.random() < 0.5 ? 'green' : 'blue',
              }}
            />
          );
        })}
        <Animated.View
          style={{
            height: 100,
            width: 100,
            opacity: fadeAnim,
            backgroundColor: 'red',
          }}
        />
        <Animated.View
          style={{
            height: 100,
            width: 100,
            left: xAnim,
            backgroundColor: 'red',
          }}>
          <Text style={{height: 24}}>Position</Text>
        </Animated.View>
        <>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [{translateX: xAnim}],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 24}}>Transform</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [{translateX: xAnimNative}],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 24}}>Native driver</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [{translateX: Animated.add(xAnimNative, 50)}],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 48}}>Native driver Addition</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [
                {translateX: Animated.multiply(xAnimNative, yAnimNative)},
              ],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 48}}>Native driver Multiplication</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [
                {
                  translateX: Animated.divide(
                    xAnimNative,
                    Animated.add(yAnimNative, 1),
                  ),
                },
              ],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 48}}>Native driver Division</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [{translateX: Animated.subtract(xAnimNative, 50)}],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 48}}>Native driver Subtraction</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [
                {scaleX: Animated.add(Animated.divide(xAnimNative, 100), 0.5)},
              ],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 48}}>Native driver scale</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [{rotate: spin}],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 48}}>Native driver rotate</Text>
          </Animated.View>
          <Animated.View
            style={{
              height: 100,
              width: 100,
              transform: [{rotateX: spin}, {rotateY: spin}],
              backgroundColor: 'red',
            }}>
            <Text style={{height: 48}}>Native driver rotate X&Y</Text>
          </Animated.View>
        </>
        {isComponentVisible && (
          <View
            style={{
              width: 100,
              height: 100,
              backgroundColor: 'blue',
              position: 'absolute',
              right: 0,
            }}
          />
        )}
      </View>
    </ScrollView>
  );
}