import { createContext, useContext, useState } from 'react';
import { useQuery } from 'react-query';
import { useLocation } from 'react-router-dom';

import useNpsFeedback from 'src/hooks/useNpsFeedback';
import useNpsSurvey from 'src/hooks/useNpsSurvey';
import { getBillingStatus } from 'src/services/billingService';
import { hiddenNavbarPath } from 'src/utils/navbar';
import { hiddenSidebarPath } from 'src/utils/sidebar';

import { navbarKeys } from 'src/components/DashboardLayout/DashboardNavbar/queries';

import useAuth from './JWTContext';

const NAVBAR_HEIGHT = 72;
const BANNER_HEIGHT = 40;

type LayoutMetricsContextType = {
  navbarHeight: number;
  hasDebtorBanner: boolean;
  isNavbarHidden: boolean;
  isSidebarHidden: boolean;
  /** If `false` applies `overflow: hidden` to main layout wrappers. Default: `false` */
  fluid: boolean;
  /** Sets the value for the `fluid` state. */
  setFluid: (fluid: boolean) => void;
};

export const LayoutMetricsContext = createContext<LayoutMetricsContextType>(
  {} as LayoutMetricsContextType,
);

type LayoutMetricsProviderProps = {
  children: React.ReactNode;
};

export const LayoutMetricsProvider = ({
  children,
}: LayoutMetricsProviderProps) => {
  const location = useLocation();
  const isNavbarHidden = hiddenNavbarPath(location.pathname);
  const isSidebarHidden = hiddenSidebarPath(location.pathname);
  const [fluid, setFluid] = useState(false);

  const { instance } = useAuth();

  const { data } = useQuery(
    // TODO: Validate if it's OK to have ! here.
    navbarKeys.billingStatus(instance!.id),
    () => getBillingStatus(instance!.id),
    {
      select: response => response.data,
    },
  );

  const isBannerVisible = !!data?.isDebtor;

  const navbarHeight = isNavbarHidden ? 0 : NAVBAR_HEIGHT;
  const bannerHeight = isBannerVisible ? BANNER_HEIGHT : 0;

  // NPS Feedback metrics
  const { npsModal } = useNpsFeedback();
  const { npsSurveyModal } = useNpsSurvey();

  return (
    <LayoutMetricsContext.Provider
      value={{
        navbarHeight: navbarHeight + bannerHeight,
        hasDebtorBanner: isBannerVisible,
        isNavbarHidden,
        isSidebarHidden,
        setFluid,
        fluid,
      }}
    >
      {children}
      {npsModal}
      {npsSurveyModal}
    </LayoutMetricsContext.Provider>
  );
};

export const useLayoutMetrics = () => {
  const context = useContext(LayoutMetricsContext);

  if (context === undefined) {
    throw new Error(
      'useLayoutMetrics must be used within a LayoutMetricsContext',
    );
  }

  return context;
};
