import React, { useState, useEffect } from 'react';
import { injectIntl, FormattedMessage } from 'react-intl';
import get from 'lodash/get';
import CapInput from '@capillarytech/cap-ui-library/CapInput';
import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
import CapUploader from '@capillarytech/cap-ui-library/CapUploader';
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
import CapDrawer from '@capillarytech/cap-ui-library/CapDrawer';
import CapImage from '@capillarytech/cap-ui-library/CapImage';
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
import LabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
import lineImgPlaceholder from '../../../../assets/line-image-placeholder.svg';
import { isUrl } from '../Wrapper/utils';
import { CAP_SPACE_12, CAP_SPACE_08, FONT_COLOR_05, CAP_WHITE, FONT_COLOR_01, CAP_G09, CAP_G08 } from '@capillarytech/cap-ui-library/styled/variables';
import Gallery from '../../../Assets/Gallery';
import style from './style';
import withStyles from '../../../../hoc/withStyles';
import { calculateAspectRatio } from './utils';
import messages from './messages';
import {
  LINE_IMG_HEIGHT,
  LINE_IMG_WIDTH,
  LINE_IMG_SIZE,
  ALLOWED_EXTENSIONS_REGEX,
  URL_ACTION_TYPE,
  TEXT_ACTION_TYPE,
  MAX_ACTION_LABEL_LENGTH,
  CAROUSEL,
} from './constants';

