import {
  Box,
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle,
  IconButton,
  TextField,
  Typography,
} from "@mui/material";
import React, { useContext, useEffect, useState } from "react";
import { getBaseApiReact, MyContext } from "../../App";
import { Spacer } from "../../common/Spacer";
import CloseIcon from '@mui/icons-material/Close';

import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
import { validateAddress } from "../../utils/validateAddress";
import { getNameInfo, requestQueueMemberNames } from "./Group";
import { useModal } from "../../common/useModal";
import { useRecoilState } from "recoil";
import { isOpenBlockedModalAtom } from "../../atoms/global";
import InfoIcon from '@mui/icons-material/Info';
export const BlockedUsersModal = () => {
  const [isOpenBlockedModal, setIsOpenBlockedModal] = useRecoilState(isOpenBlockedModalAtom)
  const [hasChanged, setHasChanged] = useState(false);
  const [value, setValue] = useState("");
  const [addressesWithNames, setAddressesWithNames] = useState({})
  const { isShow, onCancel, onOk, show, message } = useModal();
  const { getAllBlockedUsers, removeBlockFromList, addToBlockList, setOpenSnackGlobal, setInfoSnackCustom } =
    useContext(MyContext);
  const [blockedUsers, setBlockedUsers] = useState({
    addresses: {},
    names: {},
  });
  const fetchBlockedUsers = () => {
    setBlockedUsers(getAllBlockedUsers());
  };

  useEffect(() => {
    if(!isOpenBlockedModal) return
    fetchBlockedUsers();
  }, [isOpenBlockedModal]);

   const getNames = async () => {
    // const validApi = await findUsableApi();
    const addresses = Object.keys(blockedUsers?.addresses)
    const addressNames = {}

  
    const getMemNames = addresses.map(async (address) => {
        const name = await requestQueueMemberNames.enqueue(() => {
          return getNameInfo(address);
        });
        if (name) {
          addressNames[address] = name
        } 
   
  
      return true;
    });
  
    await Promise.all(getMemNames);
  
    setAddressesWithNames(addressNames)
  };

  const blockUser = async (e, user?: string) => {
    try {
      const valUser = user || value
      if (!valUser) return;
      const isAddress = validateAddress(valUser);
      let userName = null;
      let userAddress = null;
      if (isAddress) {
        userAddress = valUser;
        const name = await getNameInfo(valUser);
        if (name) {
          userName = name;
        }
      }
      if (!isAddress) {
        const response = await fetch(`${getBaseApiReact()}/names/${valUser}`);
        const data = await response.json();
        if (!data?.owner) throw new Error("Name does not exist");
        if (data?.owner) {
          userAddress = data.owner;
          userName = valUser;
        }
      }
      if(!userName){
        await addToBlockList(userAddress, null);
        fetchBlockedUsers();
        setHasChanged(true);
        executeEvent('updateChatMessagesWithBlocks', true)
        setValue('')
        return
      }
      const responseModal = await show({
        userName,
        userAddress,
      });
      if (responseModal === "both") {
        await addToBlockList(userAddress, userName);
      } else if (responseModal === "address") {
        await addToBlockList(userAddress, null);
      } else if (responseModal === "name") {
        await addToBlockList(null, userName);
      }
      fetchBlockedUsers();
      setHasChanged(true);
      setValue('')
      if(user){
        setIsOpenBlockedModal(false)
      }
      if(responseModal === 'both' || responseModal === 'address'){
        executeEvent('updateChatMessagesWithBlocks', true)
      }
    } catch (error) {
      setOpenSnackGlobal(true);

      setInfoSnackCustom({
        type: "error",
        message: error?.message || "Unable to block user",
      });
    }
  };
  const blockUserFromOutsideModalFunc = (e) => {
      const user = e.detail?.user;
      setIsOpenBlockedModal(true)
      blockUser(null, user)
    };
  
    useEffect(() => {
      subscribeToEvent("blockUserFromOutside", blockUserFromOutsideModalFunc);
  
      return () => {
        unsubscribeFromEvent("blockUserFromOutside", blockUserFromOutsideModalFunc);
      };
    }, []);
  return (
    <Dialog
      open={isOpenBlockedModal}
      aria-labelledby="alert-dialog-title"
      aria-describedby="alert-dialog-description"
    >
      <DialogTitle>Blocked Users</DialogTitle>
      <DialogContent
        sx={{
          padding: "20px",
        }}
      >
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            gap: "10px",
          }}
        >
          <TextField
            placeholder="Name or address"
            value={value}
            onChange={(e) => {
              setValue(e.target.value);
            }}
          />
          <Button
            sx={{
              flexShrink: 0,
            }}
            variant="contained"
            onClick={blockUser}
          >
            Block
          </Button>
        </Box>

        {Object.entries(blockedUsers?.addresses).length > 0 && (
          <>
            <Spacer height="20px" />
            <DialogContentText id="alert-dialog-description">
              Blocked addresses- blocks processing of txs
            </DialogContentText>
            <Spacer height="10px" />
            <Button variant="contained" size="small" onClick={getNames}>Fetch names</Button>
            <Spacer height="10px" />
          </>
        )}

        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            gap: "10px",
          }}
        >
          {Object.entries(blockedUsers?.addresses || {})?.map(
            ([key, value]) => {
              return (
                <Box
                  sx={{
                    display: "flex",
                    alignItems: "center",
                    gap: "10px",
                    width: "100%",
                    justifyContent: "space-between",
                  }}
                >
                  <Typography>{addressesWithNames[key] || key}</Typography>
                  <Button
                    sx={{
                      flexShrink: 0,
                    }}
                    size="small"
                    variant="contained"
                    onClick={async () => {
                      try {
                        await removeBlockFromList(key, undefined);
                        setHasChanged(true);
                        setValue("");
                        fetchBlockedUsers();
                      } catch (error) {
                        console.error(error);
                      }
                    }}
                  >
                    Unblock
                  </Button>
                </Box>
              );
            }
          )}
        </Box>
        {Object.entries(blockedUsers?.names).length > 0 && (
          <>
            <Spacer height="20px" />
            <DialogContentText id="alert-dialog-description">
              Blocked names for QDN
            </DialogContentText>
            <Spacer height="10px" />
          </>
        )}

        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            gap: "10px",
          }}
        >
          {Object.entries(blockedUsers?.names || {})?.map(([key, value]) => {
            return (
              <Box
                sx={{
                  display: "flex",
                  alignItems: "center",
                  gap: "10px",
                  width: "100%",
                  justifyContent: "space-between",
                }}
              >
                <Typography>{key}</Typography>
                <Button
                  size="small"
                  sx={{
                    flexShrink: 0,
                  }}
                  variant="contained"
                  onClick={async () => {
                    try {
                      await removeBlockFromList(undefined, key);
                      setHasChanged(true);
                      fetchBlockedUsers();
                    } catch (error) {
                      console.error(error);
                    }
                  }}
                >
                  Unblock
                </Button>
              </Box>
            );
          })}
        </Box>
      </DialogContent>
      <DialogActions>
        <Button
          sx={{
            backgroundColor: "var(--green)",
            color: "black",
            fontWeight: "bold",
            opacity: 0.7,
            "&:hover": {
              backgroundColor: "var(--green)",
              color: "black",
              opacity: 1,
            },
          }}
          variant="contained"
          onClick={() => {
            if (hasChanged) {
              executeEvent("updateChatMessagesWithBlocks", true);
            }
            setIsOpenBlockedModal(false);
          }}
        >
          close
        </Button>
      </DialogActions>

      <Dialog
        open={isShow}
        aria-labelledby="alert-dialog-title"
        aria-describedby="alert-dialog-description"
      >
        <DialogTitle id="alert-dialog-title">
          {"Decide what to block"}
        </DialogTitle>
        <IconButton
          onClick={onCancel}
          sx={{
            position: 'absolute',
            right: 8,
            top: 8,
            color: 'white',
          }}
        >
          <CloseIcon />
        </IconButton>
        <DialogContent>
          <DialogContentText id="alert-dialog-description">
            Blocking {message?.userName || message?.userAddress}
          </DialogContentText>
          <Box sx={{
            display: 'flex',
            alignItems: 'center',
            gap: '10px',
            marginTop: '20px'
          }}>
            <InfoIcon sx={{
              color: 'fff'
            }}/> <Typography>Choose "block txs" or "all" to block chat messages </Typography>
          </Box>
        </DialogContent>
        <DialogActions>
          <Button
            variant="contained"
            onClick={() => {
              onOk("address");
            }}
          >
            Block txs
          </Button>
          <Button
            variant="contained"
            onClick={() => {
              onOk("name");
            }}
          >
            Block QDN data
          </Button>
          <Button
            variant="contained"
            onClick={() => {
              onOk("both");
            }}
          >
            Block All
          </Button>
        </DialogActions>
      </Dialog>
    </Dialog>
  );
};
