import React, { useState, useEffect, useMemo } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useSettings } from '@/theme';
import Svg, { Rect, Circle, Defs, LinearGradient, Stop } from 'react-native-svg';

const DefsElement = Defs as unknown as React.ComponentType<{ children?: React.ReactNode }>;

const WHEEL_SIZE = 280;
const THUMB_SIZE = 24;

function hexToHsv(hex: string) {
  const r = parseInt(hex.slice(1, 3), 16) / 255;
  const g = parseInt(hex.slice(3, 5), 16) / 255;
  const b = parseInt(hex.slice(5, 7), 16) / 255;
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  const delta = max - min;
  let h = 0;
  if (delta !== 0) {
    if (max === r) h = ((g - b) / delta) % 6;
    else if (max === g) h = (b - r) / delta + 2;
    else h = (r - g) / delta + 4;
    h = Math.round(h * 60);
    if (h < 0) h += 360;
  }
  const s = max === 0 ? 0 : delta / max;
  const v = max;
  return { h, s, v };
}

function hsvToHex(h: number, s: number, v: number) {
  const c = v * s;
  const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
  const m = v - c;
  let r = 0, g = 0, b = 0;
  if (h < 60) { r = c; g = x; b = 0; }
  else if (h < 120) { r = x; g = c; b = 0; }
  else if (h < 180) { r = 0; g = c; b = x; }
  else if (h < 240) { r = 0; g = x; b = c; }
  else if (h < 300) { r = x; g = 0; b = c; }
  else { r = c; g = 0; b = x; }
  const toHex = (n: number) => Math.round((n + m) * 255).toString(16).padStart(2, '0');
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase();
}

interface ColorWheelProps {
  color: string;
  onChange: (color: string) => void;
}

