import React, {Component, Fragment} from "react";
import {connect} from "react-redux";
import Timer from 'react-compound-timer';
import classnames from "classnames";
import {
  avatarNameGenerator,
  avatarUrlGenerator,
  filterTalkingCallParticipant,
  isGroup,
  isParticipantVideoTurnedOn,
  isScreenShare,
  isScreenShareOwnerIsMe,
  isVideoCall,
  lastPersonTalking,
  mobileCheck,
  sortCallParticipantsBy
} from "../utils/helpers";

//strings
import strings from "../constants/localization";
import {
  CHAT_CALL_BOX_FULL_SCREEN, CHAT_CALL_BOX_NORMAL,
  CHAT_CALL_STATUS_INCOMING,
  CHAT_CALL_STATUS_STARTED
} from "../constants/callModes";

//actions
import {
  chatCallBoxShowing,
  chatCallGroupSettingsShowing,
  chatCallBoxShowing as chatCallBoxShowingAction,
  chatSelectParticipantForCallShowing,
} from "../actions/chatActions";
import {threadCreateWithExistThread} from "../actions/threadActions";

//components
import CallBoxEqualizer from "./CallBoxEqualizer";
import SelectParticipantForCallFooter from "./_component/SelectParticipantForCallFooter";
import {getImage, getName} from "./_component/contactList";
import Container from "../../../Talk-ui-kit/src/container";
import Avatar, {AvatarImage} from "../../../Talk-ui-kit/src/avatar";
import {Text} from "../../../Talk-ui-kit/src/typography";
import Shape, {ShapeCircle} from "../../../Talk-ui-kit/src/shape";
import {
  MdExpandLess,
  MdFullscreen,
  MdFullscreenExit,
  MdGroup,
  MdPersonAdd,
  MdChatBubbleOutline, MdOutlineGroup, MdOutlineFullscreenExit, MdOutlineFullscreen
} from "react-icons/md";

//styling
import style from "../../styles/app/CallBoxHead.scss";

//statics
window.calltimer = 0;

//functions

@connect(store => {
  return {
    user: store.user.user,
    chatCallStatus: store.chatCallStatus,
    chatCallParticipantList: sortCallParticipantsBy(store.chatCallParticipantList.participants, "id")
  }
})
export default class CallBoxHead extends Component {

  constructor(props) {
    super(props);
    this.onDropCallClick = this.onDropCallClick.bind(this);
    this.onVolumeClick = this.onVolumeClick.bind(this);
    this.onMicClick = this.onMicClick.bind(this);
    this.onFullScreenClick = this.onFullScreenClick.bind(this);
    this.groupSettingView = this.groupSettingView.bind(this);
    this.onAddMember = this.onAddMember.bind(this);
    this.switchBetweenView = this.switchBetweenView.bind(this);
    this.onStartChatClick = this.onStartChatClick.bind(this);
    this.state = {
      volume: true,
      mic: true
    }
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    const {chatCallStatus, chatCallBoxShowing} = this.props;
    const {chatCallStatus: oldChatCallStatus} = prevProps;
    const {status: oldStatus, call: oldCall} = oldChatCallStatus;
    const {status, call} = chatCallStatus;
    if (oldStatus !== status) {
      if (oldStatus === CHAT_CALL_STATUS_STARTED) {
        window.calltimer = 0;
      }
    }

    //If some one or yourself share a screen goto fullscreen mode automatically
    if (status === CHAT_CALL_STATUS_STARTED) {
      if (!isScreenShare(oldCall)) {
        if (isScreenShare(call)) {
          if (chatCallBoxShowing.showing !== CHAT_CALL_BOX_FULL_SCREEN) {
            this.onFullScreenClick();
          }
        }
      }
    }
  }

  onDropCallClick(e) {
    e.stopPropagation();
    const {dispatch} = this.props;
    dispatch(chatCallBoxShowing(false, null, null));
  }

  onVolumeClick(e) {
    e.stopPropagation();
    this.setState({
      volume: !this.state.volume,
    })
  }

  onMicClick(e) {
    e.stopPropagation();
    this.setState({
      mic: !this.state.mic,
    })
  }

  switchBetweenView(e) {
    e.stopPropagation();
  }

  groupSettingView(e) {
    e.stopPropagation();
    this.props.dispatch(chatCallGroupSettingsShowing(true));
  }

  onFullScreenClick(e) {
    e && e.stopPropagation();
    const {dispatch, chatCallBoxShowing} = this.props;
    const {thread, contact} = chatCallBoxShowing;
    dispatch(chatCallBoxShowingAction(chatCallBoxShowing.showing === CHAT_CALL_BOX_FULL_SCREEN ? CHAT_CALL_BOX_NORMAL : CHAT_CALL_BOX_FULL_SCREEN, thread, contact));
  }

  onStartChatClick(e) {
    e.stopPropagation();
    const {dispatch, chatCallBoxShowing, onCallBoxClick} = this.props;
    const {thread} = chatCallBoxShowing;
    dispatch(threadCreateWithExistThread(thread));
    onCallBoxClick();
  }

  onAddMember(e) {
    e.stopPropagation();
    const {chatCallBoxShowing, dispatch} = this.props;
    const {thread} = chatCallBoxShowing;
    return dispatch(chatSelectParticipantForCallShowing({
        thread,
        showing: true,
        selectiveMode: true,
        headingTitle: strings.addMember,
        FooterFragment: SelectParticipantForCallFooter
      },
    ));
  }

