import { useEffect, useMemo, 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 { LoadingSpinner } from "@/components/ui/LoadingSpinner";
import { User } from "@/store/models/User.model";
import { RoleEnum } from "@/constants/roleEnum";
import { RiskEnum } from "@/constants/riskEnum";
import { OperationMode } from "@/constants/operationModeEnum";
import { DialogContainer } from "@/components/ui/DialogContainer";
import { useAuthContext } from "@/auth/AuthContext";
import { useGetUsersQuery } from "@/store/api/usersApi";
import { CustomPicker, PickerItem } from "@/components/ui/CustomPicker";
import {
  adminSchema,
  AdminFormValues,
} from "@/components/features/admins/schemas/admin.schema";

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

export const AdminModal = ({
  visible,
  mode = OperationMode.ADD,
  admin = null,
  isLoading,
  onClose,
  onSubmit,
}: AdminModalProps) => {
  const isEdit = mode === OperationMode.EDIT;
  const { user: currentUser } = useAuthContext();
  const { data: adminsData } = useGetUsersQuery(
    {
      roleType: "admin",
      limit: 1000,
    },
    { skip: !visible },
  );
  const managerOptions = useMemo(
    () => (adminsData?.items || []).filter((u) => u.role === RoleEnum.MANAGER),
    [adminsData],
  );

  const adminRef = useRef<User | null>(admin);
  adminRef.current = admin;
  const currentUserRef = useRef(currentUser);
  currentUserRef.current = currentUser;

  const defaultValues: AdminFormValues = {
    id: admin?.id,
    email: admin?.email ?? "",
    firstName: admin?.firstName ?? "",
    lastName: admin?.lastName ?? "",
    title: admin?.title ?? "",
    role: admin?.role ?? RoleEnum.ADMIN,
    riskStatus: admin?.riskStatus ?? RiskEnum.LOW_RISK,
    managerId:
      admin?.managerId ??
      (currentUser?.role === RoleEnum.MANAGER ? currentUser.id : undefined),
  };

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

  useEffect(() => {
    if (!visible) return;
    const nextDefaults: AdminFormValues = {
      id: adminRef.current?.id,
      email: adminRef.current?.email ?? "",
      firstName: adminRef.current?.firstName ?? "",
      lastName: adminRef.current?.lastName ?? "",
      title: adminRef.current?.title ?? "",
      role: adminRef.current?.role ?? RoleEnum.ADMIN,
      riskStatus: adminRef.current?.riskStatus ?? RiskEnum.LOW_RISK,
      managerId:
        adminRef.current?.managerId ??
        (currentUserRef.current?.role === RoleEnum.MANAGER
          ? currentUserRef.current?.id
          : undefined),
    };
    reset(nextDefaults, { keepDefaultValues: false });
  }, [visible, reset, admin?.id, currentUser?.id, currentUser?.role]);

  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 selectedRole = watch("role");

  const submit = (vals: AdminFormValues) => {
    const payload: Partial<User> = {
      id: vals.id,
      email: vals.email.trim().toLowerCase(),
      firstName: vals.firstName.trim(),
      lastName: vals.lastName.trim(),
      title: vals.title.trim(),
      role: vals.role || RoleEnum.ADMIN,
      riskStatus: vals.riskStatus || RiskEnum.LOW_RISK,
      // Only Managers can assign Admins to a Manager (Managers themselves cannot be reassigned)
      ...(currentUser?.role === RoleEnum.MANAGER && vals.role === RoleEnum.ADMIN
        ? { managerId: vals.managerId ?? undefined }
        : {}),
    };

    onSubmit(payload);
  };

  const titleText = isEdit ? "Edit Admin" : "Add Admin";
  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 }}
          contentContainerStyle={{ paddingBottom: 16 }}
        >
          <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 address"
                    keyboardType="email-address"
                    autoCapitalize="none"
                    placeholderTextColor="#d9d9d9"
                  />
                  {errors.email ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.email.message as string}
                    </Text>
                  ) : null}
                </>
              )}
            />
          </View>

          <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"
                    autoCapitalize="words"
                    placeholderTextColor="#d9d9d9"
                  />
                  {errors.firstName ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.firstName.message as string}
                    </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"
                    autoCapitalize="words"
                    placeholderTextColor="#d9d9d9"
                  />
                  {errors.lastName ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.lastName.message as string}
                    </Text>
                  ) : null}
                </>
              )}
            />
          </View>

          {/* Password field removed for invitation-only flow */}

          <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 job title"
                    autoCapitalize="words"
                    placeholderTextColor="#d9d9d9"
                  />
                  {errors.title ? (
                    <Text className="text-highRisk text-xs mt-1">
                      {errors.title.message as string}
                    </Text>
                  ) : null}
                </>
              )}
            />
          </View>

          <View className="mb-4">
            <Text className="text-sm mb-1 font-medium">Role</Text>
            <View className="border border-gray-300 rounded overflow-hidden">
              <Controller
                control={control}
                name="role"
                render={({ field: { onChange, value } }) => (
                  <CustomPicker
                    selectedValue={value}
                    onValueChange={(v) => onChange(v)}
                  >
                    <PickerItem label="Admin" value={RoleEnum.ADMIN} />
                    <PickerItem label="Manager" value={RoleEnum.MANAGER} />
                  </CustomPicker>
                )}
              />
            </View>
          </View>

          {currentUser?.role === RoleEnum.MANAGER &&
          selectedRole === RoleEnum.ADMIN ? (
            <View className="mb-4">
              <Text className="text-sm mb-1 font-medium">
                Assign to Manager
              </Text>
              <View className="border border-gray-300 rounded overflow-hidden">
                <Controller
                  control={control}
                  name="managerId"
                  render={({ field: { onChange, value } }) => (
                    <CustomPicker
                      selectedValue={value ?? undefined}
                      onValueChange={(v) => onChange(v)}
                    >
                      {managerOptions.map((m) => (
                        <PickerItem
                          key={m.id}
                          label={
                            `${m.firstName} ${m.lastName}`.trim() || m.email
                          }
                          value={m.id}
                        />
                      ))}
                    </CustomPicker>
                  )}
                />
              </View>
            </View>
          ) : null}
        </ScrollView>
      </Dialog.Content>

      <Dialog.Actions>
        <Button
          onPress={handleSubmit(submit)}
          disabled={isLoading || !isValid || (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>
  );
};
