import React, {useCallback, useMemo, useRef, useState} from 'react';
import {View, ScrollView, StyleProp, ViewStyle, ImageProps} from 'react-native';
import {useSharedValue, withTiming} from 'react-native-reanimated';
import ActivityIndicator from '@components/ActivityIndicator';
import {Attachment} from '@interfaces/attachments';
import {ScrollEvent} from '@interfaces/generic';
import {windowDimensions} from '@shared/constants';

import {styles, MARGIN_VERTICAL_TOP, MARGIN_VERTICAL_BOTTOM} from './styles';
import {
  BOTTOM_CIRCLES_EXTRA_HEIGHT,
  FADE_ANIMATION_OFF_DURATION,
  FADE_ANIMATION_ON_DURATION,
  SIX_SECONDS,
  SCROLL_EVENT_THROTTLE,
} from './constants';
import {calculateMaxHeight} from './utils';
import AttachmentItem from './components/AttachmentItem';
import Footer from './components/Footer';

export interface MultimediaContainerProps {
  attachments: Attachment[];
  width?: number;
  isComment?: boolean;
  smallWidth?: number;
  multimediaWidth?: number;
  onDeleteImage?: (urlType: string, url: string) => void;
  onDeleteVideo?: (key: string, value: string | number) => void;
  editingPost?: boolean;
  style?: StyleProp<ViewStyle>;
  withAutoPlay?: boolean;
  imageProps?: Omit<ImageProps, 'source'>;
  postId?: number;
}

/**
 * @deprecated Use `_custom/MultimediaContainer` instead
 */
function MultimediaContainer({
  attachments,
  width,
  isComment,
  smallWidth,
  multimediaWidth,
  onDeleteImage,
  onDeleteVideo,
  editingPost,
  style = {},
  withAutoPlay,
  imageProps,
  postId,
}: MultimediaContainerProps) {
  const [activeIndex, setActiveIndex] = useState(0);
  const scrollRef = useRef<ScrollView>(null);
  const fadeAnimation = useSharedValue(0);
  const showingDeleteButton = !!onDeleteImage || !!onDeleteVideo;
  const showingBottomCircles = attachments.length > 1 && !smallWidth;
  const widthScrollView = isComment ? null : width || windowDimensions.width;

  const onNewIndex = useCallback((newIndex: number) => {
    scrollRef.current?.scrollTo({
      x: newIndex * windowDimensions.width,
      animated: false,
    });
  }, []);

  const onMomentumScrollBegin = useCallback(() => {
    fadeAnimation.value = withTiming(1, {
      duration: FADE_ANIMATION_ON_DURATION,
    });
  }, [fadeAnimation]);

  const onScroll = useCallback(
    ({nativeEvent}: ScrollEvent) => {
      const slide = Math.round(
        nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width,
      );
      slide !== activeIndex &&
        slide < attachments.length &&
        setActiveIndex(slide);
    },
    [activeIndex, attachments.length],
  );

  const onMomentumScrollEnd = useCallback(
    () =>
      setTimeout(() => {
        fadeAnimation.value = withTiming(0, {
          duration: FADE_ANIMATION_OFF_DURATION,
        });
      }, SIX_SECONDS),
    [fadeAnimation],
  );

  const maxHeight = useMemo(() => {
    const extraHeight =
      showingBottomCircles && !showingDeleteButton
        ? BOTTOM_CIRCLES_EXTRA_HEIGHT +
          MARGIN_VERTICAL_TOP +
          MARGIN_VERTICAL_BOTTOM
        : 0;
    return (
      calculateMaxHeight({
        attachments,
        isComment,
        ...(smallWidth ? {smallWidth} : {extraHeight}),
      }) || 380
    );
  }, [
    attachments,
    isComment,
    showingBottomCircles,
    showingDeleteButton,
    smallWidth,
  ]);

  return attachments ? (
    attachments.length ? (
      <View style={[!smallWidth && styles.container, {maxHeight}, style]}>
        <ScrollView
          contentContainerStyle={!smallWidth && styles.contentContainerStyle}
          ref={scrollRef}
          style={[
            styles.scrollViewStyle,
            !!widthScrollView && {width: widthScrollView},
          ]}
          horizontal
          onMomentumScrollBegin={onMomentumScrollBegin}
          onMomentumScrollEnd={onMomentumScrollEnd}
          onScroll={onScroll}
          scrollEnabled={attachments.length > 1}
          scrollEventThrottle={SCROLL_EVENT_THROTTLE}
          {...(!smallWidth && {pagingEnabled: true})}
          showsHorizontalScrollIndicator={!!smallWidth}>
          {attachments.map((item, index) => (
            <AttachmentItem
              key={index}
              item={item}
              index={index}
              multimediaWidth={multimediaWidth}
              width={width}
              onDeleteImage={onDeleteImage}
              smallWidth={smallWidth}
              postId={postId}
              isActive={index === activeIndex}
              attachments={attachments}
              isComment={isComment}
              editingPost={editingPost}
              withAutoPlay={withAutoPlay}
              onDeleteVideo={onDeleteVideo}
              imageProps={imageProps}
            />
          ))}
        </ScrollView>
        <Footer
          showingDeleteButton={showingDeleteButton}
          attachmentsLength={attachments.length}
          index={activeIndex}
          onChangeIndex={setActiveIndex}
          onNewIndex={onNewIndex}
          showingBottomCircles={showingBottomCircles}
          fadeAnimation={fadeAnimation}
        />
      </View>
    ) : (
      <View />
    )
  ) : (
    <ActivityIndicator />
  );
}

export default MultimediaContainer;