export default function ColorWheel({ color, onChange }: ColorWheelProps) {
  const { theme } = useSettings();
  const initialHsv = useMemo(() => hexToHsv(color), [color]);
  const [hue, setHue] = useState(initialHsv.h);
  const [saturation, setSaturation] = useState(initialHsv.s);
  const [value, setValue] = useState(initialHsv.v);
  const [prevColor, setPrevColor] = useState(color);

  if (prevColor !== color) {
    setPrevColor(color);
    setHue(initialHsv.h);
    setSaturation(initialHsv.s);
    setValue(initialHsv.v);
  }

  useEffect(() => {
    const newColor = hsvToHex(hue, saturation, value);
    onChange(newColor);
  }, [hue, saturation, value, onChange]);

  const handleWheelMouseDown = (e: React.MouseEvent) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const center = WHEEL_SIZE / 2;
    const radius = (WHEEL_SIZE - THUMB_SIZE) / 2;
    const handleMove = (moveEvent: MouseEvent) => {
      const dx = moveEvent.clientX - rect.left - center;
      const dy = moveEvent.clientY - rect.top - center;
      const distance = Math.sqrt(dx * dx + dy * dy);
      if (distance > radius) return;
      const angle = Math.atan2(dy, dx) * (180 / Math.PI);
      let h = angle + 180;
      if (h >= 360) h -= 360;
      setHue(h);
      setSaturation(distance / radius);
      setValue(1 - distance / radius);
    };
    const handleUp = () => {
      window.removeEventListener('mousemove', handleMove);
      window.removeEventListener('mouseup', handleUp);
    };
    window.addEventListener('mousemove', handleMove);
    window.addEventListener('mouseup', handleUp);
    handleMove(e.nativeEvent);
  };

  const handleHueMouseDown = (e: React.MouseEvent) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const handleMove = (moveEvent: MouseEvent) => {
      const h = ((moveEvent.clientX - rect.left) / WHEEL_SIZE) * 360;
      setHue(Math.min(360, Math.max(0, h)));
    };
    const handleUp = () => {
      window.removeEventListener('mousemove', handleMove);
      window.removeEventListener('mouseup', handleUp);
    };
    window.addEventListener('mousemove', handleMove);
    window.addEventListener('mouseup', handleUp);
    handleMove(e.nativeEvent);
  };

  const thumbX = ((WHEEL_SIZE - THUMB_SIZE) / 2) * saturation * Math.cos((hue - 180) * Math.PI / 180) + (WHEEL_SIZE / 2) - (THUMB_SIZE / 2);
  const thumbY = ((WHEEL_SIZE - THUMB_SIZE) / 2) * saturation * Math.sin((hue - 180) * Math.PI / 180) + (WHEEL_SIZE / 2) - (THUMB_SIZE / 2);
  const hueThumbX = (hue / 360) * WHEEL_SIZE - (THUMB_SIZE / 2);
  const currentColor = hsvToHex(hue, saturation, value);

  return (
    <View style={styles.container}>
      <View style={styles.wheelContainer}>
        <Svg width={WHEEL_SIZE} height={WHEEL_SIZE} {...({ onMouseDown: handleWheelMouseDown } as object)}>
          <DefsElement>
            <LinearGradient id="satGradient" x1="0%" y1="0%" x2="100%" y2="0%">
              <Stop offset="0%" stopColor={`hsl(${hue}, 100%, 50%)`} stopOpacity={1} />
              <Stop offset="100%" stopColor="#FFFFFF" stopOpacity={1} />
            </LinearGradient>
            <LinearGradient id="valGradient" x1="0%" y1="0%" x2="0%" y2="100%">
              <Stop offset="0%" stopColor="transparent" stopOpacity={0} />
              <Stop offset="100%" stopColor="#000000" stopOpacity={1} />
            </LinearGradient>
          </DefsElement>
          <Circle
            cx={WHEEL_SIZE / 2}
            cy={WHEEL_SIZE / 2}
            r={(WHEEL_SIZE - THUMB_SIZE) / 2}
            fill="url(#satGradient)"
          />
          <Circle
            cx={WHEEL_SIZE / 2}
            cy={WHEEL_SIZE / 2}
            r={(WHEEL_SIZE - THUMB_SIZE) / 2}
            fill="url(#valGradient)"
          />
          <Circle
            cx={thumbX + THUMB_SIZE / 2}
            cy={thumbY + THUMB_SIZE / 2}
            r={THUMB_SIZE / 2}
            fill="#FFFFFF"
            stroke="#000000"
            strokeWidth={2}
          />
        </Svg>
      </View>

      <View style={styles.hueContainer}>
        <Svg width={WHEEL_SIZE} height={36} {...({ onMouseDown: handleHueMouseDown } as object)}>
          <DefsElement>
            <LinearGradient id="hueGradient" x1="0%" y1="0%" x2="100%" y2="0%">
              <Stop offset="0%" stopColor="#FF0000" />
              <Stop offset="17%" stopColor="#FFFF00" />
              <Stop offset="33%" stopColor="#00FF00" />
              <Stop offset="50%" stopColor="#00FFFF" />
              <Stop offset="67%" stopColor="#0000FF" />
              <Stop offset="83%" stopColor="#FF00FF" />
              <Stop offset="100%" stopColor="#FF0000" />
            </LinearGradient>
          </DefsElement>
          <Rect x={0} y={0} width={WHEEL_SIZE} height={36} rx={18} fill="url(#hueGradient)" />
          <Circle
            cx={hueThumbX + THUMB_SIZE / 2}
            cy={18}
            r={THUMB_SIZE / 2}
            fill="#FFFFFF"
            stroke="#000000"
            strokeWidth={2}
          />
        </Svg>
      </View>

      <View style={styles.previewContainer}>
        <View style={[styles.preview, { backgroundColor: currentColor }]} />
        <Text style={[styles.previewText, { color: theme.text }]}>{currentColor}</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    gap: 16,
  },
  wheelContainer: {},
  hueContainer: {
    width: WHEEL_SIZE,
  },
  previewContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 12,
  },
  preview: {
    width: 44,
    height: 44,
    borderRadius: 12,
    borderWidth: 1,
    borderColor: '#00000020',
  },
  previewText: {
    fontSize: 15,
    fontWeight: '500',
    fontFamily: 'monospace',
  },
});