import {
  createNavigatorFactory,
  TabRouter,
  useNavigationBuilder,
  type DefaultNavigatorOptions,
  type NavigationProp,
  type ParamListBase,
  type TabActionHelpers,
  type TabNavigationState,
  type TabRouterOptions,
} from '@react-navigation/native';
import { withLayoutContext } from 'expo-router';
import type { ImageSourcePropType } from 'react-native';
import TabView, { type AppleIcon } from 'react-native-bottom-tabs';

// Pro-Screen Optionen (kompatibel mit Expo Router's Tabs.Screen API)
export type NativeTabsScreenOptions = {
  title?: string;
  tabBarIcon?: (props: { focused: boolean }) => AppleIcon | ImageSourcePropType;
  tabBarBadge?: string;
  // Expo-Router-Konvention: href === null → Screen NICHT in TabBar zeigen
  href?: string | null;
};

type NativeTabNavigationEventMap = {
  tabPress: { data: undefined; canPreventDefault: true };
  tabLongPress: { data: undefined };
};

// Native-spezifische Tab-Layer-Optionen (iOS 26 Glass-Pill, Haptik, etc.)
type NativeOnlyOptions = {
  sidebarAdaptable?: boolean;
  hapticFeedbackEnabled?: boolean;
  disablePageAnimations?: boolean;
  scrollEdgeAppearance?: 'default' | 'opaque' | 'transparent';
  minimizeBehavior?: 'automatic' | 'onScrollDown' | 'onScrollUp' | 'never';
  tabBarActiveTintColor?: string;
  tabBarInactiveTintColor?: string;
  labeled?: boolean;
  tabLabelStyle?: {
    fontFamily?: string;
    fontWeight?: string;
    fontSize?: number;
  };
};

type Props = DefaultNavigatorOptions<
  ParamListBase,
  string | undefined,
  TabNavigationState<ParamListBase>,
  NativeTabsScreenOptions,
  NativeTabNavigationEventMap,
  NavigationProp<ParamListBase>
> &
  TabRouterOptions &
  NativeOnlyOptions;

function NativeTabsNavigator({
  id,
  initialRouteName,
  children,
  screenOptions,
  layout,
  sidebarAdaptable = true,
  hapticFeedbackEnabled = true,
  disablePageAnimations,
  scrollEdgeAppearance,
  minimizeBehavior,
  tabBarActiveTintColor,
  tabBarInactiveTintColor,
  labeled = true,
  tabLabelStyle,
}: Props) {
  const { state, descriptors, navigation, NavigationContent } =
    useNavigationBuilder<
      TabNavigationState<ParamListBase>,
      TabRouterOptions,
      TabActionHelpers<ParamListBase>,
      NativeTabsScreenOptions,
      NativeTabNavigationEventMap
    >(TabRouter, {
      id,
      initialRouteName,
      children,
      screenOptions,
      layout,
    });

  return (
    <NavigationContent>
      <TabView
        labeled={labeled}
        sidebarAdaptable={sidebarAdaptable}
        hapticFeedbackEnabled={hapticFeedbackEnabled}
        disablePageAnimations={disablePageAnimations}
        scrollEdgeAppearance={scrollEdgeAppearance}
        minimizeBehavior={minimizeBehavior}
        tabBarActiveTintColor={tabBarActiveTintColor}
        tabBarInactiveTintColor={tabBarInactiveTintColor}
        tabLabelStyle={tabLabelStyle}
        navigationState={{
          index: state.index,
          routes: state.routes.map((route) => {
            const options = descriptors[route.key].options;
            return {
              key: route.key,
              title: options.title ?? route.name,
              focusedIcon: options.tabBarIcon
                ? options.tabBarIcon({ focused: true })
                : undefined,
              unfocusedIcon: options.tabBarIcon
                ? options.tabBarIcon({ focused: false })
                : undefined,
              badge: options.tabBarBadge,
              hidden: options.href === null,
            };
          }),
        }}
        onIndexChange={(index) => {
          const route = state.routes[index];
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
            canPreventDefault: true,
          });
          if (!event.defaultPrevented) {
            navigation.dispatch({
              type: 'NAVIGATE',
              payload: { name: route.name, merge: true },
              target: state.key,
            });
          }
        }}
        onTabLongPress={(index) => {
          const route = state.routes[index];
          navigation.emit({
            type: 'tabLongPress',
            target: route.key,
          });
        }}
        renderScene={({ route }) => descriptors[route.key].render()}
      />
    </NavigationContent>
  );
}

export const createNativeTabNavigator = createNavigatorFactory(NativeTabsNavigator);

const NativeTabNav = createNativeTabNavigator();

// withLayoutContext-wrapped Navigator für Expo-Router-Kompatibilität
export const NativeTabs = withLayoutContext(NativeTabNav.Navigator);
