import React, {
  useImperativeHandle,
  useEffect,
  useRef,
  forwardRef,
  useState,
} from 'react';
import {
  findNodeHandle,
  DeviceEventEmitter,
  NativeEventEmitter,
  Platform,
} from 'react-native';
import type {
  ODP_EVENT_LISTENER_TYPE,
  ODP_VIEW_REFERENCE_TYPE,
} from './CommandTypes';
import { CTPEventEmitter } from './MapViewManager';
import { ODP_ON_READY_TYPE } from './schemas/OdpOnReadyType';
import { ODP_ON_KEY_VALIDATION_TYPE } from './schemas/OdpOnKeyValidationType';
import { ODP_ON_NAVIGATION_UPDATE_TYPE } from './schemas/OdpOnNavigationUpdateType';
import { ODP_ON_FACILITY_UPDATE_TYPE } from './schemas/OdpOnFacilityUpdateType';
import { startOdp, stopOdp, uploadLogs } from './SendCommandOdp';
import { OdpViewManager } from './OdpViewManager';

export interface OdpViewProps {
  onOdpEvent: ODP_EVENT_LISTENER_TYPE;
}

const OdpView: React.ForwardRefRenderFunction<
  ODP_VIEW_REFERENCE_TYPE,
  OdpViewProps
> = (
  props: OdpViewProps,
  parentRef: React.Ref<ODP_VIEW_REFERENCE_TYPE> | undefined
) => {
  const nodeRef = useRef(null);
  const [onOdpReadyValue, setOnOdpReadyValue] =
    useState<ODP_ON_READY_TYPE | null>(null);
  const [onKeyValidationValue, setOnKeyValidationValue] =
    useState<ODP_ON_KEY_VALIDATION_TYPE | null>(null);
  const [onNavigationUpdateValue, setOnNavigationUpdateValue] =
    useState<ODP_ON_NAVIGATION_UPDATE_TYPE | null>(null);
  const [onFacilityUpdateValue, setOnFacilityUpdateValue] =
    useState<ODP_ON_FACILITY_UPDATE_TYPE | null>(null);

  useEffect(() => {
    if (onOdpReadyValue != null) props.onOdpEvent.onReady?.(onOdpReadyValue);
  }, [onOdpReadyValue]);
  useEffect(() => {
    if (onKeyValidationValue != null)
      props.onOdpEvent.onKeyValidation?.(onKeyValidationValue);
  }, [onKeyValidationValue]);
  useEffect(() => {
    if (onNavigationUpdateValue != null)
      props.onOdpEvent.onNavigationUpdate?.(onNavigationUpdateValue);
  }, [onNavigationUpdateValue]);
  useEffect(() => {
    if (onFacilityUpdateValue != null)
      props.onOdpEvent.onFacilityUpdate?.(onFacilityUpdateValue);
  }, [onFacilityUpdateValue]);

  useImperativeHandle(parentRef, () => {
    const viewId = findNodeHandle(nodeRef.current);
    const listeners: ODP_VIEW_REFERENCE_TYPE = {
      startOdp: (key: string, host: string, interval_ms: number = 1000) => {
        startOdp(viewId, key, host, interval_ms);
      },
      stopOdp: () => {
        stopOdp(viewId);
      },
      uploadLogs: () => {
        uploadLogs(viewId);
      },
    };
    return listeners;
  });

  useEffect(() => {
    let eventEmitter: typeof DeviceEventEmitter | NativeEventEmitter | null =
      null;
    if (Platform.OS == 'android') {
      eventEmitter = DeviceEventEmitter;
    } else if (Platform.OS == 'ios') {
      eventEmitter = new NativeEventEmitter(CTPEventEmitter);
    }
    eventEmitter?.addListener('ODP_READY', (event: ODP_ON_READY_TYPE) =>
      setOnOdpReadyValue(event)
    );
    eventEmitter?.addListener(
      'ODP_KEY_VALIDATION',
      (event: ODP_ON_KEY_VALIDATION_TYPE) => setOnKeyValidationValue(event)
    );
    eventEmitter?.addListener(
      'ODP_NAVIGATION_UPDATE',
      (event: ODP_ON_NAVIGATION_UPDATE_TYPE) =>
        setOnNavigationUpdateValue(event)
    );
    eventEmitter?.addListener(
      'ODP_FACILITY_UPDATE',
      (event: ODP_ON_FACILITY_UPDATE_TYPE) => setOnFacilityUpdateValue(event)
    );
    return () => {
      eventEmitter?.removeAllListeners('ODP_READY');
      eventEmitter?.removeAllListeners('ODP_KEY_VALIDATION');
      eventEmitter?.removeAllListeners('ODP_NAVIGATION_UPDATE');
      eventEmitter?.removeAllListeners('ODP_FACILITY_UPDATE');
    };
  }, []);

  return <>{OdpViewManager ? <OdpViewManager ref={nodeRef} /> : null}</>;
};

const odpViewFwRef = forwardRef(OdpView);
export default odpViewFwRef;
