import React, {memo, useMemo} from 'react';
import {View, ViewStyle} from 'react-native';
import {
  CustomRendererProps,
  HTMLContentModel,
  HTMLElementModel,
  TBlock,
  useContentWidth,
  useRendererProps,
} from 'react-native-render-html';
import {Video} from '@components/_core/Video';
import {Attachment, AttachmentType} from '@interfaces/attachments';
import {useTheme} from '@shared/theme';

import {ASPECT_RATIO_16_9} from '../../constants';
import {getResizedAndAlignStyle} from '../../utils';
import {
  ASPECT_RATIO_MULTIPLIER,
  DEFAULT_HEIGHT,
  MIN_WIDTH_FOR_TIME_LINE,
} from './constants';
import {styles} from './styles';

export const VideoModel = HTMLElementModel?.fromCustomModel({
  tagName: 'video',
  contentModel: HTMLContentModel.block,
});

function CustomVideoRenderer({tnode}: CustomRendererProps<TBlock>) {
  const {theme} = useTheme();
  const videoProps = useRendererProps('video');
  const contentWidth = useContentWidth();
  const shouldResizeAndAlign: boolean = videoProps.resizeAndAlignMultimedia;

  const videoStyle = useMemo(() => {
    const backgroundColor = theme.background.layout.tertiary;
    if (shouldResizeAndAlign) {
      const style = getResizedAndAlignStyle(
        tnode,
        contentWidth,
        ASPECT_RATIO_16_9,
      );

      if (style?.width) {
        return {
          ...style,
          minHeight: undefined,
          backgroundColor,
        };
      }
    }

    // We multiply the height by 1.1 because if not, some iOS devices don't show the "View full screen" video control
    return {
      height:
        Number(tnode.attributes.height || DEFAULT_HEIGHT) *
        ASPECT_RATIO_MULTIPLIER,
      backgroundColor,
    };
  }, [
    tnode,
    contentWidth,
    shouldResizeAndAlign,
    theme.background.layout.tertiary,
  ]);

  const videoWrapperStyle: ViewStyle | undefined = useMemo(() => {
    if (shouldResizeAndAlign && 'width' in videoStyle) {
      return {
        alignSelf: videoStyle.alignSelf,
        width: videoStyle.width,
        position: 'relative',
      };
    }
    return undefined;
  }, [shouldResizeAndAlign, videoStyle]);

  const source: Nullable<Attachment> = useMemo(() => {
    const attachment: Attachment = {
      url: '',
      type: AttachmentType.VIDEO,
      size: null,
    };

    if (tnode.children.length > 0) {
      const node = tnode.children[0];

      if (node.tagName === 'source') {
        attachment.url = node.attributes.src;
        return attachment;
      }
    }

    if (tnode.attributes.src) {
      attachment.url = tnode.attributes.src;
      return attachment;
    }

    return null;
  }, [tnode.attributes.src, tnode.children]);

  return (
    <View
      style={[
        styles.container,
        'width' in videoStyle && {width: contentWidth},
      ]}>
      {source && (
        <View style={videoWrapperStyle}>
          <Video
            video={source}
            style={[styles.video, videoStyle]}
            videoStyle={styles.video}
            width={contentWidth}
            withCustomControls={videoProps.hasCustomVideoControl}
            withAuthHeader
            showTimeLine={
              !('width' in videoStyle) ||
              (typeof videoStyle.width === 'number' &&
                videoStyle.width >= MIN_WIDTH_FOR_TIME_LINE)
            }
            forceMuted={false}
          />
        </View>
      )}
    </View>
  );
}

export default memo(CustomVideoRenderer);
