import type { Route } from '@react-navigation/native';
import React from 'react';
import {
  type StyleProp,
  StyleSheet,
  type TextStyle,
  View,
  type ViewStyle,
} from 'react-native';

import { Colors } from '../../Consts';
import { Badge, BadgeDot } from '../../Badge';

type Props = {
  route: Route<string>;
  badge?: string | number;
  badgeStyle?: StyleProp<TextStyle> | any;
  activeOpacity: number;
  inactiveOpacity: number;
  activeTintColor?: string;
  inactiveTintColor?: string;
  renderIcon: (props: {
    focused: boolean;
    color: string;
    size: number;
  }) => React.ReactNode;
  allowFontScaling?: boolean;
  style: StyleProp<ViewStyle>;
};

/**
 * Icon sizes taken from Apple HIG
 * https://developer.apple.com/design/human-interface-guidelines/tab-bars
 */
const ICON_SIZE_WIDE = 35;

export function TabBarIcon({
  route: _,
  badge,
  badgeStyle,
  activeOpacity,
  inactiveOpacity,
  activeTintColor,
  inactiveTintColor,
  renderIcon,
  style,
}: Props) {
  const iconSize = 25;

  const renderBadge = () => {
    if (badge == null) {
      return;
    }
    if (badge === '') {
      return <BadgeDot size={'small'} style={[styles.badge, badgeStyle]} />;
    }
    return <Badge style={[styles.badge, badgeStyle]} label={badge} />;
  };

  // We render the icon twice at the same position on top of each other:
  // active and inactive one, so we can fade between them.
  return (
    <View style={[styles.wrapperUikit, style]}>
      <View
        style={[
          styles.icon,
          {
            opacity: activeOpacity,
            // Workaround for react-native >= 0.54 layout bug
            minWidth: iconSize,
          },
        ]}
      >
        {renderIcon({
          focused: true,
          size: iconSize,
          color: activeTintColor ?? Colors.black_20,
        })}
      </View>
      <View style={[styles.icon, { opacity: inactiveOpacity }]}>
        {renderIcon({
          focused: false,
          size: iconSize,
          color: inactiveTintColor ?? Colors.black_04,
        })}
      </View>
      {renderBadge()}
    </View>
  );
}

const styles = StyleSheet.create({
  icon: {
    // We render the icon twice at the same position on top of each other:
    // active and inactive one, so we can fade between them:
    // Cover the whole iconContainer:
    position: 'absolute',
    alignSelf: 'center',
    alignItems: 'center',
    justifyContent: 'center',
    height: '100%',
    width: '100%',
  },
  wrapperUikit: {
    width: ICON_SIZE_WIDE,
    height: ICON_SIZE_WIDE,
  },
  badge: {
    position: 'absolute',
    end: -3,
    top: -3,
  },
});
