import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {View, Linking} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useNavigation, NavigationProp} from '@react-navigation/native';
import {Spinner} from '@components/_HuGo/Spinner';
import {WebView, WebViewMessageEvent} from '@components/_core/WebView';
import {tokenManager} from '@config/tokens';
import {showSnackbar} from '@redux/dispatchers';
import {useUserId} from '@redux/selectors';
import {AMPLITUDE_EVENTS, Screens} from '@shared/constants';
import {logAmplitudeEvent} from '@shared/utils';
import {HUMAND_URL} from '@shared/keys';
import {useTheme} from '@shared/theme';

import {POST_MESSAGE_TRIGGER_JS} from './constants';
import {styles} from './styles';

interface OrganizationChartProps {
  userId?: number;
  comingFrom?: string;
}

interface WebViewRequest {
  url: string;
}

const PROFILE_PATH = '/profile/';
const IGNORED_URL_PREFIXES = ['about:', 'data:'];

const isIgnoredUrl = (url: string) =>
  IGNORED_URL_PREFIXES.some(prefix => url.startsWith(prefix));

const extractProfileUserId = (pathname: string): number | null => {
  if (!pathname.startsWith(PROFILE_PATH)) return null;
  const parts = pathname.split('/').filter(Boolean);
  const id = parts.length >= 2 ? Number(parts[1]) : NaN;
  return Number.isNaN(id) ? null : id;
};

const openExternalUrl = (url: string) => {
  Linking.canOpenURL(url).then(canOpen => {
    if (canOpen) Linking.openURL(url);
  });
};

export function OrganizationChart({
  userId,
  comingFrom,
}: OrganizationChartProps) {
  const {theme} = useTheme();
  const [isLoading, setIsLoading] = useState(true);
  const currentUserId = useUserId();
  const refreshToken = tokenManager.getRefreshToken();
  const navigation =
    useNavigation<NavigationProp<Record<string, object | undefined>>>();
  const {t} = useTranslation();
  const source = useMemo(
    () => ({
      uri: `${HUMAND_URL}org-chart-mobile/${refreshToken}/${
        userId || currentUserId
      }`,
    }),
    [currentUserId, refreshToken, userId],
  );

  const humandOrigin = useMemo(() => new URL(HUMAND_URL).origin, []);

  const onShouldStartLoadWithRequest = useCallback(
    (request: WebViewRequest) => {
      const {url} = request;
      if (!url || isIgnoredUrl(url)) return false;

      try {
        const parsed = new URL(url, HUMAND_URL);
        const profileUserId = extractProfileUserId(parsed.pathname);

        if (profileUserId !== null) {
          navigation.navigate(Screens.PROFILE, {userId: profileUserId});
          return false;
        }

        if (parsed.origin !== humandOrigin) {
          openExternalUrl(url);
          return false;
        }
      } catch {
        return true;
      }

      return true;
    },
    [navigation, humandOrigin],
  );

  const onMessage = useCallback((event: WebViewMessageEvent) => {
    if (event.nativeEvent.data === 'READY') setIsLoading(false);
  }, []);

  const onError = useCallback(() => {
    showSnackbar({title: t('errors.api.404')});
  }, [t]);

  useEffect(() => {
    if (comingFrom) {
      logAmplitudeEvent(AMPLITUDE_EVENTS.ORG_CHART_VIEW, {comingFrom});
    }
  }, [comingFrom]);

  return (
    <>
      <WebView
        source={source}
        injectedJavaScript={POST_MESSAGE_TRIGGER_JS}
        onMessage={onMessage}
        onError={onError}
        onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
        originWhitelist={['https://*']}
        bounces={false}
      />
      {isLoading && (
        <View style={[styles.spinner, {backgroundColor: theme.white}]}>
          <Spinner />
        </View>
      )}
    </>
  );
}
