import { useEffect, useRef, useState } from 'react';
import { View, Text, Animated, Easing } from 'react-native';
import Svg, { Path, Circle } from 'react-native-svg';
import { useColors } from '../../lib/theme';

export type HalfDonutSegment = { value: number; color: string };

type Props = {
  segments: HalfDonutSegment[];
  centerValue: number | string;
  centerLabel: string;
  width?: number;
};

const W_DEFAULT = 220;
const H_DEFAULT = 130;
const R = 90;
const STROKE = 18;

function polar(cx: number, cy: number, r: number, angleDeg: number) {
  const rad = (angleDeg * Math.PI) / 180;
  return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };
}

function arcPath(cx: number, cy: number, r: number, startDeg: number, endDeg: number) {
  const start = polar(cx, cy, r, startDeg);
  const end = polar(cx, cy, r, endDeg);
  const largeArc = endDeg - startDeg > 180 ? 1 : 0;
  return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArc} 1 ${end.x} ${end.y}`;
}

export function HalfDonut({ segments, centerValue, centerLabel, width = W_DEFAULT }: Props) {
  const colors = useColors();

  const scale = width / W_DEFAULT;
  const W = width;
  const H = Math.round(H_DEFAULT * scale);
  const cx = W / 2;
  const cy = H - Math.round(8 * scale);
  const r = Math.round(R * scale);
  const stroke = Math.round(STROKE * scale);

  const total = Math.max(1, segments.reduce((s, x) => s + x.value, 0));

  let cumAngle = 180;
  const arcs = segments.map((seg) => {
    const startAngle = cumAngle;
    const endAngle = cumAngle + 180 * (seg.value / total);
    cumAngle = endAngle;
    return { ...seg, startAngle, endAngle };
  });

  const animProgress = useRef(new Animated.Value(0)).current;
  const [progress, setProgress] = useState(0);

  const animKey = typeof centerValue === 'number' ? centerValue : centerValue;

  useEffect(() => {
    animProgress.setValue(0);
    const l = animProgress.addListener(({ value }) => setProgress(value));
    Animated.timing(animProgress, {
      toValue: 1,
      duration: 1100,
      easing: Easing.out(Easing.cubic),
      useNativeDriver: false,
    }).start();
    return () => animProgress.removeListener(l);
  }, [animKey, animProgress]);

  const isEmpty = typeof centerValue === 'number' ? centerValue === 0 : centerValue === '0';

  return (
    <View style={{ alignItems: 'center', justifyContent: 'center' }}>
      <Svg width={W} height={H}>
        <Path
          d={arcPath(cx, cy, r, 180, 360)}
          stroke={colors.surfaceElevated}
          strokeWidth={stroke}
          fill="none"
          strokeLinecap="round"
        />
        {arcs.map((a, i) => {
          const animatedEnd = a.startAngle + (a.endAngle - a.startAngle) * progress;
          if (animatedEnd <= a.startAngle + 0.5) return null;
          return (
            <Path
              key={i}
              d={arcPath(cx, cy, r, a.startAngle, animatedEnd)}
              stroke={a.color}
              strokeWidth={stroke}
              fill="none"
              strokeLinecap="round"
            />
          );
        })}
        {isEmpty && (
          <Circle cx={cx} cy={cy - r + stroke / 2} r={3} fill="#d4d4d8" />
        )}
      </Svg>

      <View
        pointerEvents="none"
        style={{
          position: 'absolute',
          left: 0,
          right: 0,
          top: H / 2 + 4,
          alignItems: 'center',
        }}
      >
        <Text style={{ fontSize: 30, fontFamily: 'Nunito_900Black', color: colors.text, letterSpacing: -0.5 }}>
          {centerValue}
        </Text>
        <Text style={{ fontSize: 10, color: colors.textMuted, fontFamily: 'Nunito_400Regular', marginTop: -2 }}>
          {centerLabel}
        </Text>
      </View>
    </View>
  );
}
