import React, { useState, useEffect } from "react";
import { XOctagon } from "react-feather";
import { useConnection, useSend } from "state/hooks";
import { CHAINS, shortenAddress, isValidAddress, ChainId } from "utils";
import { SectionTitle } from "../Section";
import Dialog from "../Dialog";
import { SecondaryButton } from "../Buttons";
import {
  LastSection,
  Wrapper,
  Logo,
  ChangeWrapper,
  ChangeButton,
  InputWrapper,
  Input,
  ClearButton,
  CancelButton,
  ButtonGroup,
  InputError,
  Menu,
  Item,
  ToggleIcon,
  ToggleButton,
  InputGroup,
  RoundBox,
  ToggleChainName,
  Address,
  ItemWarning,
} from "./AddressSelection.styles";
import { useSelect } from "downshift";
import { CHAINS_SELECTION } from "utils/constants";
import { useAppDispatch, useAppSelector } from "state/hooks";
import { actions } from "state/send";
import { AnimatePresence } from "framer-motion";

import { useMatomo } from "@datapunt/matomo-tracker-react";

const AddressSelection: React.FC = () => {
  const { isConnected } = useConnection();
  const { toChain, toAddress, fromChain, setToAddress } = useSend();
  const [address, setAddress] = useState("");
  const [open, setOpen] = useState(false);
  const dispatch = useAppDispatch();

  const sendState = useAppSelector((state) => state.send);

  const { trackEvent } = useMatomo();

  const {
    isOpen,
    selectedItem,
    getLabelProps,
    getToggleButtonProps,
    getItemProps,
    getMenuProps,
  } = useSelect({
    items: CHAINS_SELECTION,
    defaultSelectedItem: sendState.currentlySelectedToChain,
    selectedItem: sendState.currentlySelectedToChain,
    onSelectedItemChange: ({ selectedItem }) => {
      if (selectedItem) {
        // Matomo track toChain selection
        trackEvent({
          category: "send",
          action: "setToChain",
          name: selectedItem.chainId.toString(),
        });

        const nextState = { ...sendState, toChain: selectedItem.chainId };
        dispatch(actions.toChain(nextState));
        dispatch(actions.updateSelectedToChain(selectedItem));
        const nsToChain = { ...sendState };
        if (selectedItem.chainId === ChainId.MAINNET) {
          nsToChain.fromChain = ChainId.OPTIMISM;
          dispatch(actions.fromChain(nsToChain));
          dispatch(actions.updateSelectedFromChain(CHAINS_SELECTION[0]));
        }
      }
    },
  });

  useEffect(() => {
    if (toAddress) {
      setAddress(toAddress);
    }
  }, [toAddress]);

  const toggle = () => {
    // modal is closing, reset address to the current toAddress
    if (!isConnected) return;
    if (open) setAddress(toAddress || address);
    setOpen((oldOpen) => !oldOpen);
  };
  const clearInput = () => {
    setAddress("");
  };

  const handleChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
    setAddress(evt.target.value);
  };
  const isValid = !address || isValidAddress(address);
  const handleSubmit = () => {
    if (isValid && address) {
      setToAddress({ toAddress: address });
      toggle();
    }
  };

  const isL1toL2 = fromChain === ChainId.MAINNET;

  return (
    <AnimatePresence>
      <LastSection>
        <Wrapper>
          <SectionTitle>To</SectionTitle>
          <InputGroup>
            <RoundBox as="label" {...getLabelProps()}>
              <ToggleButton type="button" {...getToggleButtonProps()}>
                <Logo src={selectedItem?.logoURI} alt={selectedItem?.name} />
                <div>
                  <ToggleChainName>
                    {selectedItem?.name === "Ether"
                      ? "Mainnet"
                      : selectedItem?.name}
                  </ToggleChainName>
                  {toAddress && <Address>{shortenAddress(toAddress)}</Address>}
                </div>
                <ToggleIcon />
              </ToggleButton>
            </RoundBox>
            <Menu isOpen={isOpen} {...getMenuProps()}>
              {isOpen &&
                sendState.currentlySelectedToChain.chainId !==
                  ChainId.MAINNET &&
                CHAINS_SELECTION.map((t, index) => {
                  return (
                    <Item
                      className={
                        t === sendState.currentlySelectedToChain ||
                        t.chainId === ChainId.MAINNET
                          ? "disabled"
                          : ""
                      }
                      {...getItemProps({ item: t, index })}
                      key={t.chainId}
                    >
                      <Logo src={t.logoURI} alt={t.name} />
                      <div>{t.name}</div>
                      <span className="layer-type">
                        {t.chainId !== ChainId.MAINNET ? "L2" : "L1"}
                      </span>
                    </Item>
                  );
                })}
              {isOpen &&
                sendState.currentlySelectedToChain.chainId ===
                  ChainId.MAINNET && (
                  <>
                    <ItemWarning
                      initial={{ y: -10 }}
                      animate={{ y: 0 }}
                      exit={{ y: -10 }}
                    >
                      <p>
                        Transfers between L2 chains is not possible at this time
                      </p>
                    </ItemWarning>
                    {CHAINS_SELECTION.map((t, index) => {
                      return (
                        <Item
                          className={"disabled"}
                          {...getItemProps({ item: t, index })}
                          key={t.chainId}
                          initial={{ y: -10 }}
                          animate={{ y: 0 }}
                          exit={{ y: -10 }}
                        >
                          <Logo src={t.logoURI} alt={t.name} />
                          <div>{t.name}</div>
                          <span className="layer-type">
                            {index !== CHAINS_SELECTION.length - 1
                              ? "L2"
                              : "L1"}
                          </span>
                        </Item>
                      );
                    })}
                  </>
                )}
            </Menu>
          </InputGroup>
          {!isL1toL2 && (
            <ChangeWrapper onClick={toggle}>
              <ChangeButton className={!isConnected ? "disabled" : ""}>
                Change account
              </ChangeButton>
            </ChangeWrapper>
          )}
        </Wrapper>
        <Dialog isOpen={open} onClose={toggle}>
          <h3>Send To</h3>
          <div>Address on {CHAINS[toChain].name}</div>
          <InputWrapper>
            <Input onChange={handleChange} value={address} />
            <ClearButton onClick={clearInput}>
              <XOctagon
                fill="var(--color-gray-300)"
                stroke="var(--color-white)"
              />
            </ClearButton>
            {!isValid && <InputError>Not a valid address</InputError>}
          </InputWrapper>
          <ButtonGroup>
            <CancelButton onClick={toggle}>Cancel</CancelButton>
            <SecondaryButton
              onClick={handleSubmit}
              disabled={!isValid || !address}
            >
              Save Changes
            </SecondaryButton>
          </ButtonGroup>
        </Dialog>
      </LastSection>
    </AnimatePresence>
  );
};

export default AddressSelection;