import { UIManager, Platform, Image, ImageSourcePropType } from 'react-native';
import {
  JIBESTREAM_STYLE,
  MAP_CREDENTIALS,
  MAP_IMAGE,
  MAP_OPTIONS,
} from './JibestreamTypes';
import { COORDINATE_TYPE } from './CommandTypes';

interface MapViewManagerCommandMappings {
  create: number | string;
  center: number | string;
  setMapVenue: number | string;
  centerMapOnPoint: number | string;
  setFollowBlueDot: number | string;
  setUserPosition: number | string;
  setUserPositionXY: number | string;
  clearWayfindingPath: number | string;
  wayfindToWaypoint: number | string;
  wayfindBetweenWaypoints: number | string;
  drawNavigationPath: number | string;
  styleUnitsForDestination: number | string;
  styleShape: number | string;
  addMapIcon: number | string;
  startOdp: number | string;
  stopOdp: number | string;
  uploadLogs: number | string;
}

let MapViewManagerCommands: MapViewManagerCommandMappings = {
  create: 1,
  center: 2,
  setMapVenue: 3,
  centerMapOnPoint: 4,
  setFollowBlueDot: 5,
  setUserPosition: 6,
  setUserPositionXY: 7,
  clearWayfindingPath: 8,
  wayfindToWaypoint: 9,
  wayfindBetweenWaypoints: 10,
  drawNavigationPath: 11,
  styleUnitsForDestination: 12,
  styleShape: 13,
  addMapIcon: 14,
  startOdp: 15,
  stopOdp: 16,
  uploadLogs: 17,
};
if (Platform.OS == 'ios') {
  MapViewManagerCommands = {
    create: 'create',
    center: 'center',
    setMapVenue: 'setMapVenue',
    centerMapOnPoint: 'centerMapOnPoint',
    setFollowBlueDot: 'setFollowBlueDot',
    setUserPosition: 'setUserPosition',
    setUserPositionXY: 'setUserPositionXY',
    clearWayfindingPath: 'clearWayfindingPath',
    wayfindToWaypoint: 'wayfindToWaypoint',
    wayfindBetweenWaypoints: 'wayfindBetweenWaypoints',
    drawNavigationPath: 'drawNavigationPath',
    styleUnitsForDestination: 'styleUnitsForDestination',
    styleShape: 'styleShape',
    addMapIcon: 'addMapIcon',
    startOdp: 'startOdp',
    stopOdp: 'stopOdp',
    uploadLogs: 'uploadLogs',
  };
}

const createImage = (imageSource: ImageSourcePropType): MAP_IMAGE =>{
  const image = {
    iconSource: imageSource
  };
  return createImageUrl(image);
}

const createImageUrl = (image: MAP_IMAGE): MAP_IMAGE => {
  if(image.iconSource){
    const resolvedImage = Image.resolveAssetSource(image.iconSource);

    if(!image.iconHeight){
      image.iconHeight = 25;
    }

    if(!image.iconWidth){
      image.iconWidth = resolvedImage.width;
    }
    
    
    image.iconUrl = resolvedImage.uri;
    image.iconImage = resolvedImage;
  }

  return image;
};

export const createFragment = (viewId: number | null) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.create.toString(),
    [viewId]
  );

export const centerMap = (
  viewId: number | null,
  rotation: number,
  zoom: number,
  animationDuration: number
) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.center.toString(),
    [rotation, zoom, animationDuration]
  );

export function getRandomInt(max: number) {
  return Math.floor(Math.random() * max);
}

export const setMapVenue = ({
  viewId,
  credentials,
  mapOptions = {},
}: {
  viewId: number | null;
  credentials: MAP_CREDENTIALS;
  mapOptions?: MAP_OPTIONS;
}) => {
  console.log('Setting up Map venue');
  if (mapOptions && mapOptions.user && mapOptions.user?.iconImage)
    mapOptions.user = {
      ...mapOptions.user,
      ...createImage(mapOptions.user.iconImage),
    };

  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.setMapVenue.toString(),
    [credentials, mapOptions]
  );
};

export const addMapIcon = (
  viewId: number | null,
  coordinates: number[],
  coordType: COORDINATE_TYPE,
  icon: MAP_IMAGE
) => {
  const mapIcon = createImageUrl(icon);

  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.addMapIcon.toString(),
    [coordinates, coordType, mapIcon]
  );
};

export const centerMapOnPoint = (viewId: number | null, point: number[]) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.centerMapOnPoint.toString(),
    [point]
  );

export const setFollowBlueDot = (
  viewId: number | null,
  enabled: boolean,
  rotate: boolean = false,
  interval: number = 500
) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.setFollowBlueDot.toString(),
    [enabled, rotate, interval]
  );

export const setUserPosition = (
  viewId: number | null,
  x: number,
  y: number,
  heading: number,
  confidence: number,
  format: string | null
) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.setUserPosition.toString(),
    [x, y, heading, confidence, format]
  );

export const clearWayfindingPath = (viewId: number | null) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.clearWayfindingPath.toString(),
    []
  );

export const wayfindToWaypoint = (viewId: number | null, waypointId: number) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.wayfindToWaypoint.toString(),
    [waypointId]
  );

export const wayfindBetweenWaypoints = (
  viewId: number | null,
  originId: number,
  destinationId: number
) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.wayfindBetweenWaypoints.toString(),
    [originId, destinationId]
  );

export const drawNavigationPath = (
  viewId: number | null,
  pathId: string,
  shouldFocus: boolean,
  style: JIBESTREAM_STYLE,
  originIconUrl?: MAP_IMAGE,
  destinationIconUrl?: MAP_IMAGE
) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.drawNavigationPath.toString(),
    [
      pathId,
      shouldFocus,
      style,
      originIconUrl ? createImageUrl(originIconUrl) : originIconUrl,
      destinationIconUrl
        ? createImageUrl(destinationIconUrl)
        : destinationIconUrl,
    ]
  );

export const styleUnitsForDestination = (
  viewId: number | null,
  destination: number,
  style?: JIBESTREAM_STYLE
) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.styleUnitsForDestination.toString(),
    [destination, style]
  );

export const styleShape = (
  viewId: number | null,
  id: number,
  style: JIBESTREAM_STYLE
) =>
  UIManager.dispatchViewManagerCommand(
    viewId,
    MapViewManagerCommands.styleShape.toString(),
    [id, style]
  );

// export type ImageSourcePropType = ImageURISource | ImageURISource[] | ImageRequireSource | Image;
