import { useEffect, useRef } from "react";
import { View, Text, ScrollView, Dimensions } from "react-native";
import { Dialog, TextInput, IconButton } from "react-native-paper";
import { Controller, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

import { Button } from "@/components/ui/Button";
import { DialogContainer } from "@/components/ui/DialogContainer";
import { LoadingSpinner } from "@/components/ui/LoadingSpinner";
import { User } from "@/store/models/User.model";
import { RiskEnum, RiskLabels } from "@/constants/riskEnum";
import { RoleEnum } from "@/constants/roleEnum";
import { OperationMode } from "@/constants/operationModeEnum";
import { CustomPicker, PickerItem } from "@/components/ui/CustomPicker";
import {
  userSchemaWithId,
  UserFormValues,
} from "@/components/features/users/schemas/user.schema";

interface UserModalProps {
  visible: boolean;
  mode?: OperationMode;
  user?: User | null;
  isLoading?: boolean;
  onClose: () => void;
  onSubmit: (payload: Partial<User>) => void | Promise<void>;
}

export const UserModal = ({
  visible,
  mode = OperationMode.ADD,
  user = null,
  isLoading = false,
  onClose,
  onSubmit,
}: UserModalProps) => {
  const isEdit = mode === OperationMode.EDIT;

  const defaultValues: UserFormValues = {
    id: user?.id,
    firstName: user?.firstName ?? "",
    lastName: user?.lastName ?? "",
    email: user?.email ?? "",
    title: user?.title ?? "",
    riskStatus: user?.riskStatus ?? RiskEnum.LOW_RISK,
  };

  const {
    control,
    handleSubmit,
    reset,
    formState: { errors, isDirty },
  } = useForm<UserFormValues>({
    resolver: zodResolver(userSchemaWithId),
    defaultValues,
    mode: "onChange",
    shouldUnregister: false,
  });

  const userRef = useRef<User | null>(user);
  userRef.current = user;

  useEffect(() => {
    if (!visible) return;
    const nextDefaults: UserFormValues = {
      id: userRef.current?.id,
      firstName: userRef.current?.firstName ?? "",
      lastName: userRef.current?.lastName ?? "",
      email: userRef.current?.email ?? "",
      title: userRef.current?.title ?? "",
      riskStatus: userRef.current?.riskStatus ?? RiskEnum.LOW_RISK,
    };
    reset(nextDefaults, { keepDefaultValues: false });
  }, [visible, reset, user?.id]);

  const windowHeight = Dimensions.get("window").height;
  const dialogVerticalMargin = 24;
  const dialogMaxHeight = windowHeight - dialogVerticalMargin - 60;
  const approxChrome = 140;
  const maxDialogContentHeight = Math.max(200, dialogMaxHeight - approxChrome);

  const submit = (vals: UserFormValues) => {
    const payload: Partial<User> = {
      id: vals.id,
      firstName: vals.firstName.trim(),
      lastName: vals.lastName.trim(),
      email: vals.email.trim().toLowerCase(),
      title: vals.title.trim(),
      riskStatus: vals.riskStatus,
      role: isEdit ? (user?.role ?? RoleEnum.USER) : RoleEnum.USER,
    };
    return onSubmit(payload);
  };

  const titleText = isEdit ? "Edit User" : "Add User";
  const submitText = isEdit ? "Edit" : "Add";

  return (
    <DialogContainer
      visible={visible}
      onDismiss={onClose}
      dialogStyle={{
        alignSelf: "center",
        marginVertical: dialogVerticalMargin,
        maxHeight: dialogMaxHeight,
      }}
    >
      <Dialog.Title>
        <View className="w-full flex-row items-center justify-between">
          <View className="flex-1">
            <Text className="pr-3">{titleText}</Text>
          </View>

          <View style={{ alignSelf: "flex-start" }}>
            <IconButton
              icon="close"
              size={20}
              onPress={onClose}
              disabled={isLoading}
              accessibilityLabel="Close dialog"
              style={{ margin: 0 }}
            />
          </View>
        </View>
      </Dialog.Title>
      <Dialog.Content>
        <ScrollView
          style={{ maxHeight: maxDialogContentHeight }}
          showsVerticalScrollIndicator
        >
          <View className="mb-4">
            <Text className="text-sm mb-1 font-medium">First Name</Text>
            <Controller
              control={control}
              name="firstName"
              render={({ field: { onChange, value } }) => (
                <>
                  <TextInput
                    className={`border ${
                      errors.firstName ? "border-highRisk" : "border-gray-300"
                    } rounded p-2 text-base bg-white`}
                    value={value}
                    onChangeText={onChange}
                    placeholder="Enter first name"
                    placeholderTextColor="#d9d9d9"
                    disabled={isLoading}
                  />
                  {errors.firstName ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.firstName.message}
                    </Text>
                  ) : null}
                </>
              )}
            />
          </View>

          <View className="mb-4">
            <Text className="text-sm mb-1 font-medium">Last Name</Text>
            <Controller
              control={control}
              name="lastName"
              render={({ field: { onChange, value } }) => (
                <>
                  <TextInput
                    className={`border ${
                      errors.lastName ? "border-highRisk" : "border-gray-300"
                    } rounded p-2 text-base bg-white`}
                    value={value}
                    onChangeText={onChange}
                    placeholder="Enter last name"
                    placeholderTextColor="#d9d9d9"
                    disabled={isLoading}
                  />
                  {errors.lastName ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.lastName.message}
                    </Text>
                  ) : null}
                </>
              )}
            />
          </View>

          <View className="mb-4">
            <Text className="text-sm mb-1 font-medium">Email</Text>
            <Controller
              control={control}
              name="email"
              render={({ field: { onChange, value } }) => (
                <>
                  <TextInput
                    className={`border ${
                      errors.email ? "border-highRisk" : "border-gray-300"
                    } rounded p-2 text-base bg-white`}
                    value={value}
                    onChangeText={onChange}
                    placeholder="Enter email"
                    keyboardType="email-address"
                    placeholderTextColor="#d9d9d9"
                    autoCapitalize="none"
                    disabled={isLoading}
                  />
                  {errors.email ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.email.message}
                    </Text>
                  ) : null}
                </>
              )}
            />
          </View>

          <View className="mb-4">
            <Text className="text-sm mb-1 font-medium">Title</Text>
            <Controller
              control={control}
              name="title"
              render={({ field: { onChange, value } }) => (
                <>
                  <TextInput
                    className={`border ${
                      errors.title ? "border-highRisk" : "border-gray-300"
                    } rounded p-2 text-base bg-white`}
                    value={value}
                    onChangeText={onChange}
                    placeholder="Enter title"
                    placeholderTextColor="#d9d9d9"
                    disabled={isLoading}
                  />
                  {errors.title ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.title.message}
                    </Text>
                  ) : null}
                </>
              )}
            />
          </View>

          <View className="mb-4">
            <Text className="text-sm mb-1 font-medium">Risk Status</Text>
            <Controller
              control={control}
              name="riskStatus"
              render={({ field: { onChange, value } }) => (
                <View className="border border-gray-300 rounded overflow-hidden">
                  <CustomPicker
                    selectedValue={value}
                    onValueChange={(val) => onChange(val)}
                    className="h-10"
                    enabled={!isLoading}
                  >
                    {Object.values(RiskEnum).map((v) => (
                      <PickerItem key={v} label={RiskLabels[v]} value={v} />
                    ))}
                  </CustomPicker>
                </View>
              )}
            />
          </View>
        </ScrollView>
      </Dialog.Content>

      <Dialog.Actions>
        <Button
          onPress={handleSubmit(submit)}
          disabled={isLoading || (isEdit && !isDirty)}
          className="ml-2!"
        >
          {submitText}
        </Button>
      </Dialog.Actions>

      {isLoading && (
        <View
          className="absolute inset-0 bg-gray-500/30 flex items-center justify-center"
          pointerEvents="auto"
          style={{ zIndex: 1000, top: 0, right: 0, bottom: 0, left: 0 }}
        >
          <LoadingSpinner size={16} />
        </View>
      )}
    </DialogContainer>
  );
};
