import { StyleFn, useStyles } from "../utils/useStyles"
import * as React from "react"
import { ComponentType } from "react"
import {
  Image,
  ImageStyle,
  StyleProp,
  TouchableOpacity,
  TouchableOpacityProps,
  View,
  ViewStyle,
} from "react-native"
import { scale } from "../theme"

export type IconTypes = keyof typeof iconRegistry

interface IconProps extends TouchableOpacityProps {
  /**
   * The name of the icon
   */
  icon: IconTypes

  /**
   * An optional tint color for the icon
   */
  color?: string

  /**
   * An optional size for the icon. If not provided, the icon will be sized to the icon's resolution.
   */
  size?: number

  /**
   * Style overrides for the icon image
   */
  style?: StyleProp<ImageStyle>

  /**
   * Style overrides for the icon container
   */
  containerStyle?: StyleProp<ViewStyle>

  /**
   * An optional function to be called when the icon is pressed
   */
  onPress?: TouchableOpacityProps["onPress"]
}

/**
 * A component to render a registered icon.
 * It is wrapped in a <TouchableOpacity /> if `onPress` is provided, otherwise a <View />.
 *
 * - [Documentation and Examples](https://github.com/infinitered/ignite/blob/master/docs/Components-Icon.md)
 */
export function Icon(props: IconProps) {
  const { $imageStyle } = useStyles(styles)

  const {
    icon,
    color,
    size,
    style: $imageStyleOverride,
    containerStyle: $containerStyleOverride,
    ...WrapperProps
  } = props

  const isPressable = !!WrapperProps.onPress
  const Wrapper: ComponentType<TouchableOpacityProps> = WrapperProps?.onPress
    ? TouchableOpacity
    : View

  return (
    <Wrapper
      accessibilityRole={isPressable ? "imagebutton" : undefined}
      {...WrapperProps}
      style={$containerStyleOverride}
    >
      <Image
        style={[
          $imageStyle as StyleProp<ImageStyle>,
          color && { tintColor: color },
          size && { width: scale(size), height: scale(size) },
          $imageStyleOverride,
        ]}
        source={iconRegistry[icon]}
      />
    </Wrapper>
  )
}

export const iconRegistry = {
  arActive: require("../../assets/icons/ar-active.png"),
  arInactive: require("../../assets/icons/ar-active.png"),
  back: require("../../assets/icons/back.png"),
  bell: require("../../assets/icons/bell.png"),
  caretLeft: require("../../assets/icons/caretLeft.png"),
  caretRight: require("../../assets/icons/caretRight.png"),
  check: require("../../assets/icons/check.png"),
  community: require("../../assets/icons/community.png"),
  components: require("../../assets/icons/components.png"),
  heart: require("../../assets/icons/heart.png"),
  hidden: require("../../assets/icons/hidden.png"),
  ladybug: require("../../assets/icons/ladybug.png"),
  lock: require("../../assets/icons/lock.png"),
  menu: require("../../assets/icons/menu.png"),
  more: require("../../assets/icons/more.png"),
  pin: require("../../assets/icons/pin.png"),
  settings: require("../../assets/icons/settings.png"),
  settingsActive: require("../../assets/icons/settings-active.png"),
  settingsInactive: require("../../assets/icons/settings-inactive.png"),
  view: require("../../assets/icons/view.png"),
  x: require("../../assets/icons/x.png"),
  brandFacebook: require("../../assets/icons/brand-facebook.png"),
  brandTwitter: require("../../assets/icons/brand-twitter.png"),
  brandGoogle: require("../../assets/icons/brand-google.png"),
  brandInstagram: require("../../assets/icons/brand-instagram.png"),
  brandLinkedin: require("../../assets/icons/brand-linkedin.png"),
  brandWhatsapp: require("../../assets/icons/brand-whatsapp.png"),
  delete: require("../../assets/icons/delete.png"),
  mail: require("../../assets/icons/mail.png"),
  mailAccepted: require("../../assets/icons/mail-accepted.png"),
  changePassword: require("../../assets/icons/change-password.png"),
  smartphone: require("../../assets/icons/smartphone.png"),
  currentLocation: require("../../assets/icons/current-location.png"),
  globe: require("../../assets/icons/globe.png"),
  map: require("../../assets/icons/map.png"),
  search: require("../../assets/icons/search.png"),
  trash: require("../../assets/icons/trash.png"),
  tv: require("../../assets/icons/tv.png"),
  user: require("../../assets/icons/user.png"),
  xCircle: require("../../assets/icons/x-circle.png"),
  chevronDown: require("../../assets/icons/chevron-down.png"),
  bookActive: require("../../assets/icons/book-active.png"),
  bookInactive: require("../../assets/icons/book-inactive.png"),
  homeActive: require("../../assets/icons/home-active.png"),
  homeInactive: require("../../assets/icons/home-inactive.png"),
  emailVerify: require("../../assets/icons/email-verify.png"),
  emailVerified: require("../../assets/icons/email-verified.png"),
  clock: require("../../assets/icons/clock.png"),
  maximize: require("../../assets/icons/maximize.png"),
  capture: require("../../assets/icons/capture.png"),
  compass: require("../../assets/icons/compass.png"),
  line: require("../../assets/icons/line.png"),
  share: require("../../assets/icons/share.png"),
  video: require("../../assets/icons/video.png"),
  videoOff: require("../../assets/icons/video-off.png"),
  shield: require("../../assets/icons/shield.png"),
  list: require("../../assets/icons/list.png"),
  mapPinOutlined: require("../../assets/icons/map-pin-outlined.png"),
  fiMapPin: require("../../assets/icons/fi_map-pin.png"),
  bigArrow: require("../../assets/icons/big-arrow.png"),
  iss: require("../../assets/icons/iss.png"),
  bellRing: require("../../assets/icons/bell-ringing.png"),
  plusCircle: require("../../assets/icons/plus-circle.png"),
  save: require("../../assets/icons/save.png"),
  removeLocation: require("../../assets/icons/remove-location.png"),
  position: require("../../assets/icons/position.png"),
  sun: require("../../assets/icons/sun.png"),
  sunset: require("../../assets/icons/sunset.png"),
  moon: require("../../assets/icons/moon.png"),
  edit: require("../../assets/icons/edit.png"),
  refresh: require("../../assets/icons/refresh.png"),
  calibration: require("../../assets/icons/calibration.png"),
  information: require("../../assets/icons/information.png"),
  trackerActive: require("../../assets/icons/tracker-active.png"),
  trackerInactive: require("../../assets/icons/tracker-inactive.png"),
  tutorial: require("../../assets/icons/tutorial.png"),
}

const styles: StyleFn = () => {
  const $imageStyle: ImageStyle = {
    resizeMode: "contain",
  }

  return { $imageStyle }
}
