import React from "react";
import {
  View,
  SafeAreaView,
  useWindowDimensions,
  TextInput,
} from "react-native";
import Animated, {
  Extrapolate,
  interpolate,
  useAnimatedRef,
  useDerivedValue,
  useSharedValue,
  useAnimatedProps,
  SharedValue,
} from "react-native-reanimated";
import Svg, { Line, Circle, Text as SVGText } from "react-native-svg";
import Slider from "@react-native-community/slider";
import {
  useFonts,
  IBMPlexSans_400Regular_Italic,
} from "@expo-google-fonts/ibm-plex-sans";
import { StatusBar } from "expo-status-bar";

const blue = "#005686";
const bluer = "#0084d6";
const bluest = "#009eff";
const sixteenPoints = [
  0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180, 202.5, 225, 247.5, 270, 292.5,
  315, 337.5, 360,
];

const AngleCircle = ({
  x,
  y,
  myAngle,
  currentAngle,
}: {
  x: number;
  y: number;
  myAngle: number;
  currentAngle: SharedValue<number>;
}) => {
  const AnimatedCircle = Animated.createAnimatedComponent(Circle);
  const animatedCircleProps = useAnimatedProps(() => {
    const r = interpolate(
      currentAngle.value,
      [myAngle - 10, myAngle, myAngle + 10],
      [3, 20, 3],
      Extrapolate.CLAMP
    );
    return {
      r,
    };
  });
  return (
    <AnimatedCircle
      x={x}
      y={y}
      r={5}
      fill={blue}
      animatedProps={animatedCircleProps}
      style={{ zIndex: 100 }}
    />
  );
};
const TrigScreen = () => {
  const { width } = useWindowDimensions();
  const AnimatedLine = Animated.createAnimatedComponent(Line);
  const AnimatedText = Animated.createAnimatedComponent(TextInput);

  const radius = width / 2;

  const aref = useAnimatedRef<Animated.ScrollView>();
  const angle = useSharedValue(0);
  const coords = useDerivedValue(() => {
    const radians = angle.value * (Math.PI / 180);
    const x = Math.floor(radius * (1 + Math.sin(radians)));
    const y = Math.floor(radius * (1 - Math.cos(radians)));
    return { x, y };
  });
  const getCoordsForAngle = (angle: number) => {
    const radians = angle * (Math.PI / 180);
    const x = Math.floor(radius * (1 + Math.sin(radians)));
    const y = Math.floor(radius * (1 - Math.cos(radians)));
    return { x, y };
  };
  const animatedTextInputProps = useAnimatedProps(() => {
    return {
      text: angle.value.toString() + "°",
      fontSize: 45,
      editable: false,
    };
  });

  const animatedOppositeProps = useAnimatedProps(() => {
    const { x, y } = coords.value;
    return {
      x1: x,
      y1: radius,
      x2: x,
      y2: y,
    };
  });
  const animatedHypotenuseProps = useAnimatedProps(() => {
    const { x, y } = coords.value;
    return {
      x1: radius,
      y1: radius,
      x2: x,
      y2: y,
    };
  });
  const animatedAdjacentProps = useAnimatedProps(() => {
    const { x, y } = coords.value;
    return {
      x1: radius,
      y1: radius,
      x2: x,
      y2: radius,
    };
  });

  const animatedXCoordProps = useAnimatedProps(() => {
    return {
      text: `x = sin(θ) = ${coords.value.x}`,
      fontSize: 45,
      editable: false,
    };
  });
  const animatedYCoordProps = useAnimatedProps(() => {
    return {
      text: `y = cos(θ) = ${coords.value.y}`,
      fontSize: 45,
      editable: false,
    };
  });
  let [fontsLoaded] = useFonts({
    IBMPlexSans_400Regular_Italic,
  });
  if (!fontsLoaded) {
    return null;
  }
  return (
    <SafeAreaView
      style={{
        flex: 1,
        backgroundColor: "#ddd",
      }}
    >
      <StatusBar style={"dark"} />
      <View style={{ flex: 1, justifyContent: "center" }}>
        <View
          style={{
            flex: 2,
            justifyContent: "flex-end",
            alignItems: "center",
          }}
        >
          <AnimatedText
            animatedProps={animatedTextInputProps}
            style={{
              fontFamily: "IBMPlexSans_400Regular_Italic",
              color: blue,
            }}
          />
          <AnimatedText
            animatedProps={animatedXCoordProps}
            style={{
              fontFamily: "IBMPlexSans_400Regular_Italic",
              color: bluer,
            }}
          />
          <AnimatedText
            animatedProps={animatedYCoordProps}
            style={{
              fontFamily: "IBMPlexSans_400Regular_Italic",
              color: bluest,
            }}
          />
        </View>
        <View style={{ flex: 1, justifyContent: "center" }}>
          <Slider
            style={{ marginHorizontal: 15 }}
            onValueChange={(value) => (angle.value = value)}
            minimumValue={0}
            maximumValue={360}
            step={1}
            minimumTrackTintColor={blue}
          />
        </View>
      </View>
      <View style={{ flex: 1 }}>
        <Svg
          viewBox={`0 -20 ${width} ${width + 50}`}
          style={{
            height: width,
            width,
          }}
        >
          {sixteenPoints.map((a) => {
            const { x, y } = getCoordsForAngle(a);
            return (
              <AngleCircle
                x={x}
                y={y}
                myAngle={a}
                currentAngle={angle}
                key={a}
              />
            );
          })}
          {sixteenPoints.map((a) => {
            const { x, y } = getCoordsForAngle(a);
            return (
              <Line x1={0} y1={y} y2={y} x2={width} stroke={"#bbb"} key={a} />
            );
          })}
          {sixteenPoints.map((a) => {
            const { x, y } = getCoordsForAngle(a);
            return (
              <Line x1={x} y1={0} y2={width} x2={x} stroke={"#bbb"} key={a} />
            );
          })}
          <AnimatedLine
            animatedProps={animatedHypotenuseProps}
            stroke={blue}
            strokeWidth={2}
          />
          <AnimatedLine
            animatedProps={animatedOppositeProps}
            stroke={bluest}
            strokeWidth={2}
          />
          <AnimatedLine
            animatedProps={animatedAdjacentProps}
            stroke={bluer}
            strokeWidth={2}
          />
          <Circle
            x={width / 2}
            y={width / 2}
            r={width / 2}
            stroke={blue}
            fillOpacity={0}
          />
        </Svg>
      </View>
    </SafeAreaView>
  );
};

export default TrigScreen;
