/* eslint-disable @typescript-eslint/no-unsafe-argument */
import * as React from 'react';
import { Button } from '@nova-hf/ui';
import { observable, makeObservable } from 'mobx';
import { gsap } from 'gsap';

import s from './StickyBar.module.scss';
import classNames from 'classnames/bind';

const cn = classNames.bind(s);

interface IStickyBarProps {
  children?: React.ReactNode;
  button?: string;
  onClick?: () => void;
  disabled?: boolean;
  color?: string;
  arrow?: boolean;
  loading?: boolean;
  backgroundColor?: string;
  noFooter?: boolean;
  alignRight?: boolean;
}

export default class StickyBar extends React.Component<IStickyBarProps> {
  sticky: HTMLDivElement | null;

  scrollRef: EventListenerOrEventListenerObject | null;

  constructor(props: IStickyBarProps) {
    super(props);

    this.scrollRef = null;
    this.sticky = null;

    makeObservable(this, {
      sticky: observable,
    });
  }

  checkStickyLayout = () => {
    const { noFooter } = this.props;
    const elm = document.querySelector('#footer');

    if (!elm) {
      return;
    }

    const footer = elm.getBoundingClientRect();
    const topFooter = footer.top - window.innerHeight;

    const fixed = topFooter > 0 || noFooter;

    this.toggleStickyBar(footer, !!fixed);
  };

  toggleStickyBar = (elm: DOMRect, fixed: boolean) => {
    if (!this.sticky) {
      return;
    }

    const t = gsap.timeline();
    t.set(this.sticky, {
      position: fixed ? 'fixed' : 'absolute',
      bottom: fixed ? 0 : elm.height,
      'z-index': fixed ? '18' : '0',
    });
  };

  componentDidMount() {
    setTimeout(() => {
      this.onScroll();
    });

    window.addEventListener('scroll', (this.scrollRef = this.onScroll));
  }

  componentWillUnmount() {
    if (this.scrollRef) {
      window.removeEventListener('scroll', this.scrollRef);
    }
  }

  componentDidUpdate() {
    this.checkStickyLayout();
  }

  onScroll = () => {
    this.checkStickyLayout();
  };

  render() {
    const {
      children,
      button,
      onClick,
      disabled,
      color,
      arrow,
      loading,
      backgroundColor,
      alignRight,
    } = this.props;

    const invertedFont = !!backgroundColor;

    return (
      <div
        className={cn(s.bar, `color-${backgroundColor || 'white'}`, {
          invertedFont,
          button,
          alignRight,
        })}
        ref={(c) => (this.sticky = c)}
        id="sticky"
      >
        <div className={s.bar__options}>
          {React.Children.toArray(children).map((c) => React.cloneElement(c, { color }))}
        </div>
        {button &&
          (arrow ? (
            <Button
              background={color}
              big
              type="button"
              onClick={onClick}
              arrowRight
              noShadow
              sticky
            >
              {button}
            </Button>
          ) : (
            <button
              className={cn(s.bar__button, `color-${color}`, { disabled, loading })}
              onClick={onClick}
            >
              <span>{button}</span>
            </button>
          ))}
      </div>
    );
  }
}
