import { useEffect, useMemo } from "react";
import { StyleSheet, useWindowDimensions, View, type ViewProps } from "react-native";
import Animated, {
  Easing,
  useAnimatedStyle,
  useSharedValue,
  withRepeat,
  withTiming,
} from "react-native-reanimated";
import Svg, { Circle, Defs, Line, RadialGradient, Stop } from "react-native-svg";

import { useAppTheme } from "@/contexts/ThemeContext";
import { blobAnimation, blobDiameter } from "@/lib/beenvoice-theme";
import { getBackgroundTokens } from "@/lib/theme-palette";

export function BrandBackground({ style, ...props }: ViewProps) {
  const { colorScheme } = useAppTheme();
  const tokens = useMemo(() => getBackgroundTokens(colorScheme), [colorScheme]);
  const { width, height } = useWindowDimensions();
  const cx = width / 2;
  const cy = height / 2;

  const gridLines = useMemo(() => {
    const vertical: Array<{ key: string; x: number }> = [];
    const horizontal: Array<{ key: string; y: number }> = [];
    for (let x = 0; x <= width; x += tokens.gridSize) {
      vertical.push({ key: `v-${x}`, x });
    }
    for (let y = 0; y <= height; y += tokens.gridSize) {
      horizontal.push({ key: `h-${y}`, y });
    }
    return { vertical, horizontal };
  }, [width, height, tokens.gridSize]);

  return (
    <View
      style={[styles.root, { backgroundColor: tokens.background }, style]}
      pointerEvents="none"
      {...props}
    >
      <Svg width={width} height={height} style={StyleSheet.absoluteFill}>
        {gridLines.vertical.map((line) => (
          <Line
            key={line.key}
            x1={line.x}
            y1={0}
            x2={line.x}
            y2={height}
            stroke={tokens.gridLine}
            strokeWidth={1}
          />
        ))}
        {gridLines.horizontal.map((line) => (
          <Line
            key={line.key}
            x1={0}
            y1={line.y}
            x2={width}
            y2={line.y}
            stroke={tokens.gridLine}
            strokeWidth={1}
          />
        ))}
      </Svg>

      <AmbientBlob cx={cx} cy={cy} blobCore={tokens.blobCore} />
    </View>
  );
}

function AmbientBlob({ cx, cy, blobCore }: { cx: number; cy: number; blobCore: string }) {
  const progress = useSharedValue(0);
  const r = blobDiameter / 2;

  useEffect(() => {
    progress.value = withRepeat(
      withTiming(1, {
        duration: blobAnimation.durationMs,
        easing: Easing.inOut(Easing.ease),
      }),
      -1,
      false,
    );
  }, [progress]);

  const animatedStyle = useAnimatedStyle(() => {
    const k = blobAnimation.keyframes;
    const t = progress.value;
    const seg = t < 0.33 ? 0 : t < 0.66 ? 1 : 2;
    const local = seg === 0 ? t / 0.33 : seg === 1 ? (t - 0.33) / 0.33 : (t - 0.66) / 0.34;
    const from = k[seg]!;
    const to = k[seg + 1] ?? k[0]!;
    const lerp = (a: number, b: number) => a + (b - a) * local;

    return {
      transform: [
        { translateX: lerp(from.translateX, to.translateX) },
        { translateY: lerp(from.translateY, to.translateY) },
        { scale: lerp(from.scale, to.scale) },
      ],
    };
  });

  return (
    <Animated.View style={[styles.blobLayer, animatedStyle]} pointerEvents="none">
      <Svg width={blobDiameter * 1.6} height={blobDiameter * 1.6}>
        <Defs>
          <RadialGradient id="blob-a" cx="50%" cy="50%" r="50%">
            <Stop offset="0%" stopColor={blobCore} stopOpacity={0.9} />
            <Stop offset="38%" stopColor={blobCore} stopOpacity={0.35} />
            <Stop offset="62%" stopColor={blobCore} stopOpacity={0.1} />
            <Stop offset="100%" stopColor={blobCore} stopOpacity={0} />
          </RadialGradient>
        </Defs>
        <Circle cx={blobDiameter * 0.8} cy={blobDiameter * 0.8} r={r} fill="url(#blob-a)" />
      </Svg>
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  root: {
    ...StyleSheet.absoluteFill,
  },
  blobLayer: {
    position: "absolute",
    left: "50%",
    top: "50%",
    width: blobDiameter * 1.6,
    height: blobDiameter * 1.6,
    marginLeft: -(blobDiameter * 0.8),
    marginTop: -(blobDiameter * 0.8),
  },
});
