import { useEffect, useState } from 'react';
import { useCreateUserMutation, useInviteUserMutation } from './queries';
import { IUserSchema, IUserFilterOptionsSchema } from '@/src/entities/models/users/users.model';
import { toast } from 'sonner';
import { set } from 'date-fns';
import { CreateUserSchema, defaulICreateUserSchemaValues, ICreateUserSchema } from '@/src/entities/models/users/create-user.model';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { defaulIInviteUserSchemaValues, IInviteUserSchema, InviteUserSchema } from '@/src/entities/models/users/invite-user.model';

export const useAddUserDialogHandler = ({ onUserAdded, onOpenChange }: {
  onUserAdded: () => void;
  onOpenChange: (open: boolean) => void;
}) => {
  const { createUser, isPending } = useCreateUserMutation();

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors: errors },
    setError,
    getValues,
    clearErrors,
    watch,
  } = useForm<ICreateUserSchema>({
    resolver: zodResolver(CreateUserSchema),
    defaultValues: {
      email: "",
      password: "",
      email_confirm: true,
    }
  });

  const emailConfirm = watch("email_confirm");

  const onSubmit = handleSubmit(async (data) => {

    await createUser(data, {
      onSuccess: () => {
        toast.success("User created successfully.");
        onUserAdded();
        onOpenChange(false);
        reset();
      },
      onError: (error) => {
        reset();
        toast.error(error.message);
      },
    });

  });

  const handleOpenChange = (open: boolean) => {
    if (!open) {
      reset();
    }
    onOpenChange(open);
  };

  return {
    register,
    handleSubmit: onSubmit,
    reset,
    errors,
    isPending,
    getValues,
    clearErrors,
    emailConfirm,
    handleOpenChange,
  };
}

export const useInviteUserHandler = ({ onUserInvited, onOpenChange }: {
  onUserInvited: () => void;
  onOpenChange: (open: boolean) => void;
}) => {

  const { inviteUser, isPending } = useInviteUserMutation();

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors: errors },
    setError,
    getValues,
    clearErrors,
    watch,
  } = useForm<IInviteUserSchema>({
    resolver: zodResolver(InviteUserSchema),
    defaultValues: defaulIInviteUserSchemaValues
  })

  const onSubmit = handleSubmit(async (data) => {
    await inviteUser(data, {
      onSuccess: () => {
        toast.success("Invitation sent");
        onUserInvited();
        onOpenChange(false);
        reset();
      },
      onError: () => {
        reset();
        toast.error("Failed to send invitation");
      },
    });
  });

  const handleOpenChange = (open: boolean) => {
    if (!open) {
      reset();
    }
    onOpenChange(open);
  };

  return {
    register,
    handleSubmit: onSubmit,
    handleOpenChange,
    reset,
    getValues,
    clearErrors,
    watch,
    errors,
    isPending,
  };
}

export const useUserManagementHandlers = (refetch: () => void) => {
  const [searchQuery, setSearchQuery] = useState("")
  const [detailUser, setDetailUser] = useState<IUserSchema | null>(null)
  const [updateUser, setUpdateUser] = useState<IUserSchema | null>(null)
  const [isSheetOpen, setIsSheetOpen] = useState(false)
  const [isUpdateOpen, setIsUpdateOpen] = useState(false)
  const [isAddUserOpen, setIsAddUserOpen] = useState(false)
  const [isInviteUserOpen, setIsInviteUserOpen] = useState(false)

  // Filter states
  const [filters, setFilters] = useState<IUserFilterOptionsSchema>({
    email: "",
    phone: "",
    lastSignIn: "",
    createdAt: "",
    status: [],
  })

  // Handle opening the detail sheet
  const handleUserClick = (user: IUserSchema) => {
    setDetailUser(user)
    setIsSheetOpen(true)
  }

  // Handle opening the update sheet
  const handleUserUpdate = (user: IUserSchema) => {
    setUpdateUser(user)
    setIsUpdateOpen(true)
  }

  // Close detail sheet when update sheet opens
  useEffect(() => {
    if (isUpdateOpen) {
      setIsSheetOpen(false)
    }
  }, [isUpdateOpen])

  // Reset detail user when sheet closes
  useEffect(() => {
    if (!isSheetOpen) {
      // Use a small delay to prevent flickering if another sheet is opening
      const timer = setTimeout(() => {
        if (!isSheetOpen && !isUpdateOpen) {
          setDetailUser(null)
        }
      }, 300)
      return () => clearTimeout(timer)
    }
  }, [isSheetOpen, isUpdateOpen])

  // Reset update user when update sheet closes
  useEffect(() => {
    if (!isUpdateOpen) {
      // Use a small delay to prevent flickering if another sheet is opening
      const timer = setTimeout(() => {
        if (!isUpdateOpen) {
          setUpdateUser(null)
        }
      }, 300)
      return () => clearTimeout(timer)
    }
  }, [isUpdateOpen])

  const clearFilters = () => {
    setFilters({
      email: "",
      phone: "",
      lastSignIn: "",
      createdAt: "",
      status: [],
    })
  }

  const getActiveFilterCount = () => {
    return Object.values(filters).filter(
      (value) => (typeof value === "string" && value !== "") || (Array.isArray(value) && value.length > 0),
    ).length
  }

  return {
    searchQuery,
    setSearchQuery,
    detailUser,
    updateUser,
    isSheetOpen,
    setIsSheetOpen,
    isUpdateOpen,
    setIsUpdateOpen,
    isAddUserOpen,
    setIsAddUserOpen,
    isInviteUserOpen,
    setIsInviteUserOpen,
    filters,
    setFilters,
    handleUserClick,
    handleUserUpdate,
    clearFilters,
    getActiveFilterCount,
  }
}

