import React, { useContext, useEffect, useMemo, useRef } from 'react';
import {
  StackNavigationOptions,
  TransitionPresets,
} from '@react-navigation/stack';
import type { HeaderTitleProps, NavigationOptions } from './types';
import { Colors, Spacing } from '../Consts';
import { Animated, AppState, Platform } from 'react-native';
import {
  MiniAppContext,
  ScreenContext,
  TrackingScopeContext,
} from '../Context';
import { HeaderTitle, TitleCustom } from './Components/HeaderTitle';
import { HeaderBackground } from './Components/HeaderBackground';
import { HeaderLeft } from './Components/HeaderLeft';
import { HeaderRight } from './Components/HeaderRight';

/**
 * default options for stack screen
 */
const getStackOptions = (): StackNavigationOptions => {
  return {
    headerTitleAlign: 'left',
    headerTitle: props => <HeaderTitle {...props} />,
    headerTitleContainerStyle: {
      marginLeft: 0,
      marginEnd: 0,
      marginStart: 0,
      marginHorizontal: 0,
      marginVertical: 0,
      margin: 0,
      left: Spacing.S,
    },
    headerBackground: (props: any) => <HeaderBackground {...props} />,
    headerLeft: (props: any) => <HeaderLeft {...props} />,
    headerRight: (props: any) => <HeaderRight {...props} />,
    headerTintColor: Colors.black_17,
    gestureEnabled: false,
    ...TransitionPresets.SlideFromRightIOS,
  };
};

/**
 * default options for modal screen
 */
const getModalOptions = (): StackNavigationOptions => {
  return {
    headerShown: false,
    headerBackground: undefined,
    cardStyle: { backgroundColor: 'transparent' },
    cardOverlayEnabled: true,
    animation: 'none',
    presentation: 'transparentModal',
  };
};

/**
 * build react-navigation options
 */
const getOptions = (
  params: NavigationOptions,
  animatedValue?: Animated.Value,
) => {
  let options: StackNavigationOptions = {};

  /**
   * left header factory
   */
  if (
    typeof params.onPressLeftHeader === 'function' ||
    typeof params.onBackHandler === 'function' ||
    params.preventBack !== undefined ||
    typeof params.hiddenBack === 'boolean'
  ) {
    let headerLeft: any = (props: any) => (
      <HeaderLeft
        {...props}
        preventBack={params.preventBack}
        onPressLeftHeader={params.onPressLeftHeader}
        onBackHandler={params.onBackHandler}
      />
    );
    if (params.hiddenBack) {
      headerLeft = null;
      options.headerTitleContainerStyle = {
        marginLeft: 0,
        marginEnd: 0,
        marginStart: 0,
        marginHorizontal: 0,
        marginVertical: 0,
        margin: 0,
        left: Spacing.M,
      };
    }
    options = {
      ...options,
      headerLeft,
    };
  }

  /**
   *  title
   */
  if (params.headerTitle) {
    options = {
      ...options,
      ...exportHeaderTitle(params, animatedValue),
    };
  }

  /**
   *  header right
   */
  if (params.headerRight) {
    options = {
      ...options,
      ...{
        headerRight: (props: any) => {
          return <HeaderRight {...props} headerRight={params.headerRight} />;
        },
      },
    };
  }

  return {
    ...params,
    ...options,
  };
};

const exportHeaderTitle = (
  params: NavigationOptions,
  animatedValue?: Animated.Value,
): StackNavigationOptions => {
  if (typeof params.headerTitle === 'object') {
    return {
      headerTitleAlign: 'left',
      headerTitle: (props: any) => {
        return (
          <TitleCustom
            {...props}
            {...(params.headerTitle as HeaderTitleProps)}
            animatedValue={animatedValue}
          />
        );
      },
    };
  } else if (typeof params.headerTitle === 'string') {
    return {
      headerTitle: (props: any) => (
        <HeaderTitle
          {...props}
          children={params.headerTitle}
          animatedValue={animatedValue}
        />
      ),
    };
  }
  return {};
};

const setAutomationID = (accessibilityLabel = '') => {
  if (Platform.OS === 'ios') {
    return {
      accessible: true,
      testID: accessibilityLabel,
      accessibilityLabel: undefined,
    };
  } else {
    return {
      accessibilityLabel,
    };
  }
};

const useComponentId = (componentName: string, accessibilityLabel?: string) => {
  const app = useContext<any>(MiniAppContext);
  const screen = useContext<any>(ScreenContext);
  const { scopeName } = useContext<any>(TrackingScopeContext);

  const scope = scopeName ? `${scopeName}/` : '';

  const componentId = useMemo(() => {
    if (accessibilityLabel) {
      return accessibilityLabel;
    }
    return `${app.appId}/${app.code}/${screen.screenName}/${scope}${componentName}`;
  }, [
    accessibilityLabel,
    app.appId,
    app.code,
    screen.screenName,
    scope,
    componentName,
  ]);

  return { componentId };
};

const useAppState = () => {
  const isBackgroundToForeground = useRef(false);
  const appState = useRef(AppState.currentState);

  useEffect(() => {
    const subscription = AppState.addEventListener('change', nextAppState => {
      isBackgroundToForeground.current = !!(
        appState.current.match(/inactive|background/) &&
        nextAppState === 'active'
      );
      appState.current = nextAppState;

      if (isBackgroundToForeground.current) {
        setTimeout(() => {
          isBackgroundToForeground.current = false;
        }, 100);
      }
    });

    return () => {
      subscription.remove();
    };
  }, []);

  return {
    isBackgroundToForeground: isBackgroundToForeground.current,
    appState: appState.current,
  };
};

export {
  getStackOptions,
  getModalOptions,
  getOptions,
  exportHeaderTitle,
  setAutomationID,
  useComponentId,
  useAppState,
};