export const LineImageCarouselContent = ({
  id,
  intl: { formatMessage },
  isFullMode,
  supportedExtensions,
  actions = {},
  Line,
  index,
  updateCarouselMessageState,
  content,
  uploadedAssetList,
  updateUploadedAssetList,
  activeIndex,
}) => {
  const [isDrawerRequired, updateDrawerRequirement] = useState(false);
  const [isImageError, updateImageErrorMessage] = useState(false);
  const [imageSrc, updateImageSrc] = useState();
  const [aspectRatio, updateAspectRatio] = useState();
  const [isImage, updateImageStatus] = useState(false);
  const [selectedActionType, updateActionType] = useState('');
  const [actionLabel, updateActionLabel] = useState('');
  const [actionContent, updateActionContent] = useState('');
  const [actionContentErrorMessage, updateActionContentErrorMessage] = useState(false);
  const [actionLabelErrorMessage, updateActionLabelErrorMessage] = useState(false);

  useEffect(() => {
    const {
      originalContentUrl = '',
      type,
      aspectRatio: contentAspectRatio = '',
      selectedActionType = '',
      actionLabel = '',
      actionContent = '',
    } = content;
    if (type === CAROUSEL) {
      updateImageStatus(!!originalContentUrl);
      updateImageSrc(originalContentUrl);
      updateActionType(selectedActionType);
      updateActionLabel(actionLabel);
      updateActionContent(actionContent);
      if (!!contentAspectRatio) updateAspectRatio(contentAspectRatio);
    }
  }, [content]);

  useEffect(() => {
    if (imageSrc) {
      updateCarouselMessageState({
        activeIndex,
        originalContentUrl: imageSrc,
        aspectRatio,
        selectedActionType,
        actionContent,
        actionLabel,
        actionContentErrorMessage,
        actionLabelErrorMessage,
        index,
        type: CAROUSEL,
        messageType: 'originalContentUrl',
      });
    }
  }, [imageSrc, isImageError]);

  useEffect(() => {
    if (Line[`uploadedAssetDataImageCarousel${index}`] && Object.keys(Line[`uploadedAssetDataImageCarousel${index}`]).length) {
      const imgSrc = get(Line, `uploadedAssetDataImageCarousel${index}.metaInfo.secure_file_path`, '');
      if (imgSrc) {
        updateUploadedAssetList({
          ...uploadedAssetList,
          [index]: {
            ...uploadedAssetList[index],
            [activeIndex]: {
              imgSrc,
            }
          },
        });
        actions.clearAsset(`ImageCarousel${index}`);
      }
    }
  }, [Line[`uploadedAssetDataImageCarousel${index}`]]);

  useEffect(() => {
    const imgSrc = get(uploadedAssetList[index], `${activeIndex}.imgSrc`, '');

    if (imgSrc) {
      updateImageSrc(imgSrc);
      updateImageStatus(true);

      updateCarouselMessageState({
        activeIndex,
        isError: !imgSrc,
        originalContentUrl: imgSrc,
        selectedActionType,
        actionContent,
        actionLabel,
        aspectRatio,
        actionContentErrorMessage,
        actionLabelErrorMessage,
        index,
        type: CAROUSEL,
        messageType: 'originalContentUrl',
      });
    }
  }, [uploadedAssetList]);

  const submitAction = (data, incorrectFile) => {
    const {
      file: {
        size,
      },
      fileParams: {
        height,
        width,
      },
      type,
    } = data;
    if (incorrectFile || size > LINE_IMG_SIZE || height > LINE_IMG_HEIGHT || width > LINE_IMG_WIDTH || height > (width * 3)) {
      updateImageErrorMessage(formatMessage(messages.lineImageIncorrectSize));
    } else {
      updateImageErrorMessage('');
      updateAspectRatio(calculateAspectRatio(width, height));
      actions.uploadAsset(
        data.file,
        data.type,
        data.fileParams,
        `ImageCarousel${index}`,
      );
    }
  };

  const uploadImages = (e, { files }) => {
    if (e) {
      e.preventDefault();
    }
    const _URL = window.URL || window.webkitURL;
    let incorrectFile = false;
    const file = files[0];
    if (!ALLOWED_EXTENSIONS_REGEX.test(file.name)) {
      incorrectFile = true;
    }
    const img = new Image();
    img.src = _URL.createObjectURL(file);
    img.onload = () => {
      const fileParams = {
        width: img.width,
        height: img.height,
        error: file && (file.size / (1e+6) > 3),
      };
      submitAction({ file, type: 'image', fileParams }, incorrectFile);
    };
    if (e) {
      const event = e;
      event.target.value = null;
    }
  };

  const capUploaderCustomRequest = (uploadData) => {
    uploadImages(undefined, { files: [uploadData.file] });
  }

  const setDrawerVisibility = (drawervisibleFlag) => updateDrawerRequirement(drawervisibleFlag);

  const onGalleryClick = (event) => {
    event.stopPropagation();
    setDrawerVisibility(true);
  }

  const ImageComponent = (props) => (
    <div key={`${id}_imgComponent`}>
      <CapHeader
        title={formatMessage(messages.uploadImageLabel)}
        description={formatMessage(messages.uploadImageDescription)}
        size="regular"
      />
      <div
        className={`image-container ${props.ifError ? 'error' : ''}`}
        style={{
          marginTop: isImage ? 20 : 8,
          backgroundColor: CAP_G09,
        }}
      >
        {isImage
          ? (
            <CapImage src={imageSrc} alt="line-image-src" style={props.style} height="400" />
          )
          : (
            <div style={{ width: "100%", textAlign: "center" }}>
              <span className="image-placeholder">{props.placeholder}</span>
            </div>
          )
        }
      </div>
    </div>
  );

  const WithLabel = LabelHOC(ImageComponent);

  const onReUpload = () => {
    updateImageStatus(false);
    updateUploadedAssetList({
      ...uploadedAssetList,
      [index]: {
        ...uploadedAssetList[index],
        [activeIndex]: null,
      },
    });
    updateImageSrc('');
    updateCarouselMessageState({
      activeIndex,
      isError: true,
      originalContentUrl: '',
      previewImageUrl: '',
      selectedActionType,
      actionContent,
      actionLabel,
      aspectRatio,
      actionContentErrorMessage,
      actionLabelErrorMessage,
      index,
      type: CAROUSEL,
      messageType: 'originalContentUrl',
    });
  }

  const getLineImageSection = (isImage) => {
    if (!isImage) {
      return (
        <>
          <CapUploader.CapDragger
            customRequest={(data) => capUploaderCustomRequest(data)}
            className="form-builder-dragger"
          >
            <CapHeading className="dragger-title" type="h7">
              <FormattedMessage {...messages.dragAndDrop} />
            </CapHeading>
            <CapHeading className="dragger-or" type="label6">
              <FormattedMessage {...messages.or} />
            </CapHeading>
            <CapButton className="dragger-button" type="secondary" style={{ marginRight: CAP_SPACE_08 }}>
              <FormattedMessage {...messages.uploadComputer} />
            </CapButton>
            <CapButton
              className="dragger-button"
              type="secondary"
              style={{ marginLeft: CAP_SPACE_08 }}
              onClick={onGalleryClick}
            >
              <FormattedMessage {...messages.uploadGallery} />
            </CapButton>
          </CapUploader.CapDragger>
          <CapHeading type="h6" style={{ marginTop: CAP_SPACE_12 }}>
            <FormattedMessage {...messages.imageDimenstionDesc} />
          </CapHeading>
        </>);
    }
    return (
      <CapButton
        className="dragger-button"
        type="link"
        style={{
          top: 0,
          position: 'absolute',
          right: 0,
          color: FONT_COLOR_05,
          padding: 0,
          height: 'min-content',
        }}
        onClick={onReUpload}
      >
        <FormattedMessage {...messages.imageReUpload} />
      </CapButton>
    );
  }

  const onGalleryImageSelect = (imageTemplate) => {
    const image = get(imageTemplate, 'metaInfo.secure_file_path');
    const imageHeight = get(imageTemplate, 'metaInfo.height');
    const imageWidth = get(imageTemplate, 'metaInfo.width');
    const imageSize = get(imageTemplate, 'metaInfo.file_size');
    const calculatedAspectRatio = calculateAspectRatio(imageWidth, imageHeight);
    updateDrawerRequirement(false);
    if (
      !ALLOWED_EXTENSIONS_REGEX.test(image)
      || imageHeight > LINE_IMG_HEIGHT
      || imageWidth > LINE_IMG_WIDTH
      || imageSize > LINE_IMG_SIZE
    ) {
      updateImageErrorMessage(formatMessage(messages.lineImageIncorrectSize));
    } else {
      updateImageErrorMessage('');
      updateImageStatus(true);
      updateImageSrc(image);
      updateAspectRatio(calculatedAspectRatio);
      updateCarouselMessageState({
        activeIndex,
        isError: !image || isImageError,
        originalContentUrl: image,
        aspectRatio: calculatedAspectRatio,
        selectedActionType,
        actionContent,
        actionLabel,
        actionContentErrorMessage,
        actionLabelErrorMessage,
        index,
        type: CAROUSEL,
        messageType: 'originalContentUrl',
      });
    }
  }

  const getGalleryDrawerContent = () => {
    const location = {
      pathname: `/assets`,
      search: '',
      query: !isFullMode ? { type: 'embedded', module: 'library' } : {},
    };
    return (
      <>
        <CapHeading type="h3">
          {formatMessage(messages.imageGallery)}
        </CapHeading>
        <Gallery
          location={location}
          isFullMode={isFullMode}
          isLineAsset
          onGalleryImageSelect={onGalleryImageSelect}
        />
      </>
    );
  };

  const getActionTypes = () => {
    return [TEXT_ACTION_TYPE, URL_ACTION_TYPE].map(type => ({
      value: type,
      label: formatMessage(
        messages[
        type !== URL_ACTION_TYPE ? 'textActionTypeTitle' : 'urlActionTypeTitle'
        ],
      ),
      key: type,
    }));
  }

  const updateActionLabelError = (value) => {
    if (value.length > MAX_ACTION_LABEL_LENGTH) {
      updateActionLabelErrorMessage(formatMessage(messages.maxActionLabelErrorMessage));
      return formatMessage(messages.maxActionLabelErrorMessage);
    } else {
      updateActionLabelErrorMessage();
    }
  }

  const onActionLabelChange = ({ target: { value } }) => {
    updateActionLabel(value);
    const actionLabelErrorMessage = updateActionLabelError(value);
    updateCarouselMessageState({
      activeIndex,
      originalContentUrl: imageSrc,
      selectedActionType,
      actionContent,
      actionLabel: value,
      aspectRatio,
      actionContentErrorMessage,
      actionLabelErrorMessage,
      index,
      type: CAROUSEL,
      messageType: 'originalContentUrl',
    });
  }

  const onActionChange = (type) => {
    updateActionType(type);
    updateActionContent('');
    updateCarouselMessageState({
      activeIndex,
      originalContentUrl: imageSrc,
      selectedActionType: type,
      actionContent: '',
      actionLabel,
      aspectRatio,
      actionContentErrorMessage,
      actionLabelErrorMessage,
      index,
      type: CAROUSEL,
      messageType: 'originalContentUrl',
    });
  }

  const updateActionContentError = (value, passedActionType) => {
    const actionType = passedActionType || selectedActionType;
    if (!value) {
      updateActionContentErrorMessage(formatMessage(messages.emptyActionContentErrorMessage));
      return formatMessage(messages.emptyActionContentErrorMessage);
    } else if (actionType === URL_ACTION_TYPE && !isUrl(value)) {
      updateActionContentErrorMessage(formatMessage(messages.inValidUrliErrorMessage));
      return formatMessage(messages.inValidUrliErrorMessage);
    } else {
      updateActionContentErrorMessage();
    }
  }

  const onActionContentChange = ({ target: { value } }) => {
    updateActionContent(value);
    const actionContentErrorMessage = updateActionContentError(value);
    updateCarouselMessageState({
      activeIndex,
      originalContentUrl: imageSrc,
      selectedActionType,
      actionContent: value,
      actionLabel,
      aspectRatio,
      actionContentErrorMessage,
      actionLabelErrorMessage,
      index,
      type: CAROUSEL,
      messageType: 'originalContentUrl',
    });
  }

  const getActionSection = () => {
    return (
      <>
        <CapInput
          onChange={onActionLabelChange}
          placeholder={formatMessage(messages.actionLabelPlaceholder)}
          value={actionLabel}
          errorMessage={actionLabelErrorMessage}
          label={formatMessage(messages.actionLabelTitle)}
          addonAfter={<span>{actionLabel.length} / ({MAX_ACTION_LABEL_LENGTH})</span>}
          className="action-type-section"
        />
        <CapSelect
          onChange={onActionChange}
          options={getActionTypes()}
          placeholder={formatMessage(messages.actionTypePlaceholder)}
          style={{ width: '100%' }}
          value={selectedActionType}
          label={formatMessage(messages.actionTypeTitle)}
        />
        {
          selectedActionType
            ? (
              <CapInput
                onChange={onActionContentChange}
                placeholder={formatMessage(
                  messages[
                  selectedActionType !== URL_ACTION_TYPE ? 'enterTextActionTypeTitle' : 'enterUrlActionTypeTitle'
                  ],
                )}
                value={actionContent}
                errorMessage={actionContentErrorMessage}
                style={{ marginTop: 12 }}
              />
            )
            : null
        }
      </>
    )
  }

  return (
    <div className="carousel-content">
      <CapRow>
        <CapColumn span="4">
          <div
            style={{
              background: CAP_G08,
              color: FONT_COLOR_01,
              borderRadius: 8,
              position: 'relative',
              height: 'auto',
              overflow: 'initial',
              maxHeight: 'initial',
              minHeight: 120,
              minWidth: 124,
              display: 'flex',
              justifyContent: 'center',
              alignItems: 'center',
              padding: '0 6px',
            }}
          >
            <CapImage
              src={imageSrc || lineImgPlaceholder}
              alt="line-image-src"
              height="40"
              rest={{
                style: {
                  maxWidth: '100%',
                  marginBottom: 5,
                },
              }}
            />
            <span
              style={{
                position: 'absolute',
                bottom: 10,
                background: 'rgba(94, 108, 132, 0.33)',
                borderRadius: '42%',
                padding: '0 12px',
                color: CAP_WHITE,
              }}
            >
              {actionLabel}
            </span>
          </div>
        </CapColumn>
        <CapColumn span="16" offset="4">
          <WithLabel key={`${id}-with-label`} errorMessage={isImageError} ifError={!!isImageError} />
          <form encType="multipart/form-data" id={`${id}_form`}>
            <input
              key={`${id}_imgFile`}
              style={{ display: 'none' }}
              id="fileName"
              type="file"
              onChange={(e) => uploadImages(e, { files: e.target.files })}
              accept={supportedExtensions ? supportedExtensions : "image/*"}
            />
            {getLineImageSection(isImage)}
            {getActionSection()}
            <CapDrawer
              content={getGalleryDrawerContent()}
              visible={isDrawerRequired}
              width={430}
              onClose={() => updateDrawerRequirement(false)}
            />
          </form>
        </CapColumn>
      </CapRow>
    </div>
  )
}

export default injectIntl(withStyles(LineImageCarouselContent, style));