import React, { useRef } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, Switch } from 'react-native';
import { Controller, Control, useWatch } from 'react-hook-form';
import { TaskFormData } from '@/types';
import { useSettings } from '@/theme';
import DateTimeInput from '@/components/DateTimeInput';
import { WheelTimePicker } from '@/components/WheelTimePicker';
import Svg, { Path, Circle } from 'react-native-svg';
import { format } from 'date-fns';

interface DateTimePickerComponentProps {
  control: Control<TaskFormData>;
}

export function DateTimePickerComponent({ control }: DateTimePickerComponentProps) {
  const { theme } = useSettings();
  const [picker, setPicker] = React.useState<'date' | 'time' | 'endTime' | null>(null);
  const dateRef = useRef<((value: Date | null) => void) | null>(null);
  const timeRef = useRef<((value: string) => void) | null>(null);
  const endTimeRef = useRef<((value: string) => void) | null>(null);

  const allDay = useWatch({ control, name: 'allDay' }) ?? false;
  const dueDate = useWatch({ control, name: 'dueDate' }) ?? null;
  const startTime = useWatch({ control, name: 'dueTime' }) ?? '';
  const endTime = useWatch({ control, name: 'endTime' }) ?? '';

  const endTimeInvalid = startTime !== '' && endTime !== '' && endTime <= startTime;

  const setDateValue = (value: Date | null) => dateRef.current?.(value);
  const setTimeValue = (value: string) => timeRef.current?.(value);
  const setEndTimeValue = (value: string) => endTimeRef.current?.(value);

  const handlePickerDismiss = () => setPicker(null);

  const renderTimeButton = (
    fieldName: 'dueTime' | 'endTime',
    ref: React.MutableRefObject<((value: string) => void) | null>,
    placeholder: string,
    onPress: () => void
  ) => (
    <Controller
      control={control}
      name={fieldName}
      render={({ field }) => {
        ref.current = field.onChange;
        return (
          <TouchableOpacity
            style={[
              styles.pickerButton,
              { backgroundColor: theme.inputBg, borderColor: theme.borderStrong },
              field.value && { borderColor: theme.accent, backgroundColor: theme.accentSoft },
              fieldName === 'endTime' && endTimeInvalid && { borderColor: '#E53935', backgroundColor: theme.accentSoft },
            ]}
            onPress={onPress}
            activeOpacity={0.8}
          >
            <Svg width={20} height={20} viewBox="0 0 24 24">
              <Circle cx={12} cy={12} r={10} stroke={field.value ? theme.accent : theme.textFaint} strokeWidth={1.8} fill="none" />
              <Path d="M12 6v6l4 2" stroke={field.value ? theme.accent : theme.textFaint} strokeWidth={1.8} strokeLinecap="round" />
            </Svg>
            <Text
              style={[
                styles.pickerText,
                { color: field.value ? theme.text : theme.textMuted },
                field.value && styles.pickerTextFilled,
              ]}
              numberOfLines={1}
            >
              {field.value ? formatTime12(field.value) : placeholder}
            </Text>
            {field.value ? (
              <TouchableOpacity
                style={styles.clearButton}
                onPress={() => {
                  if (fieldName === 'dueTime') {
                    field.onChange('');
                    endTimeRef.current?.('');
                  } else {
                    field.onChange('');
                  }
                }}
                hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
              >
                <Svg width={14} height={14} viewBox="0 0 24 24">
                  <Path d="M18 6L6 18M6 6l12 12" stroke={theme.textSecondary} strokeWidth={2.2} strokeLinecap="round" />
                </Svg>
              </TouchableOpacity>
            ) : null}
          </TouchableOpacity>
        );
      }}
    />
  );

  return (
    <View style={styles.container}>
      <Text style={[styles.label, { color: theme.text }]}>Date & Time</Text>
      <View style={styles.dateRow}>
        <Controller
          control={control}
          name="dueDate"
          render={({ field }) => {
            dateRef.current = field.onChange;
            return (
              <TouchableOpacity
                style={[
                  styles.pickerButton,
                  { backgroundColor: theme.inputBg, borderColor: theme.borderStrong },
                  field.value && { borderColor: theme.accent, backgroundColor: theme.accentSoft },
                ]}
                onPress={() => setPicker('date')}
                activeOpacity={0.8}
              >
                <Svg width={20} height={20} viewBox="0 0 24 24">
                  <Path
                    d="M8 2v4M16 2v4M3 10h18M3 18h18"
                    stroke={field.value ? theme.accent : theme.textFaint}
                    strokeWidth={1.8}
                    strokeLinecap="round"
                  />
                  <Path
                    d="M10 2H14a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z"
                    stroke={field.value ? theme.accent : theme.textFaint}
                    strokeWidth={1.8}
                    fill="none"
                  />
                </Svg>
                <Text
                  style={[
                    styles.pickerText,
                    { color: field.value ? theme.text : theme.textMuted },
                    field.value && styles.pickerTextFilled,
                  ]}
                  numberOfLines={1}
                >
                  {field.value ? format(field.value, 'MMM d, yyyy') : 'Due Date'}
                </Text>
                {field.value ? (
                  <TouchableOpacity
                    style={styles.clearButton}
                    onPress={() => setDateValue(null)}
                    hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
                  >
                    <Svg width={14} height={14} viewBox="0 0 24 24">
                      <Path d="M18 6L6 18M6 6l12 12" stroke={theme.textSecondary} strokeWidth={2.2} strokeLinecap="round" />
                    </Svg>
                  </TouchableOpacity>
                ) : null}
              </TouchableOpacity>
            );
          }}
        />
      </View>
      <Controller
        control={control}
        name="allDay"
        render={({ field }) => (
          <View style={styles.allDayRow}>
            <Text style={[styles.allDayLabel, { color: theme.text }]}>All Day</Text>
            <Switch
              trackColor={{ false: theme.border, true: theme.accent }}
              thumbColor={field.value ? theme.accent : theme.textMuted}
              ios_backgroundColor={theme.border}
              value={field.value ?? false}
              onValueChange={(value) => {
                field.onChange(value);
                if (value) {
                  timeRef.current?.('');
                  endTimeRef.current?.('');
                }
              }}
            />
          </View>
        )}
      />
      {!allDay && (
        <>
          <View style={styles.timeRow}>
            {renderTimeButton('dueTime', timeRef, 'Start Time', () => setPicker('time'))}
            {renderTimeButton('endTime', endTimeRef, 'End Time', () => setPicker('endTime'))}
          </View>

          {endTimeInvalid && (
            <View style={[styles.warningRow, { backgroundColor: theme.accentSoft, borderColor: '#E53935' }]}>
              <Svg width={14} height={14} viewBox="0 0 24 24">
                <Circle cx={12} cy={12} r={10} stroke="#EF5350" strokeWidth={1.8} fill="none" />
                <Path d="M12 8v5M12 16.5v.5" stroke="#E53935" strokeWidth={1.8} strokeLinecap="round" />
              </Svg>
              <Text style={[styles.warningText, { color: '#E53935' }]}>
                {endTime === startTime
                  ? 'The end time is the same as the start time.'
                  : 'The end time is before the start time.'}
              </Text>
            </View>
          )}
        </>
      )}

      <DateTimeInput
        testID="date-picker"
        value={dueDate ?? new Date()}
        mode="date"
        is24Hour={false}
        isVisible={picker === 'date'}
        onChange={(_event, selectedDate) => {
          if (selectedDate) {
            setDateValue(selectedDate);
          }
        }}
        onDismiss={handlePickerDismiss}
      />

      <WheelTimePicker
        visible={picker === 'time' || picker === 'endTime'}
        title={picker === 'endTime' ? 'End Time' : 'Start Time'}
        initialTime={
          picker === 'endTime'
            ? endTime || startTime
            : startTime
        }
        onConfirm={(time) => {
          if (picker === 'endTime') {
            setEndTimeValue(time);
          } else {
            setTimeValue(time);
          }
          handlePickerDismiss();
        }}
        onDismiss={handlePickerDismiss}
      />
    </View>
  );
}

