import React, {useCallback, useMemo, useState} from 'react';
import {LayoutChangeEvent, Pressable, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {IconUsersPlus} from '@tabler/icons-react-native';
import {Button} from '@components/_HuGo';
import {hasVideo, hasScreenShare} from '@modules/calls/utils';
import {useCallState} from '@modules/calls/hooks';
import {useIsInPipMode} from '@modules/calls/store/selectors';

import {FloatingParticipantView} from './components/FloatingParticipantView';
import {ParticipantView} from './components/ParticipantView';
import {ParticipantsDialog} from './components/ParticipantsDialog';
import {CallActionButtons} from './components/CallActionButtons';
import {GridView} from './components/GridView';
import {CallTopBar} from './components/CallTopBar';
import {styles, getContainerStyle, getGridItemPressableStyle} from './styles';

export function CallActiveLayout({onHangupCall}: {onHangupCall: () => void}) {
  const {t} = useTranslation();
  const {top, bottom} = useSafeAreaInsets();
  const isInPipMode = useIsInPipMode();
  const {
    onFloatingViewParticipantSwitch,
    participantInFloatingView,
    participantInSpotlight,
    participantInFloatingViewTrackType,
    showFloatingView,
    allParticipants,
    gridParticipants,
    moreParticipants,
    displayedParticipants,
  } = useCallState();

  const containerStyle = useMemo(
    () => getContainerStyle(top, bottom),
    [top, bottom],
  );
  const gridItemPressableStyle = useMemo(
    () =>
      getGridItemPressableStyle(
        styles.gridItemPressable.bottom + bottom * 0.3,
        styles.gridItemPressable.height + top * 0.1,
      ),
    [bottom, top],
  );
  const [footerHeight, setFooterHeight] = useState(0);
  const [participantsDialogVisible, setParticipantsDialogVisible] =
    useState(false);
  const [topBarVisible, setTopBarVisible] = useState(false);
  const [addParticipantsVisible, setAddParticipantsVisible] = useState(false);

  const showParticipantsDialog = () => setParticipantsDialogVisible(true);
  const hideParticipantsDialog = () => setParticipantsDialogVisible(false);
  const toggleTopBar = () => setTopBarVisible(!topBarVisible);
  const showAddParcipants = () => setAddParticipantsVisible(true);
  const hideAddParcipants = () => setAddParticipantsVisible(false);

  const onFooterLayout = useCallback((event: LayoutChangeEvent) => {
    setFooterHeight(event.nativeEvent.layout.height);
  }, []);

  const renderParticipants = useMemo(
    () =>
      displayedParticipants.map(participant => {
        const isOne = displayedParticipants.length === 1;
        const currentParticipant = isOne ? participantInSpotlight : participant;
        const hasOngoingScreenShare = currentParticipant
          ? hasScreenShare(currentParticipant)
          : false;
        const objectFit = hasOngoingScreenShare ? 'contain' : 'cover';
        const trackType = hasOngoingScreenShare
          ? 'screenShareTrack'
          : 'videoTrack';
        const participantViewKey = trackType + currentParticipant?.userId;

        return (
          <View
            style={styles.participantViewContainer}
            key={participantViewKey}>
            {currentParticipant && (
              <ParticipantView
                key={participantViewKey}
                style={styles.participantView}
                participant={currentParticipant}
                objectFit={objectFit}
                trackType={trackType}
              />
            )}
          </View>
        );
      }),
    [displayedParticipants, participantInSpotlight],
  );

  if (isInPipMode) {
    const remoteParticipant = participantInSpotlight?.isLocalParticipant
      ? participantInFloatingView
      : participantInSpotlight;

    return (
      <View style={styles.container}>
        {remoteParticipant && (
          <ParticipantView
            key={`pip-${remoteParticipant.userId}`}
            style={styles.participantView}
            participant={remoteParticipant}
            objectFit="cover"
            trackType="videoTrack"
          />
        )}
      </View>
    );
  }

  return (
    <View style={containerStyle}>
      {displayedParticipants.length <= 2 ? (
        <View style={styles.participants}>
          {renderParticipants}
          <Pressable onPress={toggleTopBar} style={styles.overlayButton} />
          {showFloatingView && (
            <FloatingParticipantView
              key={participantInFloatingViewTrackType}
              containerStyle={[
                styles.floatingParticipant,
                participantInFloatingView &&
                  !hasVideo(participantInFloatingView) &&
                  styles.cameraDisabled,
              ]}
              participant={participantInFloatingView ?? undefined}
              onPressHandler={onFloatingViewParticipantSwitch}
              trackType={participantInFloatingViewTrackType}
            />
          )}
        </View>
      ) : (
        <>
          <View style={styles.participantViewContainer}>
            <GridView
              participants={gridParticipants}
              moreParticipants={moreParticipants}
              showModal={showParticipantsDialog}
              footerHeight={footerHeight}
            />
            <Pressable onPress={toggleTopBar} style={styles.overlayButton} />
            <Pressable
              onPress={showParticipantsDialog}
              disabled={!moreParticipants.length}
              style={gridItemPressableStyle}
            />
          </View>
        </>
      )}
      <View>
        <CallActionButtons
          onHangupCall={onHangupCall}
          onLayout={onFooterLayout}
          addParticipants={addParticipantsVisible}
          onCloseAddParticipants={hideAddParcipants}
        />
      </View>
      {participantsDialogVisible && (
        <ParticipantsDialog
          onClose={hideParticipantsDialog}
          isVisible={participantsDialogVisible}>
          <Button
            style={styles.addButton}
            text={t('calls.add_people')}
            IconLeft={IconUsersPlus}
            onPress={showAddParcipants}
          />
        </ParticipantsDialog>
      )}
      {topBarVisible && (
        <CallTopBar
          showModal={showParticipantsDialog}
          participantsCount={allParticipants.length}
        />
      )}
    </View>
  );
}
