/* eslint-disable react/no-array-index-key */
import type { EVMChain } from '@lifi/sdk';
import { Avatar, Box, Skeleton, Tooltip, Typography } from '@mui/material';
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  maxChainsToOrder,
  maxChainsToShow,
} from '../../stores/chains/createChainOrderStore.js';
import type { FormTypeProps } from '../../stores/form/types.js';
import { FormKeyHelper } from '../../stores/form/types.js';
import { useFieldValues } from '../../stores/form/useFieldValues.js';
import { navigationRoutes } from '../../utils/navigationRoutes.js';
import { ChainCard, ChainContainer } from '../ChainSelect/ChainSelect.style.js';
import { useChainSelect } from '../ChainSelect/useChainSelect.js';
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
import { useFieldActions } from '../../stores/form/useFieldActions.js';
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js';
import { useToken } from '../../hooks/useToken.js';
import { useAccount } from '../../hooks/useAccount.js';
import { WidgetEvent } from '../../types/events.js';

export const ListChainSelect = ({ formType }: FormTypeProps) => {
  const navigate = useNavigate();
  const {
    chainOrder,
    chains,
    getChains,
    isLoading,
    setChainOrder,
    setCurrentChain,
  } = useChainSelect(formType);
  const {
    handleSelectToken,
    handleSelectChainId,
    defaultChainId,
    defaultFromToken,
    defaultToToken,
  } = useWidgetConfig();

  const [chainId] = useFieldValues(FormKeyHelper.getChainKey(formType));
  const { setUserAndDefaultValues, resetField } = useFieldActions();

  const [fromToken] = useFieldValues(FormKeyHelper.getTokenKey('from'));
  const [toToken] = useFieldValues(FormKeyHelper.getTokenKey('to'));

  const { token: fromTokenInfo } = useToken(chainId, fromToken);
  const { token: toTokenInfo } = useToken(chainId, toToken);

  const emitter = useWidgetEvents();

  const { account } = useAccount();

  useEffect(() => {
    if (account?.isConnected) {
      emitter.emit(WidgetEvent.WalletConnected, {
        address: account.address,
        chainId: account.chainId,
        chainType: account.chainType,
      });
    } else {
      emitter.emit(WidgetEvent.WalletConnected, {
        address: '',
        chainId: 0,
        chainType: undefined,
      });
    }
  }, [account, emitter]);

  useEffect(() => {
    if (chainId) {
      handleSelectChainId && handleSelectChainId(chainId);
      handleSelectToken && handleSelectToken({});
    }
  }, [chainId, handleSelectChainId, handleSelectToken]);

  useEffect(() => {
    if (fromToken || toToken) {
      handleSelectToken &&
        handleSelectToken({
          fromToken,
          fromTokenInfo,
          toToken,
          toTokenInfo,
        });
    }
  }, [fromToken, fromTokenInfo, toToken, toTokenInfo, handleSelectToken]);

  // useEffect(() => {
  //   if (defaultChainId && defaultFromToken && defaultToToken) {
  //     resetField('fromChain', { defaultValue: defaultChainId });
  //     resetField('toChain', { defaultValue: defaultChainId });

  //     window.history.replaceState(
  //       null,
  //       '',
  //       window.location.pathname +
  //         `?fromChain=${defaultChainId}&fromToken=${defaultFromToken}&toChain=${defaultChainId}&toToken=${defaultToToken}`,
  //     );
  //   }
  // }, [defaultChainId, defaultFromToken, defaultToToken, resetField]);

  useEffect(() => {
    if (chainId) {
      const hasChainInOrderedList = chainOrder.includes(chainId);
      // If we don't have a chain in the ordered chain list we should add it.
      if (!hasChainInOrderedList) {
        setChainOrder(chainId, formType);
      }
    }
  }, [chainId, chainOrder, formType, setChainOrder]);

  const showAllChains = () => {
    navigate(navigationRoutes[`${formType}Chain`]);
  };

  // We check if we can accommodate all the chains on the grid
  // If there are more than 10 chains we show the number of hidden chains as the last one tile
  const chainsToHide =
    chains?.length === maxChainsToShow
      ? 0
      : (chains?.length ?? 0) - maxChainsToOrder;

  // When there is less than 10 chains we don't care about the order
  const chainsToShow = chainsToHide > 0 ? getChains() : chains;

  const sortedChainsToShow = chainsToShow?.sort((a, b) => {
    const chainTypeOrder = { MVM: 1, TVM: 2, SVM: 3 };
    const aOrder =
      chainTypeOrder[a.chainType as keyof typeof chainTypeOrder] || 4;
    const bOrder =
      chainTypeOrder[b.chainType as keyof typeof chainTypeOrder] || 4;
    return aOrder - bOrder;
  });

  return (
    <>
      {chains?.length === 1 ? (
        <></>
      ) : (
        <ChainContainer style={{ marginBottom: '14px' }}>
          {isLoading
            ? Array.from({ length: maxChainsToOrder }).map((_, index) => (
                <Skeleton
                  key={index}
                  variant="rectangular"
                  width={56}
                  height={56}
                  sx={{ borderRadius: 1 }}
                />
              ))
            : sortedChainsToShow?.map((chain: EVMChain) => (
                <Tooltip key={chain.id} title={chain.name} enterNextDelay={100}>
                  <ChainCard
                    component="button"
                    onClick={() => {
                      if (chain.id === chainId) {
                        return;
                      }
                      setCurrentChain(chain.id);
                      setUserAndDefaultValues({
                        fromToken: '',
                        toToken: '',
                      });
                    }}
                    type={chainId === chain.id ? 'selected' : 'default'}
                    selectionColor="primary"
                  >
                    <Avatar
                      src={chain.logoURI}
                      alt={chain.key}
                      sx={{ width: 40, height: 40 }}
                    >
                      {chain.name[0]}
                    </Avatar>
                  </ChainCard>
                </Tooltip>
              ))}

          {chainsToHide > 0 ? (
            <ChainCard component="button" onClick={showAllChains}>
              <Box
                sx={{
                  width: 40,
                  height: 40,
                  display: 'grid',
                  placeItems: 'center',
                }}
              >
                <Typography fontWeight={500}>+{chainsToHide}</Typography>
              </Box>
            </ChainCard>
          ) : null}
        </ChainContainer>
      )}
    </>
  );
};
