import React, { FunctionComponent } from 'react';
import { StyleSheet, View, ViewStyle } from 'react-native';
import { CallState } from '../../../store/webrtc/types';
import { IPbxCall } from '../../../store/pbx/types';
import { IStyledProps } from '../../common/types';
import { Logger } from '../../../utils/Log';
import { MicButton, LoudspeakerButton } from '../CallActionButtons';

const logger = new Logger('PBXCallActions');

interface IProps
  extends IStyledProps<{
    container: ViewStyle;
    actionsContainer: ViewStyle;
  }> {
  call: IPbxCall;
  endCallButton?: Element;
  answerAudioCallButton?: Element;
  dialPadButton?: Element;
  holdButton?: Element;
  retrieveCallButton?: Element;
  voiceMailButton?: Element;
  sessionsCount?: number;
  divertCallButton?: Element;
  swapCallsButton?: Element;
  addNewCallButton?: Element;
  mergeCallsButton?: Element;
  transferCallButton?: Element;
  RejectPbxCallButton?: Element;
}

export const PBXCallActions: FunctionComponent<IProps> = ({
  call,
  endCallButton,
  answerAudioCallButton,
  dialPadButton,
  holdButton,
  retrieveCallButton,
  voiceMailButton,
  divertCallButton,
  swapCallsButton,
  mergeCallsButton,
  transferCallButton,
  addNewCallButton,
  sessionsCount,
  RejectPbxCallButton,
  style,
}) => {

  const {
    callState,
  } = call;
  style = { ...defaultStyle, ...style };
  const isOutgoingCall = callState === CallState.RINGING_OUTGOING;
  const isHeldOrActiveCall =
    callState === CallState.ACTIVE || callState === CallState.HELD;
  const isHeldOrActivePbxCall = isHeldOrActiveCall
  const endCallButtonView =
    endCallButton;

  const answerAudioCallButtonView =
    callState === CallState.RINGING_INCOMING &&
    answerAudioCallButton;
  const micButtonView = (isHeldOrActiveCall || isOutgoingCall) && <MicButton />;
  const loudspeakerButtonView = (isHeldOrActiveCall || isOutgoingCall) && (
    <LoudspeakerButton />
  );
  const dialPadButtonView =
    (isHeldOrActivePbxCall || isOutgoingCall) && dialPadButton;
  const holdButtonView = isHeldOrActivePbxCall && holdButton;
  const retrieveCallButtonView = callState === CallState.HELD  && retrieveCallButton;
  const voiceMailButtonView = callState === CallState.RINGING_INCOMING  && voiceMailButton;
  const RejectPbxCallButtonView = callState === CallState.RINGING_INCOMING && RejectPbxCallButton;
  const addNewCallButtonView = isHeldOrActivePbxCall && addNewCallButton;
  const swapCallsButtonView = isHeldOrActivePbxCall && swapCallsButton;
  const divertCallButtonView = isHeldOrActivePbxCall && divertCallButton;
  const transferCallButtonView =
    (isHeldOrActivePbxCall && isOutgoingCall) && transferCallButton;
  const mergeCallsButtonView = isHeldOrActivePbxCall && mergeCallsButton;

  const updateTransferButton = () => {

    if (sessionsCount === 1) {
      return divertCallButtonView;
    } else {
      return transferCallButtonView;
    }
  };
  const updateNewCallOrBackAndForthButton = () => {
    if (sessionsCount === 1) {
      return addNewCallButtonView;
    } else {
      return swapCallsButtonView;
    }
  };
  const updateHoldOrConferenceButton = () => {
    if (sessionsCount === 1) {
      return holdButtonView;
    } else {
      return mergeCallsButtonView;
    }
  };

  const updateHoldOrEndCallButton = () => {
    if (callState === CallState.RINGING_OUTGOING) {
      return endCallButtonView;
    }
    if (callState === CallState.RINGING_INCOMING) {
      return endCallButtonView;
    }
    if (sessionsCount === 1 && callState === CallState.ACTIVE) {
      return endCallButtonView;
    }
    if (sessionsCount === 1 && callState === CallState.HELD) {
      if (call.isHeldByDistant) {
        logger.info(`call is held by distant?: ${call.isHeldByDistant}`);
        return endCallButtonView;
      } else {
        logger.info(`call is held by distant?: ${call.isHeldByDistant}`);
        return retrieveCallButtonView;
      }
    } else {
      if (callState === CallState.ACTIVE) {
        return endCallButtonView;
      } else {
        return retrieveCallButtonView;
      }
    }
  };
  const updateRejectOrRedirectToVoiceMailButton = () => {
    if (
      callState === CallState.RINGING_INCOMING &&
      call.isVoiceMailAllowed
    ) {
      logger.info(`incomingCall: redirect incoming Call to voicemail`);
      return voiceMailButtonView;
    } else {
      logger.info(`incomingCall: cancel incoming Call `);
      return RejectPbxCallButtonView;
    }
  };



  return (
    <View style={style.container}>
      <View style={style.actionsContainer}>
        {micButtonView}
        {dialPadButtonView}
        {loudspeakerButtonView}
      </View>
      <View style={style.actionsContainer}>
        {updateNewCallOrBackAndForthButton()}
        {updateHoldOrConferenceButton()}
        {updateTransferButton()}
      </View>
      <View style={style.actionsContainer}>
        {answerAudioCallButtonView}
        {updateHoldOrEndCallButton()}
        {updateRejectOrRedirectToVoiceMailButton()}
      </View>
    </View>
  );
};

const defaultStyle = StyleSheet.create({
  container: {
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'space-between',
    zIndex: 99,
  },
  actionsContainer: {
    display: 'flex',
    flexDirection: 'row',
    alignContent: 'center',
    justifyContent: 'space-around',
    zIndex: 99,
    marginTop: 25,
  },
  addVideo: {
    fontSize: 40,
    color: '#ffffff',
  }
});
