/**
*
* CapVideoUpload
*
*/
import React, {
  useCallback, useState, Fragment, useRef, useEffect,
} from 'react';
import PropTypes from "prop-types";
import get from 'lodash/get';
import CapDrawer from '@capillarytech/cap-ui-library/CapDrawer';
import { injectIntl, FormattedMessage, intlShape } from 'react-intl';
import moment from 'moment';
import isEmpty from 'lodash/isEmpty';
import {
  CapHeading,
  CapButton,
  CapError,
  CapUploader,
  CapSpin,
} from '@capillarytech/cap-ui-library';
import messages from './messages';
import {bytes2Size, getDecodedFileName} from '../../utils/common';
import {
  SUPPORTED_FILE_FORMATS, WHATSAPP, DEFAULT, MAX_DURATION, RCS, MOBILEPUSH,
} from './constants';
import './index.scss';
import { VIBER } from '../../v2Containers/CreativesContainer/constants';
import { GIF, VIDEO } from '../../v2Containers/MobilePushNew/constants';

function CapVideoUpload(props) {
  const {
    supportedExtensions,
    allowedExtensionsRegex,
    videoSize,
    intl,
    uploadAsset,
    uploadedAssetList = {},
    style,
    onVideoUploadUpdateAssestList,
    index,
    videoData,
    channel,
    errorMessage,
    showVideoNameAndDuration = true,
    formClassName = 'video-form',
    showReUploadButton = true,
    mediaType = VIDEO.toLowerCase(),
    assetUploading = false, // Add assetUploading prop
    videoSrc: propVideoSrc = '', // Add videoSrc prop for fallback
  } = props;
  const [isVideoError, updateVideoErrorMessage] = useState(false);
  const [isVideo, updateVideoStatus] = useState(false);
  const [videoDuration, updateVideoDuration] = useState(null);
  const [isPlaying, updateIsPlaying] = useState(false);
  const [isSpinning, setSpinning] = useState(false);


  const videoEl = useRef(null);
  const {
    videoSrc: uploadedVideoSrc = '',
    videoName,
    previewUrl,
    videoHeight,
    videoWidth,
    videoId,
    fileHandle = '',
  } = uploadedAssetList;

  // Use uploadedAssetList.videoSrc first, then fall back to prop videoSrc
  // Only use propVideoSrc if uploadedVideoSrc is empty to avoid conflicts with upload logic
  const videoSrc = uploadedVideoSrc || (uploadedVideoSrc === '' ? propVideoSrc : '');

  const [isTemplateDrawerRequired, updateTemplateDrawerRequirement] = useState(false);

  const uploadVideo = useCallback((e, { files }) => {
    if (e) {
      e.preventDefault();
    }
    const _URL = window.URL || window.webkitURL;
    let incorrectFile = false;
    const file = files[0];

    if (!allowedExtensionsRegex.test(file.name)) {
      incorrectFile = true;
    }
    const video = new FileReader();
    video.src = _URL.createObjectURL(file);
    const fileParams = {
      width: video.width,
      height: video.height,
      error: false,
      isGenerateVideoThumbnail: true,
    };
    submitVideoAction({ file, type: mediaType, fileParams }, incorrectFile);
    if (e) {
      const event = e;
      event.target.value = null;
    }
  }, []);

  useEffect(() => {
  }, [videoData, index]);

  useEffect(() => {
    if (!isEmpty(videoData[`uploadedAssetData${index}`])) {
      const {
        metaInfo: {
          secure_file_path: metaVideoSrc = '',
          file_name: metaVideoName = '',
          preview_image_url: previewImgUrl = '',
          video_file_path_preview: videoPreviewUrl = '',
        } = {},
      } = videoData[`uploadedAssetData${index}`] || {};

      const metaVideoId = get(videoData, `uploadedAssetData${index}.videoIdResponse.fbVideo.id`, '');
      const karixFileHandle = get(videoData, `uploadedAssetData${index}.metaInfo.karixFileHandle`, '');
      const hapticFileHandle = get(videoData, `uploadedAssetData${index}.metaInfo.hapticFileHandle`, '');

      if (metaVideoSrc && videoSrc === "") {
        onVideoUploadUpdateAssestList(index, {
          previewUrl: videoPreviewUrl || previewImgUrl,
          videoSrc: metaVideoSrc,
          videoName: metaVideoName,
          videoId: metaVideoId,
          fileHandle: hapticFileHandle || karixFileHandle,
          videoDuration: null,
        });
      }
    }
  }, [videoData, index, videoSrc, onVideoUploadUpdateAssestList]);

  useEffect(() => {
    // Use the assetUploading prop directly for loading state
    setSpinning(assetUploading);
  }, [assetUploading]);


  useEffect(() => {
    if (!isEmpty(uploadedAssetList)) {
      const {
        videoSrc: metaVideoSrc = '',
      } = uploadedAssetList || {};
      if (metaVideoSrc) {
        updateVideoStatus(true);
      } else {
        updateVideoStatus(false);
      }
    } else {
      // When uploadedAssetList is empty, reset video status to show upload interface
      updateVideoStatus(false);
    }
  }, [uploadedAssetList]);

  const submitVideoAction = useCallback((data, incorrectFile) => {
    const {
      file: {
        size,
      },
      file,
      fileParams,
      type,
    } = data;

    if (incorrectFile || size > videoSize) {
      if (errorMessage) {
        updateVideoErrorMessage(errorMessage);
      } else {
        updateVideoErrorMessage(formatMessage(messages.videoIncorrectSize));
      }
    } else {
      updateVideoErrorMessage('');
      uploadAsset(
        file,
        type,
        fileParams,
        index,
      );
    }
  }, [isVideoError]);

  const {
    formatMessage,
  } = intl || {};

  const playVideo = useCallback((e) => {
    if (e.target.paused && !isPlaying) {
      e.target.play();
    }
  }, [isPlaying]);

  const pauseVideo = useCallback((e) => {
    if (!e.target.paused && isPlaying) {
      e.target.pause();
    }
  }, [isPlaying]);

  const onReUpload = useCallback(() => {
    updateVideoStatus(false);
    updateVideoDuration(null);
    onVideoUploadUpdateAssestList(
      index,
      {
        previewUrl: "",
        videoName: "",
        videoHeight: "",
        videoWidth: "",
        videoSrc: "",
        videoDuration: null,
        videoId: "",
        fileHandle: "",
      }
    );
    
    // Reset file input value to allow re-upload of same file
    setTimeout(() => {
      const fileInput = document.getElementById("videoFileName");
      if (fileInput) {
        // eslint-disable-next-line no-param-reassign
        fileInput.value = '';
        fileInput.click();
      }
    }, 100);
  }, [index, onVideoUploadUpdateAssestList]);

  const updateMetadataLoaded = useCallback(() => {
    const { current: { duration, videoHeight: metaVideoHeight, videoWidth: metaVideoWidth } = {} } = videoEl;
    if (duration) {
      updateVideoDuration(duration);
      if (videoWidth === undefined && videoHeight === undefined) {
        if (duration <= MAX_DURATION) {
          onVideoUploadUpdateAssestList(index, {
            videoSrc,
            videoId,
            videoName,
            videoHeight: metaVideoHeight,
            videoWidth: metaVideoWidth,
            previewUrl,
            fileHandle,
            videoDuration: duration,
          });
        } else {
          onReUpload();
          updateVideoErrorMessage(formatMessage(messages.videoDurationError));
        }
      }
    }
  }, [videoSrc, videoId, videoName, previewUrl, fileHandle, videoWidth, videoHeight, index, onVideoUploadUpdateAssestList, formatMessage, onReUpload]);

  const videoDurationValue = videoDuration ? moment('1900-01-01 00:00:00').add(videoDuration, 'seconds').format("HH.mm.ss") : '';

  const capUploaderCustomVideoRequest = useCallback((uploadData) => {
    uploadVideo(undefined, { files: [uploadData.file] });
  }, [uploadVideo]);

  const getVideoSection = () => {
    if (!isVideo) {
      return (
        <>
          <CapUploader.CapDragger
            customRequest={(data) => capUploaderCustomVideoRequest(data)}
            className="form-builder-dragger whatsapp-background"
            showUploadList={!isVideoError}
          >
            <CapHeading className="dragger-title" type="h7">
              <FormattedMessage {...messages.dragAndDrop} />
            </CapHeading>
            <CapHeading className="dragger-or" type="label6">
              <FormattedMessage {...messages.or} />
            </CapHeading>
            <CapButton className="dragger-button upload-video" type="secondary">
              <FormattedMessage {...messages.selectFromComputer} />
            </CapButton>
          </CapUploader.CapDragger>
          <CapError type="error" className="upload-video-error">
            {isVideoError}
          </CapError>
        </>
      );
    }

    return (
      <Fragment key={videoSrc}>
        {showReUploadButton && (
          <div style={{ overflow: 'hidden' }}>
            <CapButton
              className="dragger-button video-reupload"
              type="flat"
              onClick={onReUpload}
            >
              <FormattedMessage {...messages.imageReUpload} />
            </CapButton>
          </div>
        )}
        <div className={showVideoNameAndDuration ? 'video-panel' : 'video-panel-wp'}>
          {mediaType === GIF.toLowerCase() ? (
            <img
              width="230"
              src={videoSrc}
              alt="GIF preview"
              className="line-image-src"
              key={`${index}-gif`}
              style={{ maxWidth: '230px', maxHeight: '200px', objectFit: 'contain' }}
            />
          ) : (
            <video
              width="230"
              poster={previewUrl}
              className="line-image-src"
              key={`${index}-video`}
              onLoadedMetadata={updateMetadataLoaded}
              onPlaying={() => updateIsPlaying(true)}
              onPause={() => updateIsPlaying(false)}
              onMouseOver={playVideo}
              onMouseOut={pauseVideo}
              onFocus={playVideo}
              onBlur={pauseVideo}
              ref={videoEl}
            >
              <source src={videoSrc} type="video/mp4" />
              <track kind="captions" />
            </video>
          )}
          {showVideoNameAndDuration && (
            <div className="video-info">
              <CapHeading type="h4">
                {getDecodedFileName(videoName)}
              </CapHeading>
              <CapHeading type="h6">
                {videoDurationValue}
              </CapHeading>
            </div>
          )}
        </div>
      </Fragment>
    );
  };

  const getVideoSizeDescription = () => (
    <CapHeading.CapHeadingSpan type="label2">
      <FormattedMessage
        {...messages.videoSizeDescription}
        values={{ size: bytes2Size(videoSize) }}
      />
    </CapHeading.CapHeadingSpan>
  );

  return (
    <CapSpin spinning={isSpinning}>
      <div style={style} className="cap-custom-video-upload">
        <form encType="multipart/form-data" id="form" className={formClassName}>
          <input
            key={`videoFile-${index}-${isVideo ? 'uploaded' : 'empty'}`}
            style={{ display: 'none' }}
            id="videoFileName"
            type="file"
            onChange={(e) => uploadVideo(e, { files: e.target.files })}
            accept={mediaType === GIF.toLowerCase() ? '.gif' : (supportedExtensions || "video/*")}
          />
          {getVideoSection()}
          <CapDrawer
            visible={isTemplateDrawerRequired}
            width={624}
            onClose={() => updateTemplateDrawerRequirement(false)}
          />
        </form>
        {![WHATSAPP, VIBER, RCS, MOBILEPUSH].includes(channel)
        && (
        <>
          <CapHeading.CapHeadingSpan type="h6" className="video-description">
            <FormattedMessage {...messages.videoRatioDescription} />
          </CapHeading.CapHeadingSpan>
          {' '}
          <CapHeading.CapHeadingSpan type="h6" className="video-description file-format">
            <FormattedMessage {...messages.channelFileFormat} values={{ format: SUPPORTED_FILE_FORMATS[DEFAULT] }} />
          </CapHeading.CapHeadingSpan>
          <CapHeading.CapHeadingSpan type="h6" className="video-description video-details">
            <FormattedMessage {...messages.videoSizeDescription} values={{size: bytes2Size(videoSize)}} />
          </CapHeading.CapHeadingSpan>
        </>
        )}
        {channel === RCS
        && (
          <>
            {getVideoSizeDescription()}
            <CapHeading.CapHeadingSpan type="label2" className="whatsapp-format">
              <FormattedMessage {...messages.channelFileFormat} values={{ format: SUPPORTED_FILE_FORMATS[DEFAULT] }} />
            </CapHeading.CapHeadingSpan>
          </>
        )}
        {channel === WHATSAPP
        && (
        <>
          {getVideoSizeDescription()}
          <CapHeading.CapHeadingSpan type="label2" className="whatsapp-format">
            <FormattedMessage {...messages.channelFileFormat} values={{ format: SUPPORTED_FILE_FORMATS[DEFAULT] }} />
          </CapHeading.CapHeadingSpan>
        </>
        )}
        {channel === VIBER && (
        <>
          {getVideoSizeDescription()}
          <CapHeading.CapHeadingSpan type="label2" className="whatsapp-format">
            <FormattedMessage {...messages.channelFileFormat} values={{ format: SUPPORTED_FILE_FORMATS.VIBER }} />
          </CapHeading.CapHeadingSpan>
          <CapHeading.CapHeadingSpan type="label2" className="video-duration">
            <FormattedMessage {...messages.viberMaxDuration} />
          </CapHeading.CapHeadingSpan>
        </>
        )}
        {channel === MOBILEPUSH
        && (
        <>
          {getVideoSizeDescription()}
          <CapHeading.CapHeadingSpan type="label2" className="whatsapp-format">
            <FormattedMessage {...messages.channelFileFormat} values={{ format: SUPPORTED_FILE_FORMATS.MOBILEPUSH }} />
          </CapHeading.CapHeadingSpan>
          <CapHeading.CapHeadingSpan type="label2" className="video-duration">
            <FormattedMessage {...messages.maxDuration} />
          </CapHeading.CapHeadingSpan>
        </>
        )}

      </div>
    </CapSpin>
  );
}

CapVideoUpload.propTypes = {
  supportedExtensions: PropTypes.any,
  allowedExtensionsRegex: PropTypes.string,
  videoSize: PropTypes.string,
  intl: intlShape,
  showVideoNameAndDuration: PropTypes.bool,
  uploadAsset: PropTypes.func,
  uploadedAssetList: PropTypes.object,
  style: PropTypes.any,
  onVideoUploadUpdateAssestList: PropTypes.func,
  index: PropTypes.number,
  videoData: PropTypes.object,
  channel: PropTypes.string,
  errorMessage: PropTypes.string,
  formClassName: PropTypes.string,
  showReUploadButton: PropTypes.bool,
  mediaType: PropTypes.string,
  assetUploading: PropTypes.bool,
  videoSrc: PropTypes.string,
};

export default injectIntl(CapVideoUpload);