export const filterUsers = (users: IUserSchema[], searchQuery: string, filters: IUserFilterOptionsSchema): IUserSchema[] => {
  return users.filter((user) => {

    // Global search
    if (searchQuery) {
      const query = searchQuery.toLowerCase()
      const matchesSearch =
        user.email?.toLowerCase().includes(query) ||
        user.phone?.toLowerCase().includes(query) ||
        user.id.toLowerCase().includes(query)

      if (!matchesSearch) return false
    }

    // Email filter
    if (filters.email && !user.email?.toLowerCase().includes(filters.email.toLowerCase())) {
      return false
    }

    // Phone filter
    if (filters.phone && !user.phone?.toLowerCase().includes(filters.phone.toLowerCase())) {
      return false
    }

    // Last sign in filter
    if (filters.lastSignIn) {
      if (filters.lastSignIn === "never" && user.last_sign_in_at) {
        return false
      } else if (filters.lastSignIn === "today") {
        const today = new Date()
        today.setHours(0, 0, 0, 0)
        const signInDate = user.last_sign_in_at ? new Date(user.last_sign_in_at) : null
        if (!signInDate || signInDate < today) return false
      } else if (filters.lastSignIn === "week") {
        const weekAgo = new Date()
        weekAgo.setDate(weekAgo.getDate() - 7)
        const signInDate = user.last_sign_in_at ? new Date(user.last_sign_in_at) : null
        if (!signInDate || signInDate < weekAgo) return false
      } else if (filters.lastSignIn === "month") {
        const monthAgo = new Date()
        monthAgo.setMonth(monthAgo.getMonth() - 1)
        const signInDate = user.last_sign_in_at ? new Date(user.last_sign_in_at) : null
        if (!signInDate || signInDate < monthAgo) return false
      }
    }

    // Created at filter
    if (filters.createdAt) {
      if (filters.createdAt === "today") {
        const today = new Date()
        today.setHours(0, 0, 0, 0)
        const createdAt = user.created_at ? (user.created_at ? new Date(user.created_at) : new Date()) : new Date()
        if (createdAt < today) return false
      } else if (filters.createdAt === "week") {
        const weekAgo = new Date()
        weekAgo.setDate(weekAgo.getDate() - 7)
        const createdAt = user.created_at ? new Date(user.created_at) : new Date()
        if (createdAt < weekAgo) return false
      } else if (filters.createdAt === "month") {
        const monthAgo = new Date()
        monthAgo.setMonth(monthAgo.getMonth() - 1)
        const createdAt = user.created_at ? new Date(user.created_at) : new Date()
        if (createdAt < monthAgo) return false
      }
    }

    // Status filter
    if (filters.status.length > 0) {
      const userStatus = user.banned_until ? "banned" : !user.email_confirmed_at ? "unconfirmed" : "active"

      if (!filters.status.includes(userStatus)) {
        return false
      }
    }

    return true
  })
}