import {
  Box,
  Button,
  ListItem,
  ListItemButton,
  ListItemText,
  Popover,
  TextField,
  Typography,
} from "@mui/material";
import React, {
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import {
  AutoSizer,
  CellMeasurer,
  CellMeasurerCache,
  List,
} from "react-virtualized";
import _ from "lodash";
import { MyContext, getBaseApiReact } from "../../App";
import { LoadingButton } from "@mui/lab";
import { getBaseApi, getFee } from "../../background";

const cache = new CellMeasurerCache({
  fixedWidth: true,
  defaultHeight: 50,
});

export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
  const { memberGroups, show, setTxList } = useContext(MyContext);

  const [groups, setGroups] = useState([]);
  const [popoverAnchor, setPopoverAnchor] = useState(null); // Track which list item the popover is anchored to
  const [openPopoverIndex, setOpenPopoverIndex] = useState(null); // Track which list item has the popover open
  const listRef = useRef();
  const [inputValue, setInputValue] = useState("");
  const [filteredItems, setFilteredItems] = useState(groups);
  const [isLoading, setIsLoading] = useState(false);

  const handleFilter = useCallback(
    (query) => {
      if (query) {
        setFilteredItems(
          groups.filter((item) =>
            item.groupName.toLowerCase().includes(query.toLowerCase())
          )
        );
      } else {
        setFilteredItems(groups);
      }
    },
    [groups]
  );
  const debouncedFilter = useMemo(
    () => _.debounce(handleFilter, 500),
    [handleFilter]
  );

  const handleChange = (event) => {
    const value = event.target.value;
    setInputValue(value);
    debouncedFilter(value);
  };

  const getGroups = async () => {
    try {
      const response = await fetch(
        `${getBaseApiReact()}/groups/?limit=0`
      );
      const groupData = await response.json();
      const filteredGroup = groupData.filter(
        (item) => !memberGroups.find((group) => group.groupId === item.groupId)
      );
      setGroups(filteredGroup);
      setFilteredItems(filteredGroup);
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    getGroups();
  }, [memberGroups]);

  const handlePopoverOpen = (event, index) => {
    setPopoverAnchor(event.currentTarget);
    setOpenPopoverIndex(index);
  };

  const handlePopoverClose = () => {
    setPopoverAnchor(null);
    setOpenPopoverIndex(null);
  };

  const handleJoinGroup = async (group, isOpen) => {
    try {
      const groupId = group.groupId;
      const fee = await getFee('JOIN_GROUP')
          await show({
            message: "Would you like to perform an JOIN_GROUP transaction?" ,
            publishFee: fee.fee + ' QORT'
          })
      setIsLoading(true);
      await new Promise((res, rej) => {
        chrome.runtime.sendMessage(
          {
            action: "joinGroup",
            payload: {
              groupId,
            },
          },
          (response) => {
          
            if (!response?.error) {
              setInfoSnack({
                type: "success",
                message: "Successfully requested to join group. It may take a couple of minutes for the changes to propagate",
              });
              if(isOpen){
                setTxList((prev)=> [{
                  ...response,
                  type: 'joined-group',
                  label: `Joined Group ${group?.groupName}: awaiting confirmation`,
                  labelDone: `Joined Group ${group?.groupName}: success !`,
                  done: false,
                  groupId,
                }, ...prev])
              } else {
                setTxList((prev)=> [{
                  ...response,
                  type: 'joined-group-request',
                  label: `Requested to join Group ${group?.groupName}: awaiting confirmation`,
                  labelDone: `Requested to join Group ${group?.groupName}: success !`,
                  done: false,
                  groupId,
                }, ...prev])
              }
              setOpenSnack(true);
              handlePopoverClose();
              res(response);
              return;
            } else {
              setInfoSnack({
                type: "error",
                message: response?.error,
              });
              setOpenSnack(true);
              rej(response.error);
            }
          }
        );
      });
      setIsLoading(false);
    } catch (error) {} finally {
      setIsLoading(false);

    }
  };

  const rowRenderer = ({ index, key, parent, style }) => {
    const group = filteredItems[index];

    return (
      <CellMeasurer
        key={key}
        cache={cache}
        parent={parent}
        columnIndex={0}
        rowIndex={index}
      >
        {({ measure }) => (
          <div style={style} onLoad={measure}>
            <ListItem disablePadding>
              <Popover
                open={openPopoverIndex === index}
                anchorEl={popoverAnchor}
                onClose={handlePopoverClose}
                anchorOrigin={{
                  vertical: "bottom",
                  horizontal: "center",
                }}
                transformOrigin={{
                  vertical: "top",
                  horizontal: "center",
                }}
                style={{ marginTop: "8px" }}
              >
                <Box
                  sx={{
                    width: "325px",
                    height: "250px",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    gap: "10px",
                    padding: "10px",
                  }}
                >
                  <Typography>Join {group?.groupName}</Typography>
                  <Typography>
                    {group?.isOpen === false &&
                      "This is a closed/private group, so you will need to wait until an admin accepts your request"}
                  </Typography>
                  <LoadingButton
                    loading={isLoading}
                    loadingPosition="start"
                    variant="contained"
                    onClick={() => handleJoinGroup(group, group?.isOpen)}
                  >
                    Join group
                  </LoadingButton>
                </Box>
              </Popover>
              <ListItemButton
                onClick={(event) => handlePopoverOpen(event, index)}
              >
    
                <ListItemText
                  primary={group?.groupName}
                  secondary={group?.description}
                />
              </ListItemButton>
            </ListItem>
          </div>
        )}
      </CellMeasurer>
    );
  };

  return (
    <div>
      <p>Groups list</p>
      <TextField
        label="Search for Groups"
        variant="outlined"
        fullWidth
        value={inputValue}
        onChange={handleChange}
      />
      <div
        style={{
          position: "relative",
          height: "500px",
          width: "600px",
          display: "flex",
          flexDirection: "column",
          flexShrink: 1,
        }}
      >
        <AutoSizer>
          {({ height, width }) => (
            <List
              ref={listRef}
              width={width}
              height={height}
              rowCount={filteredItems.length}
              rowHeight={cache.rowHeight}
              rowRenderer={rowRenderer}
              deferredMeasurementCache={cache}
            />
          )}
        </AutoSizer>
      </div>
    </div>
  );
};