function formatTime12(time: string): string {
  const [hours, minutes] = time.split(':').map(Number);
  if (Number.isNaN(hours) || Number.isNaN(minutes)) return time;
  const period = hours >= 12 ? 'PM' : 'AM';
  const h = hours % 12 === 0 ? 12 : hours % 12;
  return `${h}:${String(minutes).padStart(2, '0')} ${period}`;
}

const styles = StyleSheet.create({
  container: {
    gap: 8,
  },
  label: {
    fontSize: 14,
    fontWeight: '600',
  },
  dateRow: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  allDayRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingVertical: 14,
  },
  allDayLabel: {
    fontSize: 15,
    fontWeight: '500',
  },
  timeRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  pickerButton: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    gap: 8,
    paddingVertical: 14,
    paddingHorizontal: 12,
    borderRadius: 12,
    borderWidth: 1,
    minHeight: 52,
  },
  pickerText: {
    fontSize: 15,
    flex: 1,
    flexShrink: 1,
  },
  pickerTextFilled: {
    fontWeight: '500',
  },
  clearButton: {
    padding: 4,
  },
  warningRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
    paddingVertical: 8,
    paddingHorizontal: 12,
    borderRadius: 10,
    borderWidth: 1,
  },
  warningText: {
    fontSize: 13,
    fontWeight: '500',
    flex: 1,
  },
});