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 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 LabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
import LineDrawer from '../Drawer';
import { CAP_SPACE_12, CAP_SPACE_08, FONT_COLOR_05 } from '@capillarytech/cap-ui-library/styled/variables';
import Gallery from '../../../Assets/Gallery';
import style from './style';
import { CAP_G06, CAP_G09 } from '@capillarytech/cap-ui-library/styled/variables';
import withStyles from '../../../../hoc/withStyles';
import { getCdnUrl } from '../../../../utils/cdnTransformation';

import messages from './messages';
import {
  LINE_IMG_HEIGHT,
  LINE_IMG_WIDTH,
  LINE_IMG_SIZE,
  ALLOWED_EXTENSIONS_REGEX,
} from './constants';

export const LineImage = ({
    className,
    id,
    intl: { formatMessage },
    isFullMode,
    inheritedTitleStyle,
    supportedExtensions,
    actions = {},
    Line,
    index,
    updateMessageState,
    content,
    activeKey,
    Templates,
    getAllTemplates,
    uploadedAssetList,
    updateUploadedAssetList,
    deleteUploadedImgList,
}) => {
    if (activeKey !== 'image') {
        return null;
    }

    const [errorMessageTitle, updateErrorMessageTitle] = useState(false);
    const [isCreateNew, updateCreateNew] = useState(isFullMode);
    const [messageTitle, updateTextMessageTitle] = useState('');
    const [isDrawerRequired, updateDrawerRequirement] = useState(false);
    const [isImage, updateImageStatus] = useState(false);
    const [isImageError, updateImageErrorMessage] = useState(false);
    const [imageSrc, updateImageSrc] = useState();
    const [imagePreview, updateImagePreview] = useState();
    const [isTemplateDrawerRequired, updateTemplateDrawerRequirement] = useState(false);
    const [selectedTemplate, updateSelectedTemplate] = useState();

    useEffect(() => {
        const { messageTitle = '', originalContentUrl = '', previewImageUrl = '', type } = content;
        if (originalContentUrl && type === 'image') {
            updateImageStatus(true);
            updateCreateNew(true);
            updateImageSrc(originalContentUrl);
            updateTextMessageTitle(messageTitle);
            updateImagePreview(previewImageUrl);
        }
    }, [content]);

    useEffect(() => {
        if (imageSrc && (isFullMode ? messageTitle: true) && imagePreview) {
                updateMessageState({
                    isError: !imageSrc || !(isFullMode ? messageTitle : true) || isImageError || errorMessageTitle,
                    originalContentUrl: getCdnUrl({url: imageSrc, channelName: 'LINE', channelSubType: 'IMAGE'}),
                    previewImageUrl: imagePreview,
                    messageTitle,
                    index,
                    type: 'image',
                    messageType: 'originalContentUrl',
                });
            }
    }, [errorMessageTitle, imageSrc, messageTitle, isImageError]);

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

    useEffect(() => {
        const imgSrc = get(uploadedAssetList[index], 'imgSrc', '');
        const imgPreview = get(uploadedAssetList[index], 'imgPreview', '');
        const { type } = content;

        if (imgSrc && type === 'image') {
            updateImageSrc(imgSrc);
            updateImageStatus(true);
            updateImagePreview(imgPreview);

            updateMessageState({
                isError: !imgSrc || !(isFullMode ? messageTitle : true) || errorMessageTitle,
                originalContentUrl: getCdnUrl({url: imgSrc, channelName: 'LINE', channelSubType: 'IMAGE'}),
                previewImageUrl: imgPreview,
                messageTitle,
                index,
                type: 'image',
                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) {
            updateImageErrorMessage(formatMessage(messages.lineImageIncorrectSize));
        } else {
            updateImageErrorMessage('');
            data.fileParams.isGeneratePreview = true;
            actions.uploadAsset(
                data.file,
                data.type,
                data.fileParams,
                index,
            );
        }
    }

    const onTextTitleChange = ({ target: { value } }) => {
        updateTextMessageTitle(value);
        let errorMessage = false;
        if (value === '') {
            errorMessage = formatMessage(messages.emptyTitleErrorMessage);
        }
        updateMessageState({
            isError: !imageSrc || !(isFullMode ? value : true) || isImageError || !value,
            originalContentUrl: getCdnUrl({url: imageSrc, channelName: 'LINE', channelSubType: 'IMAGE'}),
            previewImageUrl: imagePreview,
            messageTitle: value,
            index,
            type: 'image',
            messageType: 'originalContentUrl',
        });
        updateErrorMessageTitle(errorMessage);
    }

    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) > 5), // Checking if file exists and its size is greater than 5MB (5 * 10^6 bytes)
            };
            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`}>
            <CapHeading type="label3" style={{ marginBotton: 20, color: 'unset' }}>
                <FormattedMessage {...messages.uploadImageLabel} />
            </CapHeading>
            <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);
        if (!isFullMode) {
            updateCreateNew(false);
        }
        deleteUploadedImgList(index);
        updateImageSrc('');
        updateImagePreview('');
        updateMessageState({
            isError: true,
            originalContentUrl: '',
            previewImageUrl: '',
            messageTitle,
            index,
            type: 'image',
            messageType: 'originalContentUrl',
        });
    }

    const onSelectTemplate = (event) => {
        event.stopPropagation();
        updateTemplateDrawerRequirement(true);
    }

    const getLineImageSection = (isImage) => {
        if (!isCreateNew) {
            return (
            <div className="form-builder-dragger" style={{
                textAlign: 'center',
                border: `1px dashed ${CAP_G06}`,
                minHeight: 120,
                padding: 60
            }}>
                <CapHeader
                    className="choice-title"
                    size="regular"
                    title={formatMessage(messages.textMessageAddLabel)}
                    style={{ marginBottom: 12 }}
                />
                
                <CapButton
                    className="dragger-button create-button"
                    type="secondary"
                    style={{marginRight: CAP_SPACE_08}}
                    onClick={setNewContent}
                    isAddBtn
                >
                    <FormattedMessage {...messages.textMessageCreateNew} />
                </CapButton>

                <CapHeading className="dragger-or" type="label6" style={{ display: 'inline-block' }}>
                    <FormattedMessage {...messages.textMessageORLabel} />
                </CapHeading>

                <CapButton
                    className="dragger-button select-template-button"
                    type="secondary"
                    style={{marginLeft: CAP_SPACE_08}}
                    onClick={onSelectTemplate}
                >
                    <FormattedMessage {...messages.textMessageSelectTemplate} />
                </CapButton>
            </div>);
        } else {
            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.imageDimenstionDescription} />
                    </CapHeading>
                </>);
            }
            return (
                <CapButton
                    className="dragger-button"
                    type="link"
                    style={{
                        top: isFullMode ? 105 : -8,
                        position: 'absolute',
                        right: 20,
                        color: FONT_COLOR_05
                    }}
                    onClick={onReUpload}
                >
                    <FormattedMessage {...messages.imageReUpload} />
                </CapButton>
            );
        }
    }

    const setNewContent = () => updateCreateNew(true);

    const onTemplateSelection = (template) => {
        const originalContentUrl = get(template, 'versions.base.content.messages[0].originalContentUrl', '');
        const previewImageUrl = get(template, 'versions.base.content.messages[0].previewImageUrl', '');
        updateSelectedTemplate(template);
        updateImageSrc(originalContentUrl);
        updateImagePreview(previewImageUrl || originalContentUrl);
        updateImageStatus(true);
        updateTemplateDrawerRequirement(false);
        updateCreateNew(true);
    }

    const getLineImageDrawerContent = () => {
        const lineTextTemplates = Templates.templates;
        if (!lineTextTemplates) {
            return null;
        }

        const cardDataList = [];
        lineTextTemplates.forEach(template => {
            let templateData = {};
            const {
                content: {
                messages: [{
                    originalContentUrl = '',
                }] = [{}],
                } = {},
            } = template.versions.base;
            templateData.url = originalContentUrl;
            templateData.title = template.name;
            templateData.key = template.name;
            templateData.hoverOption = (
                <CapButton onClick={() => onTemplateSelection(template)}>
                    <FormattedMessage {...messages.select} />
                </CapButton>
            );
            if (originalContentUrl) {
                cardDataList.push(templateData);
            }
        });
        return (
        <>
            <CapHeading type="h3" className="drawer-head">
                {formatMessage(messages.lineTemplateImage)}
            </CapHeading>
            <LineDrawer
                getAllTemplates={getAllTemplates}
                cardDataList={cardDataList}
                isDrawer={isTemplateDrawerRequired}
                Templates={Templates}
                searchPlaceholder={formatMessage(messages.searchImages)}
            />
        </>
        );
    };

    const onGalleryImageSelect = (imageTemplate) => {
        const image = get(imageTemplate, 'metaInfo.secure_file_path');
        const imagePreview = get(imageTemplate, 'metaInfo.secure_file_path_preview');
        updateDrawerRequirement(false);
        if (!ALLOWED_EXTENSIONS_REGEX.test(image)) {
            updateImageErrorMessage(formatMessage(messages.lineImageIncorrectSize));
        } else {
            updateImageErrorMessage('');
            updateImageStatus(true);
            updateImageSrc(image);
            updateImagePreview(imagePreview);
            updateMessageState({
                isError: !image || !(isFullMode ? messageTitle : true) || isImageError || errorMessageTitle,
                originalContentUrl: getCdnUrl({url: image, channelName: 'LINE', channelSubType: 'IMAGE'}),
                previewImageUrl: imagePreview,
                messageTitle,
                index,
                type: 'image',
                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}
            />
        </>
        );
    };


    return (
        <div className={className}>
            {
                isFullMode
                ? (
                    <CapInput
                        id={`${id}_input`}
                        onChange={onTextTitleChange}
                        errorMessage={errorMessageTitle}
                        className="image-template-title"
                        style={inheritedTitleStyle || {}}
                        placeholder={formatMessage(messages.textMessageTitlePlaceholder)}
                        defaultValue={messageTitle || ''}
                        value={messageTitle || ''}
                        size="default"
                        label={formatMessage(messages.textMessageTitleLabel)}
                    />
                )
                : null
            }
            <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)}
                <CapDrawer
                    content={getGalleryDrawerContent()}
                    visible={isDrawerRequired}
                    width={430}
                    onClose={() => updateDrawerRequirement(false)}
                />
                <CapDrawer
                    content={getLineImageDrawerContent()}
                    visible={isTemplateDrawerRequired}
                    width={624}
                    onClose={() => updateTemplateDrawerRequirement(false)}
                />
            </form>
        </div>
    )
}

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