import { Ionicons } from "@expo/vector-icons";
import DateTimePicker, {
  type DateTimePickerEvent,
} from "@react-native-community/datetimepicker";
import { useState } from "react";
import { Modal, Platform, Pressable, StyleSheet, Text, View } from "react-native";

import { fonts, radii, spacing } from "@/constants/theme";
import { useAppTheme } from "@/contexts/ThemeContext";
import { formatDate, formatDateTime } from "@/lib/format";

type DateTimeFieldProps = {
  label: string;
  value: Date;
  mode?: "date" | "datetime";
  maximumDate?: Date;
  minimumDate?: Date;
  onChange: (date: Date) => void;
};

export function DateTimeField({
  label,
  value,
  mode = "datetime",
  maximumDate = new Date(),
  minimumDate,
  onChange,
}: DateTimeFieldProps) {
  const { colors, isDark } = useAppTheme();
  const [open, setOpen] = useState(false);
  const [draft, setDraft] = useState(value);

  function openPicker() {
    setDraft(value);
    setOpen(true);
  }

  function applyDate(next: Date) {
    const clamped =
      next.getTime() > maximumDate.getTime()
        ? maximumDate
        : minimumDate && next.getTime() < minimumDate.getTime()
          ? minimumDate
          : next;
    onChange(clamped);
  }

  function handleChange(event: DateTimePickerEvent, selected?: Date) {
    if (Platform.OS === "android") {
      setOpen(false);
      if (event.type === "set" && selected) {
        applyDate(selected);
      }
      return;
    }
    if (selected) {
      setDraft(selected);
    }
  }

  return (
    <View style={styles.wrapper}>
      <Text style={[styles.label, { color: colors.mutedForeground }]}>{label}</Text>
      <Pressable
        accessibilityRole="button"
        onPress={openPicker}
        style={({ pressed }) => [
          styles.trigger,
          {
            borderColor: colors.border,
            backgroundColor: colors.cardGlass,
          },
          pressed && styles.triggerPressed,
        ]}
      >
        <Text style={[styles.value, { color: colors.foreground }]}>
          {mode === "date" ? formatDate(value) : formatDateTime(value)}
        </Text>
        <Ionicons name="calendar-outline" size={18} color={colors.mutedForeground} />
      </Pressable>

      {Platform.OS === "ios" ? (
        <Modal visible={open} transparent animationType="slide" onRequestClose={() => setOpen(false)}>
          <Pressable style={styles.backdrop} onPress={() => setOpen(false)}>
            <Pressable
              style={[styles.sheet, { backgroundColor: colors.card }]}
              onPress={(event) => event.stopPropagation()}
            >
              <View style={[styles.sheetHeader, { borderBottomColor: colors.border }]}>
                <Pressable onPress={() => setOpen(false)}>
                  <Text style={[styles.sheetAction, { color: colors.mutedForeground }]}>Cancel</Text>
                </Pressable>
                <Text style={[styles.sheetTitle, { color: colors.foreground }]}>{label}</Text>
                <Pressable
                  onPress={() => {
                    applyDate(draft);
                    setOpen(false);
                  }}
                >
                  <Text style={[styles.sheetAction, { color: colors.primary }]}>Done</Text>
                </Pressable>
              </View>
              <DateTimePicker
                value={draft}
                mode={mode}
                display="spinner"
                maximumDate={maximumDate}
                minimumDate={minimumDate}
                themeVariant={isDark ? "dark" : "light"}
                onChange={handleChange}
              />
            </Pressable>
          </Pressable>
        </Modal>
      ) : open ? (
        <DateTimePicker
          value={draft}
          mode={mode}
          maximumDate={maximumDate}
          minimumDate={minimumDate}
          onChange={handleChange}
        />
      ) : null}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    gap: spacing.xs,
  },
  label: {
    fontSize: 13,
    fontFamily: fonts.bodyMedium,
  },
  trigger: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    borderWidth: 1,
    borderRadius: radii.md,
    paddingHorizontal: spacing.md,
    minHeight: 48,
    paddingVertical: spacing.sm,
  },
  triggerPressed: {
    opacity: 0.92,
  },
  value: {
    fontSize: 15,
    fontFamily: fonts.body,
    flex: 1,
  },
  backdrop: {
    flex: 1,
    justifyContent: "flex-end",
    backgroundColor: "rgba(0,0,0,0.45)",
  },
  sheet: {
    borderTopLeftRadius: radii.lg,
    borderTopRightRadius: radii.lg,
    paddingBottom: spacing.lg,
  },
  sheetHeader: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    paddingHorizontal: spacing.md,
    paddingVertical: spacing.md,
    borderBottomWidth: 1,
  },
  sheetTitle: {
    fontSize: 15,
    fontFamily: fonts.bodySemiBold,
  },
  sheetAction: {
    fontSize: 15,
    fontFamily: fonts.bodyMedium,
  },
});
