import { useColor } from "@/hooks/useColor";
import { Picker } from "@react-native-picker/picker";
import dayjs from "dayjs";
import * as DocumentPicker from "expo-document-picker";
import * as ImagePicker from "expo-image-picker";
import { CalendarIcon, CaretDown } from "phosphor-react-native";
import React, { useMemo, useState } from "react";
import { Image, Modal, Pressable, Text, TextInput, TouchableOpacity, View } from "react-native";

type FieldType = "text" | "number" | "textarea" | "image" | "file" | "select" | "date";

interface DynamicFormFieldsProps {
  id: string | number;
  label?: string;
  type: FieldType;
  required?: boolean;
  options?: string[]; // for select fields
  value?: any;
  onChange: (val: any) => void;
  placeholder?: string;
  validationError?: string;
}

export default function DynamicFormFields({ label, type, required, options = [], value, onChange, placeholder, validationError }: DynamicFormFieldsProps) {
  const [preview, setPreview] = useState<string | null>(null);
  const { primary } = useColor();
  const [showDatePicker, setShowDatePicker] = useState(false);

  // Parse YYYY-MM-DD or fall back to today
  const currentDate = useMemo(() => {
    if (value && typeof value === "string") {
      const d = dayjs(value);
      if (d.isValid()) return d;
    }
    return dayjs();
  }, [value]);

  const [tempDate, setTempDate] = useState({
    day: currentDate.date(),
    month: currentDate.month(),
    year: currentDate.year(),
  });

  const handlePickImage = async () => {
    const res = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ["images", "videos", "livePhotos"],
      quality: 0.8,
    });

    if (!res.canceled && res.assets && res.assets.length > 0) {
      const image = res.assets[0];

      const file = {
        uri: image.uri,
        name: image.fileName || `image_${Date.now()}.jpg`,
        type: image.mimeType || "image/jpeg",
      };

      setPreview(image.uri);
      onChange(file);
    }
  };

  const handlePickFile = async () => {
    const res = await DocumentPicker.getDocumentAsync({
      type: "*/*",
      copyToCacheDirectory: true,
    });

    if (res.assets && res.assets.length > 0) {
      const file = res.assets[0];

      const fileObj = {
        uri: file.uri,
        name: file.name,
        type: file.mimeType || "application/octet-stream",
      };
      onChange(fileObj);
    }
  };

  const renderInput = () => {
    switch (type) {
      case "text":
      case "number":
        return (
          <TextInput
            keyboardType={type === "number" ? "numeric" : "default"}
            value={value ?? ""}
            onChangeText={(text) => onChange?.(text)}
            placeholder={placeholder || label}
            className="placeholder:text-slate-400 text-slate-700 border border-slate-200 rounded-xl px-4 py-4 bg-slate-50/50 font-manrope-medium text-base"
          />
        );

      case "date":
        const yearOptions = [];
        const currentYear = dayjs().year();
        for (let i = currentYear - 100; i <= currentYear + 20; i++) {
          yearOptions.push(i);
        }

        const daysInMonth = dayjs(`${tempDate.year}-${tempDate.month + 1}-01`).daysInMonth();
        const dayOptions = Array.from({ length: daysInMonth }, (_, i) => i + 1);
        const monthOptions = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

        return (
          <>
            <Pressable
              onPress={() => {
                const dateToSet = value ? dayjs(value) : dayjs();
                setTempDate({
                  day: dateToSet.date(),
                  month: dateToSet.month(),
                  year: dateToSet.year(),
                });
                setShowDatePicker(true);
              }}
              className="placeholder:text-slate-400 text-slate-700 border border-slate-200 rounded-xl px-4 py-4 bg-slate-50/50 flex-row justify-between items-center"
            >
              <Text className={`font-manrope-medium text-base ${value ? "text-slate-800" : "text-slate-400"}`}>{value ? dayjs(value).format("MMMM DD, YYYY") : placeholder || "Select Date"}</Text>
              <CalendarIcon size={20} color={primary.base} weight="duotone" />
            </Pressable>

            <Modal animationType="fade" transparent={true} visible={showDatePicker} onRequestClose={() => setShowDatePicker(false)}>
              <View className="flex-1 justify-end bg-black/50">
                <View className="bg-white rounded-t-3xl overflow-hidden shadow-2xl">
                  {/* Header */}
                  <View className="flex-row justify-between items-center p-6 border-b border-slate-100">
                    <Text className="text-xl font-manrope-bold text-slate-900">Select Date</Text>
                    <TouchableOpacity onPress={() => setShowDatePicker(false)} className="size-10 bg-slate-50 rounded-full items-center justify-center">
                      <CaretDown size={20} color="#64748b" weight="bold" />
                    </TouchableOpacity>
                  </View>

                  {/* Pickers */}
                  <View className="flex-row p-4 min-h-[250px]">
                    <View className="flex-[1.2]">
                      <Picker
                        selectedValue={tempDate.month}
                        onValueChange={(val) => {
                          const m = Number(val);
                          const maxDays = dayjs().year(tempDate.year).month(m).date(1).daysInMonth();
                          setTempDate((prev) => ({
                            ...prev,
                            month: m,
                            day: prev.day > maxDays ? maxDays : prev.day,
                          }));
                        }}
                      >
                        {monthOptions.map((name, idx) => (
                          <Picker.Item key={idx} label={name} value={idx} style={{ fontSize: 16 }} />
                        ))}
                      </Picker>
                    </View>
                    <View className="flex-1">
                      <Picker selectedValue={tempDate.day} onValueChange={(val) => setTempDate((prev) => ({ ...prev, day: Number(val) }))}>
                        {dayOptions.map((d) => (
                          <Picker.Item key={d} label={String(d)} value={d} style={{ fontSize: 16 }} />
                        ))}
                      </Picker>
                    </View>
                    <View className="flex-[1.2]">
                      <Picker
                        selectedValue={tempDate.year}
                        onValueChange={(val) => {
                          const y = Number(val);
                          const maxDays = dayjs().year(y).month(tempDate.month).date(1).daysInMonth();
                          setTempDate((prev) => ({
                            ...prev,
                            year: y,
                            day: prev.day > maxDays ? maxDays : prev.day,
                          }));
                        }}
                      >
                        {[...yearOptions].reverse().map((y) => (
                          <Picker.Item key={y} label={String(y)} value={y} style={{ fontSize: 16 }} />
                        ))}
                      </Picker>
                    </View>
                  </View>

                  {/* Action Buttons */}
                  <View className="flex-row gap-x-4 p-6 border-t border-slate-50">
                    <TouchableOpacity onPress={() => setShowDatePicker(false)} className="flex-1 py-4 rounded-2xl bg-slate-100 items-center">
                      <Text className="font-manrope-bold text-slate-500">Cancel</Text>
                    </TouchableOpacity>
                    <TouchableOpacity
                      onPress={() => {
                        const formattedDate = dayjs().year(tempDate.year).month(tempDate.month).date(tempDate.day).format("YYYY-MM-DD");
                        onChange(formattedDate);
                        setShowDatePicker(false);
                      }}
                      className="flex-2 py-4 rounded-2xl items-center"
                      style={{ backgroundColor: primary.base }}
                    >
                      <Text className="font-manrope-bold text-white px-10">Confirm</Text>
                    </TouchableOpacity>
                  </View>
                </View>
              </View>
            </Modal>
          </>
        );

      case "textarea":
        return (
          <TextInput
            multiline
            numberOfLines={4}
            value={value ?? ""}
            onChangeText={(text) => onChange?.(text)}
            placeholder={placeholder || label}
            className="placeholder:text-slate-400 text-slate-700 border border-slate-200 rounded-xl px-4 py-3 bg-slate-50/50 font-manrope-medium text-base h-28"
            style={{ textAlignVertical: "top" }}
          />
        );

      case "select":
        return (
          <View className="border border-slate-200 rounded-xl bg-slate-50/50 h-14 justify-center">
            <Picker
              selectedValue={value ?? ""}
              onValueChange={(itemValue) => onChange?.(itemValue)}
              style={{
                color: "#1e293b",
                backgroundColor: "transparent",
                width: "100%",
                fontSize: 16,
                fontFamily: "Manrope_500Medium",
              }}
            >
              <Picker.Item label={placeholder || "Select"} value="" />
              {options.map((opt, idx) => (
                <Picker.Item key={idx} label={opt} value={opt} />
              ))}
            </Picker>
          </View>
        );

      case "image":
        return (
          <View className="items-start">
            <TouchableOpacity onPress={handlePickImage} className="border border-slate-200 bg-slate-50 p-4 rounded-xl w-full flex-row items-center justify-center gap-x-2">
              <Text className="font-manrope-bold text-slate-800 text-base">{preview ? "Change Image" : "Upload Image"}</Text>
            </TouchableOpacity>
            {preview && <Image source={{ uri: preview }} className="w-full h-40 mt-4 rounded-2xl border border-slate-100" resizeMode="cover" />}
          </View>
        );

      case "file":
        return (
          <View className="items-start">
            <TouchableOpacity onPress={handlePickFile} className="border border-slate-200 bg-slate-50 p-4 rounded-xl w-full flex-row items-center justify-center gap-x-2">
              <Text className="font-manrope-bold text-slate-800 text-base">{value ? "Change File" : "Upload File"}</Text>
            </TouchableOpacity>
            {value?.name && (
              <View className="mt-3 px-3 py-1.5 bg-slate-100 rounded-lg">
                <Text className="text-slate-600 font-manrope-medium text-sm" numberOfLines={1}>
                  {value.name}
                </Text>
              </View>
            )}
          </View>
        );

      default:
        return null;
    }
  };

  return (
    <View>
      {label && (
        <Text className="mb-2 text-[15px] text-slate-700 font-manrope-bold">
          {label}
          {required && <Text className="text-red-500"> *</Text>}
        </Text>
      )}
      {renderInput()}
      {validationError && <Text className="text-red-500 text-xs mt-1.5 font-manrope-medium px-1">{validationError}</Text>}
    </View>
  );
}
