import { useEffect, useState } from "react";
import { View, GestureResponderEvent, ScrollView, Text } from "react-native";

import { User } from "@/store/models/User.model";
import { useAppSelector } from "@/store/hooks";
import { selectIsMobile } from "@/store/screen/screenSizeSlice";
import { UserTableControls } from "@/components/features/users/UserTableControls";
import { DesktopUserAccountsTable } from "@/components/features/users/DesktopUserAccountsTable";
import { MobileUserAccountsTable } from "@/components/features/users/MobileUserAccountsTable";
import { TablePagination } from "@/components/shared/TablePagination";
import { TableSortDirection } from "@/constants/tableSortDirectionEnum";
import { RiskEnum } from "@/constants/riskEnum";

interface UserAccountsTableProps {
  users: User[];
  onEdit: (user: User) => void;
  onAddUser: () => void;
  onDelete: (user: User) => void;
  onLock: (user: User) => void;
  onSelect: (userIds: string[]) => void;
  onBulkDelete: (users: User[]) => void;
  selectedUserIds?: string[];
  page: number;
  itemsPerPage: number;
  totalItems: number;
  from: number;
  to: number;
  searchQuery: string;
  selectedRisks: RiskEnum[];
  sortColumn: string | null;
  sortDirection: TableSortDirection;
  onSearch: (q: string) => void;
  onSelectRisks: (risks: RiskEnum[]) => void;
  onSort: (column: string) => void;
  onItemsPerPageChange: (value: number) => void;
  onPageChange: (page: number) => void;
  onAddingUser: boolean;
}

export const UserAccountsTable = ({
  users,
  onEdit,
  onAddUser,
  onDelete,
  onLock,
  onSelect,
  onBulkDelete,
  selectedUserIds,
  page,
  itemsPerPage,
  totalItems,
  from,
  to,
  searchQuery,
  selectedRisks,
  sortColumn,
  sortDirection,
  onSearch,
  onSelectRisks,
  onSort,
  onItemsPerPageChange,
  onPageChange,
  onAddingUser,
}: UserAccountsTableProps) => {
  const [selectedUsers, setSelectedUsers] = useState<string[]>([]);
  const [selectAll, setSelectAll] = useState(false);
  const [menuVisible, setMenuVisible] = useState(false);
  const [menuAnchor, setMenuAnchor] = useState<{ x: number; y: number }>({
    x: 0,
    y: 0,
  });
  const [prevSelectedUserIds, setPrevSelectedUserIds] = useState<
    string[] | undefined
  >(selectedUserIds);
  const isMobile = useAppSelector(selectIsMobile);

  const handleSort = (column: string) => onSort(column);
  const handleSearch = (query: string) => onSearch(query);
  const handleSelectRisks = (risks: RiskEnum[]) => onSelectRisks(risks);
  const handleItemsPerPageChange = (value: number) =>
    onItemsPerPageChange(value);

  const handleSelectAll = () => {
    if (selectAll) {
      setSelectedUsers([]);
    } else {
      setSelectedUsers(users.map((user) => user.id) || []);
    }
    setSelectAll(!selectAll);
  };

  const handleSelectUser = (userId: string) => {
    if (selectedUsers.includes(userId)) {
      setSelectedUsers(selectedUsers.filter((id) => id !== userId));
    } else {
      setSelectedUsers([...selectedUsers, userId]);
    }
  };

  const handleBulkDelete = () => {
    if (selectedUsers.length === 0) return;

    const selectedUserObjects = users.filter((user) =>
      selectedUsers.includes(user.id)
    );

    if (onBulkDelete) {
      onBulkDelete(selectedUserObjects || []);
    } else {
      alert(`Would delete ${selectedUsers.length} users`);
    }

    if (onSelect) {
      onSelect(selectedUsers);
    }
  };

  const handleEdit = (user: User) => {
    if (onEdit) {
      onEdit(user);
    } else {
      alert(`Edit user: ${user.firstName} ${user.lastName}`);
    }
  };

  const handleDelete = (user: User) => {
    if (onDelete) {
      onDelete(user);
    } else {
      alert(`Delete user: ${user.firstName} ${user.lastName}`);
    }
  };

  const handleLock = (user: User) => {
    if (onLock) {
      onLock(user);
    } else {
      alert(`Lock user: ${user.firstName} ${user.lastName}`);
    }
  };

  useEffect(() => {
    if (onSelect) {
      onSelect(selectedUsers);
    }
  }, [selectedUsers, onSelect]);

  useEffect(() => {
    if (
      prevSelectedUserIds &&
      prevSelectedUserIds.length > 0 &&
      selectedUserIds &&
      selectedUserIds.length === 0
    ) {
      setSelectedUsers([]);
      setSelectAll(false);
    }

    setPrevSelectedUserIds(selectedUserIds);
  }, [selectedUserIds, prevSelectedUserIds]);

  useEffect(() => {
    const validSelectedUsers = selectedUsers.filter((userId) =>
      users.some((user) => user.id === userId)
    );

    if (validSelectedUsers.length !== selectedUsers.length) {
      setSelectedUsers(validSelectedUsers);
    }

    const allDisplayedSelected =
      users.every((user) => validSelectedUsers.includes(user.id)) ?? false;
    setSelectAll(allDisplayedSelected && users.length > 0);
  }, [users, selectedUsers]);

  return (
    <View className="flex-1">
      <UserTableControls
        searchQuery={searchQuery}
        selectAll={selectAll}
        selectedItems={selectedUsers}
        menuVisible={menuVisible}
        menuAnchor={menuAnchor}
        selectedRisks={selectedRisks}
        onSearch={handleSearch}
        onSelectAll={handleSelectAll}
        onBulkDelete={handleBulkDelete}
        onMenuDismiss={() => setMenuVisible(false)}
        onItemsPerPageChange={handleItemsPerPageChange}
        onSelectRisks={handleSelectRisks}
        onAddUser={onAddUser}
        onAddingUser={onAddingUser}
        itemsPerPage={itemsPerPage}
      />

      {users.length === 0 ? (
        <View
          className={`flex-1 items-center justify-center ${
            isMobile ? "p-1" : "p-5"
          }`}
        >
          <Text className="text-lg text-gray-500">
            No users match your search{searchQuery && ` for "${searchQuery}"`}
          </Text>
        </View>
      ) : isMobile ? (
        <MobileUserAccountsTable
          users={users}
          selectedUsers={selectedUsers}
          onSelectUser={handleSelectUser}
          onEdit={handleEdit}
          onLock={handleLock}
          onDelete={handleDelete}
        />
      ) : (
        <ScrollView className="flex-1">
          <DesktopUserAccountsTable
            users={users}
            selectedUsers={selectedUsers}
            sortColumn={sortColumn}
            sortDirection={sortDirection}
            onSort={handleSort}
            onSelectUser={handleSelectUser}
            onEdit={handleEdit}
            onLock={handleLock}
            onDelete={handleDelete}
          />
        </ScrollView>
      )}

      <TablePagination
        page={page}
        itemsPerPage={itemsPerPage}
        totalItems={totalItems}
        from={from}
        to={to}
        onPageChange={onPageChange}
        onItemsPerPageButtonPress={(event: GestureResponderEvent) => {
          const { pageX, pageY } = event.nativeEvent;
          setMenuAnchor({ x: pageX, y: pageY });
          setMenuVisible(true);
        }}
      />
    </View>
  );
};
