import * as React from 'react';
import {
  createContext,
  ReactNode,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react';
import {
  AlertBanner,
  AlertBannerLinkProps,
  AlertBannerType,
  Transition,
  TransitionType,
} from 'twitch-core-ui';

const initBannerContent: BannerContent = {
  id: '',
  status: '',
  message: '',
  type: AlertBannerType.Info,
};

interface BannerContent {
  id: string;
  status: string;
  message: string;
  type: AlertBannerType;
  link?: BannerLink;
}

interface BannerLink {
  text: string;
  href: string;
}

export const BannerContext = createContext({
  bannerContent: initBannerContent,
  showBanner: (_: BannerContent): void => {
    /**/
  },
  hideBanner: (): void => {
    /**/
  },
  enabled: false,
});

interface BannerContextProps {
  children: ReactNode;
}
export const BannerContextProvider = ({ children }: BannerContextProps) => {
  const [bannerContent, setBannerContent] = useState<BannerContent>(
    initBannerContent,
  );

  const [enabled, setEnabled] = useState(false);
  const [bannerId, setBannerId] = useState<NodeJS.Timeout | undefined>(undefined);
  const lastBannerId = usePreviousBannerId(bannerId);
  useEffect(() => {
    if (bannerId !== lastBannerId && lastBannerId !== undefined) {
      clearTimeout(lastBannerId);
    }
  }, [lastBannerId]);

  const showBanner = (b: BannerContent) => {
    setBannerId(setTimeout(hideBanner, 10000));
    setBannerContent(b);
    setEnabled(true);
  };

  const hideBanner = () => {
    setBannerId(undefined);
    setEnabled(false);
  };

  const contextData = {
    bannerContent,
    showBanner,
    hideBanner,
    enabled,
  };

  return (
    <BannerContext.Provider value={contextData}>
      {children}
    </BannerContext.Provider>
  );
};

export const Banner = () => {
  const { bannerContent, hideBanner, enabled } = useContext(BannerContext);

  let link: AlertBannerLinkProps | undefined;
  if (bannerContent.link) {
    link = {
      text: bannerContent.link.text,
      linkTo: bannerContent.link.href,
    };
  } else {
    link = undefined;
  }

  return (
    <Transition type={TransitionType.TranslateTop} show={enabled}>
      <AlertBanner
        status={bannerContent.status}
        message={bannerContent.message}
        type={bannerContent.type}
        closeButton={{
          'aria-label': 'Close',
          'onClick': hideBanner,
        }}
        link={link}
      />
    </Transition>
  );
};

function usePreviousBannerId(value: NodeJS.Timeout | undefined): NodeJS.Timeout | undefined {
  const ref = useRef<NodeJS.Timeout>();
  useEffect(() => {
    ref.current = value;
  }, [value]);
  return ref.current ? ref.current : undefined;
}
