import React, { useRef, useState } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import Svg, { Circle, Line, G, Text as SvgText } from 'react-native-svg';
import { useSettings } from '@/theme';

interface AnalogClockProps {
  value: Date;
  is24Hour?: boolean;
  onChange: (date: Date) => void;
}

const SIZE = 240;
const CENTER = SIZE / 2;
const RADIUS = CENTER - 8;
const NUM_RADIUS = RADIUS * 0.72;
const INNER_NUM_RADIUS = RADIUS * 0.52;

function pad(n: number): string {
  return String(n).padStart(2, '0');
}

export function AnalogClock({ value, is24Hour = false, onChange }: AnalogClockProps) {
  const { theme } = useSettings();
  const [mode, setMode] = useState<'hour' | 'minute'>('hour');
  const movedRef = useRef(false);

  const hours = value.getHours();
  const minutes = value.getMinutes();
  const isPM = hours >= 12;
  const display12 = ((hours % 12) + 12) % 12;
  const displayHour = display12 === 0 ? 12 : display12;

  const emit = (hour: number, minute: number) => {
    const next = new Date(value);
    next.setHours(hour, minute, 0, 0);
    onChange(next);
  };

  const handleSelect = (dx: number, dy: number, dragging: boolean) => {
    const distance = Math.sqrt(dx * dx + dy * dy);
    if (distance > RADIUS) return;

    const deg = (Math.atan2(dx, dy) * 180) / Math.PI;
    const normDeg = ((deg % 360) + 360) % 360;

    if (mode === 'hour') {
      if (dragging) return;
      const base = Math.round(normDeg / 30) % 12;
      let hour: number;
      if (is24Hour) {
        const inner = distance < INNER_NUM_RADIUS + 14;
        hour = inner ? base + 12 : (base === 0 ? 12 : base);
      } else {
        hour = isPM ? base + 12 : (base === 0 ? 0 : base);
      }
      emit(hour, minutes);
      setMode('minute');
    } else {
      const minute = Math.round(normDeg / 6) % 60;
      emit(hours, minute);
    }
  };

  const onLocation = (event: any, dragging: boolean) => {
    const { locationX, locationY } = event.nativeEvent;
    if (typeof locationX !== 'number' || typeof locationY !== 'number') return;
    handleSelect(locationX - CENTER, locationY - CENTER, dragging);
  };

  const hourAngle = ((hours % 12) + minutes / 60) * 30;
  const minuteAngle = minutes * 6;

  const ticks = Array.from({ length: 60 }, (_, i) => {
    const angle = (i * 6 * Math.PI) / 180;
    const major = i % 5 === 0;
    const r1 = major ? RADIUS * 0.86 : RADIUS * 0.93;
    const r2 = RADIUS * 0.985;
    return (
      <Line
        key={`tick-${i}`}
        x1={CENTER + r1 * Math.sin(angle)}
        y1={CENTER - r1 * Math.cos(angle)}
        x2={CENTER + r2 * Math.sin(angle)}
        y2={CENTER - r2 * Math.cos(angle)}
        stroke={major ? theme.textMuted : theme.borderStrong}
        strokeWidth={major ? 2 : 1}
        strokeLinecap="round"
      />
    );
  });

  const numbers = Array.from({ length: 12 }, (_, i) => {
    const hour = i === 0 ? 12 : i;
    const angle = (i * 30 * Math.PI) / 180;
    const x = CENTER + NUM_RADIUS * Math.sin(angle);
    const y = CENTER - NUM_RADIUS * Math.cos(angle);
    const active = mode === 'hour' && display12 === i;
    return (
      <SvgText
        key={`num-${hour}`}
        x={x}
        y={y}
        fontSize={16}
        fontWeight={active ? '700' : '500'}
        fill={active ? theme.accent : mode === 'minute' ? theme.textMuted : theme.text}
        textAnchor="middle"
        alignmentBaseline="central"
      >
        {hour}
      </SvgText>
    );
  });

  const innerNumbers = !is24Hour
    ? null
    : Array.from({ length: 11 }, (_, i) => {
        const hour = i + 13;
        const angle = (i * 30 * Math.PI) / 180;
        const x = CENTER + INNER_NUM_RADIUS * Math.sin(angle);
        const y = CENTER - INNER_NUM_RADIUS * Math.cos(angle);
        const active = mode === 'hour' && display12 === i + 1;
        return (
          <SvgText
            key={`inner-${hour}`}
            x={x}
            y={y}
            fontSize={12}
            fontWeight={active ? '700' : '400'}
            fill={active ? theme.accent : theme.textFaint}
            textAnchor="middle"
            alignmentBaseline="central"
          >
            {hour}
          </SvgText>
        );
      });

  const minuteDots = mode === 'minute'
    ? Array.from({ length: 12 }, (_, i) => {
        const angle = (i * 30 * Math.PI) / 180;
        const x = CENTER + RADIUS * 0.82 * Math.sin(angle);
        const y = CENTER - RADIUS * 0.82 * Math.cos(angle);
        const active = Math.round(minutes / 5) % 12 === i;
        return (
          <Circle
            key={`min-dot-${i}`}
            cx={x}
            cy={y}
            r={active ? 5 : 3}
            fill={active ? theme.accent : theme.accentBorder}
          />
        );
      })
    : null;

  return (
    <View style={styles.container}>
      <View style={styles.displayRow}>
        <TouchableOpacity onPress={() => setMode('hour')} activeOpacity={0.7}>
          <Text
            style={[
              styles.displayValue,
              { color: mode === 'hour' ? theme.accent : theme.textMuted },
              { fontSize: mode === 'hour' ? 30 : 22 },
            ]}
          >
            {pad(displayHour)}
          </Text>
        </TouchableOpacity>
        <Text style={[styles.displayColon, { color: theme.text }]}>:</Text>
        <TouchableOpacity onPress={() => setMode('minute')} activeOpacity={0.7}>
          <Text
            style={[
              styles.displayValue,
              { color: mode === 'minute' ? theme.accent : theme.textMuted },
              { fontSize: mode === 'minute' ? 30 : 22 },
            ]}
          >
            {pad(minutes)}
          </Text>
        </TouchableOpacity>
        {!is24Hour && (
          <View style={styles.periodGroup}>
            {(['AM', 'PM'] as const).map((period) => {
              const active = isPM === (period === 'PM');
              return (
                <TouchableOpacity
                  key={period}
                  onPress={() => {
                    const hour = active ? hours : hours + (period === 'PM' ? 12 : -12);
                    emit(((hour % 24) + 24) % 24, minutes);
                  }}
                  activeOpacity={0.7}
                >
                  <Text
                    style={[
                      styles.periodText,
                      { color: active ? theme.accent : theme.textFaint },
                      active && styles.periodTextActive,
                    ]}
                  >
                    {period}
                  </Text>
                </TouchableOpacity>
              );
            })}
          </View>
        )}
      </View>
      <Text style={[styles.hint, { color: theme.textFaint }]}>
        {mode === 'hour' ? 'Select the hour' : 'Select the minute'}
      </Text>

      <View
        style={styles.clockSurface}
        onStartShouldSetResponder={() => true}
        onMoveShouldSetResponder={() => true}
        onResponderGrant={(e) => {
          movedRef.current = false;
          onLocation(e, false);
        }}
        onResponderMove={(e) => {
          movedRef.current = true;
          onLocation(e, true);
        }}
        onResponderRelease={(e) => {
          if (!movedRef.current) {
            onLocation(e, false);
          }
          movedRef.current = false;
        }}
        onResponderTerminationRequest={() => false}
      >
        <Svg width={SIZE} height={SIZE}>
          <Circle
            cx={CENTER}
            cy={CENTER}
            r={RADIUS}
            fill={theme.inputBg}
            stroke={theme.borderStrong}
            strokeWidth={1.5}
          />
          {ticks}
          {minuteDots}
          {numbers}
          {innerNumbers}
          <G rotation={hourAngle} origin={`${CENTER}, ${CENTER}`}>
            <Line
              x1={CENTER}
              y1={CENTER + 12}
              x2={CENTER}
              y2={CENTER - RADIUS * 0.45}
              stroke={theme.text}
              strokeWidth={4}
              strokeLinecap="round"
            />
          </G>
          <G rotation={minuteAngle} origin={`${CENTER}, ${CENTER}`}>
            <Line
              x1={CENTER}
              y1={CENTER + 14}
              x2={CENTER}
              y2={CENTER - RADIUS * 0.66}
              stroke={theme.accent}
              strokeWidth={3}
              strokeLinecap="round"
            />
          </G>
          <Circle cx={CENTER} cy={CENTER} r={5} fill={theme.accent} />
          <Circle cx={CENTER} cy={CENTER} r={2} fill={theme.inputBg} />
        </Svg>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    gap: 4,
  },
  displayRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 6,
  },
  displayValue: {
    fontWeight: '700',
    fontVariant: ['tabular-nums'],
  },
  displayColon: {
    fontSize: 30,
    fontWeight: '700',
  },
  periodGroup: {
    marginLeft: 8,
    gap: 0,
  },
  periodText: {
    fontSize: 14,
    fontWeight: '600',
    paddingVertical: 2,
    paddingHorizontal: 4,
  },
  periodTextActive: {
    textDecorationLine: 'underline',
  },
  hint: {
    fontSize: 12,
    marginBottom: 6,
  },
  clockSurface: {
    width: SIZE,
    height: SIZE,
  },
});