  render() {
    const {chatCallStatus, thread, chatCallBoxShowing, user, chatCallParticipantList} = this.props;
    const {status, call} = chatCallStatus;
    const incomingCondition = status === CHAT_CALL_STATUS_INCOMING;
    const callStarted = status === CHAT_CALL_STATUS_STARTED;
    const fullScreenCondition = chatCallBoxShowing.showing === CHAT_CALL_BOX_FULL_SCREEN || mobileCheck();
    const isMobileCondition = mobileCheck();
    const isScreenShareOwnerIsMeResult = (isScreenShare(call) && isScreenShareOwnerIsMe(call.screenShare, user));
    const isVideoCallBool = (isParticipantVideoTurnedOn(call, chatCallParticipantList)) || (isScreenShare(call) && (!isScreenShareOwnerIsMe(call.screenShare, user) || isGroup(thread)));
    const accentTextColorCondition = isVideoCallBool && callStarted ? "accent" : undefined;
    const invertTextColorCondition = (fullScreenCondition && !incomingCondition && !isVideoCallBool) || (isVideoCallBool && fullScreenCondition && !incomingCondition && !callStarted);
    const lastPersonTalkingResult = lastPersonTalking(chatCallParticipantList);
    const chatCallParticipantsTalking = chatCallParticipantList.filter(participant => filterTalkingCallParticipant(participant));
    const personTalkingContainerClassName = classnames({
      [style.CallBoxHead__PersonTalkingContainer]: true,
      [style["CallBoxHead__PersonTalkingContainer--show"]]: isVideoCallBool && lastPersonTalkingResult && lastPersonTalkingResult.audioLevel > 1,
    });

    return <Container className={style.CallBoxHead}>
      <Container className={style.CallBoxHead__StatusContainer}>
        <Text bold
              invert={invertTextColorCondition}
              color={accentTextColorCondition}
              size="sm">{incomingCondition ? strings.ringing(isVideoCall(call)) : callStarted ? strings.callStarted : strings.calling(isVideoCall(call))}</Text>
        {callStarted &&
        <Timer
          formatValue={(value) => `${(value < 10 ? `0${value}` : value)}`}
          initialTime={window.calltimer}>
          {({getTime}) => {
            window.calltimer = getTime();
            return <Text size="xs" invert={invertTextColorCondition} color={accentTextColorCondition} bold>
              <Timer.Minutes/>:<Timer.Seconds/>
            </Text>
          }}
        </Timer>
        }
      </Container>
      <Container className={style.CallBoxHead__StatusIconContainer}>
        {(callStarted && thread) &&
        <Fragment>
          {
            isGroup(thread) ?
              <Container onClick={this.groupSettingView}>
                <MdOutlineGroup size={style.iconSizeMd} color={style.colorAccent}
                                title={strings.showGroupInfo}
                                style={{marginLeft: "10px", cursor: "pointer"}}/>
                {chatCallParticipantsTalking.length > 0 &&
                <Shape className={style.CallBoxHead__GroupIconBadge}
                       color="accent">
                  <ShapeCircle>{chatCallParticipantsTalking.length}</ShapeCircle>
                </Shape>
                }

                {isVideoCallBool &&
                <Container className={personTalkingContainerClassName}>
                  <CallBoxEqualizer participant={lastPersonTalkingResult} customSize={25}
                                    speakerClassName={style.CallBoxHead__EqualizerSpeakerContainer}/>
                  <Avatar>
                    <AvatarImage
                      customSize={25}
                      src={avatarUrlGenerator(getImage(lastPersonTalkingResult), avatarUrlGenerator.SIZES.SMALL)}
                      text={avatarNameGenerator(getName(lastPersonTalkingResult)).letter}
                      textBg={avatarNameGenerator(getName(lastPersonTalkingResult)).color}>
                    </AvatarImage>
                  </Avatar>
                </Container>
                }
              </Container> : <MdPersonAdd size={style.iconSizeMd} color={style.colorAccent}
                                          title={strings.addAPersonToCall}
                                          style={{marginLeft: "10px", cursor: "pointer"}}
                                          onClick={this.onAddMember}/>

          }

        </Fragment>

        }
        {!isMobileCondition && !isScreenShareOwnerIsMeResult &&
        <>
          {
            fullScreenCondition ?
              <MdOutlineFullscreenExit size={style.iconSizeMd} color={style.colorAccent} style={{marginLeft: "7px"}}
                                       title={strings.exitFromFullScreen}
                                       onClick={this.onFullScreenClick}/> :
              <MdOutlineFullscreen size={style.iconSizeMd} color={style.colorAccent} style={{marginLeft: "7px"}}
                                   title={strings.startFullScreen}
                                   onClick={this.onFullScreenClick}/>
          }
        </>
        }

        <MdExpandLess size={style.iconSizeMd} color={style.colorAccent} title={strings.compactCallBox}/>
      </Container>
      {
        (callStarted && chatCallBoxShowing?.thread?.id) &&
        <Container className={style.CallBoxHead__ChatIconContainer}>
          <MdChatBubbleOutline size={style.iconSizeSm} color={style.colorAccent}
                               title={strings.sendAMessage}
                               onClick={this.onStartChatClick}/>
        </Container>
      }


    </Container>
  }
}