import React, { useState, useEffect, useReducer } 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 CapHeader from '@capillarytech/cap-ui-library/CapHeader';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
import CapDrawer from '@capillarytech/cap-ui-library/CapDrawer';
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
import CapImage from '@capillarytech/cap-ui-library/CapImage';
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
import CapDivider from '@capillarytech/cap-ui-library/CapDivider';
import CapError from '@capillarytech/cap-ui-library/CapError';
import CapRadioGroup from '@capillarytech/cap-ui-library/CapRadioGroup';
import { CAP_SPACE_12, CAP_SPACE_16, CAP_SPACE_20, CAP_SPACE_28, CAP_SPACE_08, FONT_COLOR_05,  FONT_WEIGHT_MEDIUM } from '@capillarytech/cap-ui-library/styled/variables';
import Gallery from '../../../Assets/Gallery';
import style from './style';
import withStyles from '../../../../hoc/withStyles';
import TEMPLATES_JSON from './templates.json';
import { isUrl } from '../Wrapper/utils'
import LineDrawer from '../Drawer';
import messages from './messages';
import {
  LINE_ASSET_WIDTH,
  LINE_ASSET_HEIGHT,
  MAX_ALLOWED_TITLE_LENGTH,
  CUSTOM_ASSET_TYPE,
  DEFAULT_ASSET_TYPE,
  DEFAULT_TEMPLATES,
  CUSTOM_TEMPLATES,
  LINE_CUSTOM_ASSET_HEIGHT_MIN,
  LINE_CUSTOM_ASSET_HEIGHT_MAX
} from './constants';
import {
  IMAGE_MAP
} from '../constants';

const { CapIconAvatar } = CapIcon;
import { getCdnUrl } from '../../../../utils/cdnTransformation';

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

    //base image
    const [imageSrc, updateImageSrc] = useState('');
    //selected template
    const [imageMapTemplate, updateImageMapTemplate] = useState();
    //action links
    const [actionLinks, updateActionLinks] = useState({});
    //base size
    const [baseSize, updateBaseSize] = useState({});
    //template name
    const [messageTitle, updateMessageTitle] = useState('');
    //asset type
    const [assetType, updateAssetType] = useState(DEFAULT_ASSET_TYPE);

    const [isCreateNew, updateCreateNew] = useState(isFullMode);
    const [errorMessageTitle, updateErrorMessageTitle] = useState(false);
    const [isDrawerRequired, updateDrawerRequirement] = useState(false);
    const [isImage, updateImageStatus] = useState(false);
    const [isImageError, updateImageErrorMessage] = useState(false);
    const [templateSchema, updateTemplateSchema] = useState([]);
    const [isTemplateDrawerRequired, updateTemplateDrawerRequirement] = useState(false);
    const [altText, updateTitle] = useState('');
    const [errorTitle, updateErrorTitle] = useState(false);

    useEffect(() => {
        const { messageTitle = '',
                type,
                baseUrl,
                baseSize = {},
                selectedTemplate,
                assetType,
                actionLinks = {},
                altText,
              } = content;
        if ( baseUrl && type === IMAGE_MAP) {
            updateImageStatus(true);
            updateCreateNew(true);
            updateImageSrc(baseUrl);
            updateMessageTitle(messageTitle);
            updateImageMapTemplate(selectedTemplate);
            updateAssetType(assetType);
            updateActionLinks(actionLinks);
            updateTemplateSchema(TEMPLATES_JSON[selectedTemplate]);
            updateBaseSize(baseSize);
            updateTitle(altText);
        }
    }, [content]);

    useEffect(() => {
        if (imageSrc && (isFullMode ? messageTitle: true) && imageMapTemplate && actionLinks) {
                updateMessageState({
                    isError: !imageSrc || !(isFullMode ? messageTitle : true)  || !imageMapTemplate || (isImageError && errorMessageTitle) || errorTitle || !altText,
                    baseUrl: getCdnUrl({url: imageSrc, channelName: 'LINE', channelSubType: 'RICH_MESSAGE'}),
                    messageTitle,
                    index,
                    type: IMAGE_MAP,
                    messageType: 'actions',
                    baseSize,
                    messageContent: getActions(),
                    selectedTemplate: imageMapTemplate,
                    assetType,
                    actionLinks,
                    altText,
                });
            }
    }, [errorMessageTitle, imageSrc, messageTitle, isImageError, imageMapTemplate, actionLinks, assetType, isImage, templateSchema, altText]);

    useEffect(() => {
        const imgSrc = get(Line, `uploadedAssetData${index}`, false);
        if (imgSrc && typeof imgSrc !== 'object') {
            updateUploadedAssetList({
                ...uploadedAssetList,
                [index]: {
                    imgSrc: imgSrc.slice(0, -5),
                },
            });
            actions.clearAsset(index);
        }
    }, [Line[`uploadedAssetData${index}`]]);

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

        if (imgSrc) {
            updateImageSrc(imgSrc);
            updateImageStatus(true);
        }
    }, [uploadedAssetList]);

    const getActions = () => {
      const actionsMap = [];
      const isCustom = assetType === CUSTOM_ASSET_TYPE;
      console.log("getActions", templateSchema)
      templateSchema.forEach(template => {
        let { label, errorMessage, ...rest } = template;
        const linkUri = actionLinks[label];
        if(isCustom) {
          rest = {...rest, ...baseSize};
        }
         console.log("getActions", linkUri, template, label, actionLinks, actionLinks[label])
        if(linkUri) {
          actionsMap.push({
            type: 'uri',
            linkUri,
            area: rest
          });
        }
      });
      return actionsMap;
    }

    const submitAction = (data, incorrectFile) => {
        const {
            file: {
                size,
            },
            fileParams: {
                height,
                width,
            },
            type,
        } = data;
        const validWidth = width === LINE_ASSET_WIDTH;
        const isCustom = assetType === CUSTOM_ASSET_TYPE;
        const validHeight = isCustom ? ( LINE_CUSTOM_ASSET_HEIGHT_MIN <= height && height <= LINE_CUSTOM_ASSET_HEIGHT_MAX) : height === LINE_ASSET_HEIGHT;
        if (isCustom) {
            data.fileParams.assetType = CUSTOM_ASSET_TYPE;
        }
        if (incorrectFile || !validWidth || !validHeight) {
            updateImageErrorMessage(formatMessage(messages.lineImageMapIncorrectSize));
        } else {
            updateImageErrorMessage('');
            data.fileParams.isGeneratePreview = true;
            updateBaseSize({
              height,
              width
            });
            actions.uploadAsset(
                data.file,
                data.type,
                data.fileParams,
                index,
            );
        }
    }

    const onTextTitleChange = ({ target: { value } }) => {
        updateMessageTitle(value);
        let errorMessage = false;
        if (value === '') {
            errorMessage = formatMessage(messages.emptyTitleErrorMessage);
        }
        updateErrorMessageTitle(errorMessage);
    }

    const onTitleChange = ({ target: { value } }) => {
        updateTitle(value);
        let errorMessage = false;
        if (value === '') {
            errorMessage = formatMessage(messages.emptyAltTextErrorMessage);
        }
        updateErrorTitle(errorMessage);
    }

    const uploadImages = (e, {files}) => {
        if (e) {
            e.preventDefault();
        }
        const _URL = window.URL || window.webkitURL;
        let incorrectFile = false;
        const file = files[0];
        if (supportedExtensions) {
            const allowedExtensions = /(\.bmp|\.jpeg|\.png|\.gif|\.avif|\.jpg)$/i;
            if (!allowedExtensions.exec(file.name)) {
                incorrectFile = true;
            }
        }
        const img = new Image();
        img.src = _URL.createObjectURL(file);
        img.onload = () => {
            const fileParams = {
                width: img.width,
                height: img.height,
            };
            submitAction({file, type: 'line', fileParams}, incorrectFile);
        };
        if (e) {
            const event = e;
            event.target.value = null;
        }
    };

    const changeAssetType = (event) => {
        event.stopPropagation();
        updateAssetType(event.target.value);
    }

    const getDrawerContent = () => {
        return (
            <>
                <CapRadioGroup 
                    defaultValue={DEFAULT_ASSET_TYPE}
                    value={assetType}
                    onChange={changeAssetType}
                    style={{fontWeight: FONT_WEIGHT_MEDIUM}}
                    options={[
                        {
                            label: 'Square',
                            value: DEFAULT_ASSET_TYPE
                        },
                        {
                            label: 'Custom',
                            value: CUSTOM_ASSET_TYPE
                        }
                    ]}
                />
                <CapLabel type="label1" style={{paddingTop: CAP_SPACE_12}}>
                  {
                    assetType === DEFAULT_ASSET_TYPE ? formatMessage(messages.squareAssetDesc) : formatMessage(messages.customAssetDesc)
                  }
                </CapLabel>
                <CapRow>
                    {getTemplatesSelection()}
                </CapRow>
            </>
        );
    }

    const getTemplatesSelection = () => {
        const isDefaultAssetType = assetType === DEFAULT_ASSET_TYPE ;
        const templatesList = isDefaultAssetType ? DEFAULT_TEMPLATES : CUSTOM_TEMPLATES;
        return (
            <>
                {templatesList.map(template => {
                    const imageSrc = imageMapTemplate === template ? require(`./assets/selected/${template}.png`) : require(`./assets/templates/${template}.png`);
                    return (
                        <CapColumn span={12} key={template}>
                        <CapButton
                            type="flat"
                            style={{ padding: 0, marginTop: CAP_SPACE_12, marginRight: CAP_SPACE_16, height: 'auto' }}
                            onClick={() => changeImageMapTemplate(template)}
                        >
                            <CapImage
                                src={imageSrc}
                                rest={{
                                    height: isDefaultAssetType ? 260 : 520,
                                    width: 260,
                                    onMouseOut: e => (e.currentTarget.src = imageSrc),
                                    onMouseOver: e => (e.currentTarget.src = require(`./assets/hover/${template}.png`))
                                }}
                            />
                        </CapButton>
                    </CapColumn>
                    );
                })}
            </>
        )
    }

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

    const changeImageMapTemplate = (template) => {
        updateImageMapTemplate(template);
        updateTemplateSchema(TEMPLATES_JSON[template]);
        setDrawerVisibility(false);
    }

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

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

    const onReUpload = () => {
        updateImageStatus(false);
        deleteUploadedImgList(index);
        updateImageSrc('');
    }

    const getImageSection = (isImage) => {
        if (!isImage) {
            return (
            <>
                <CapUploader.CapDragger
                    customRequest={(data) => capUploaderCustomRequest(data)}
                    className="form-builder-dragger"
                    disabled={!imageMapTemplate}
                >
                    <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}} disabled={!imageMapTemplate}>
                        <FormattedMessage {...messages.uploadComputer} />
                    </CapButton>
                </CapUploader.CapDragger>
                <CapLabel type="label9" style={{marginTop: CAP_SPACE_12 }}>
                    {formatMessage(messages.imageDimenstionDescription, {dimensions: assetType === DEFAULT_ASSET_TYPE ? '1040 X 1040 px' : '1040 X 520 - 2080 px'})}
                </CapLabel>
                <CapDivider />
            </>);
        }
        return (
          <>
            <CapImage className="base-image-preview" src={`${imageSrc}/1040`} />
            <CapLabel type="label9" style={{marginTop: CAP_SPACE_12 }}>
              {formatMessage(messages.imageDimenstionDescription, {dimensions: assetType === DEFAULT_ASSET_TYPE ? '1040 X 1040 px' : '1040 X 520 - 2080 px'})}
            </CapLabel>
            <CapDivider />
          </>
        );
    }

    const templatePreviewLayout = () => {
        return (
        <>
            <div className="imagemap-preview-container">
                {
                    !imageMapTemplate && <CapLabel type="label11" className="select-template-desc">
                        <FormattedMessage {...messages.selectTemplateDesc} />
                    </CapLabel>
                }
                {
                    imageMapTemplate && <CapImage className="template-preview" src={require(`./assets/templates_with_alphabets/${imageMapTemplate}.png`)} />
                }
                {
                    imageSrc && <CapImage className="image-preview" src={`${imageSrc}/1040`}  width={122} height={122}/>
                }
            </div>
            <CapButton
                className="select-template"
                type="secondary"
                style={{minWidth: 'fit-content', padding: '0.25rem'}}
                onClick={onSelectTemplateClick}
            >
                <FormattedMessage {...messages.textMessageSelectTemplate} />
            </CapButton>
        </>
        );
    }

    const changeLinkUrls = (value, label, index) => {
      console.log("changeLinkUrls", value, label, index)
      if(!isUrl(value) && value !== "") {
        templateSchema[index].errorMessage = formatMessage(messages.validUrl);
        updateTemplateSchema(templateSchema);
      } else {
        templateSchema[index].errorMessage = '';
        updateTemplateSchema(templateSchema);
      }
      actionLinks[label] = value;
      updateActionLinks({...actionLinks}); 
    }

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

    const templateLinksLayout = () => {
      return (
        <>
          <CapHeader 
            size="label1"
            title={formatMessage(messages.linkUrl)}
            description={formatMessage(messages.linkDescription)}
            />
          {templateSchema.map((templateDetails, index) => {
            const { label, errorMessage = '' } = templateDetails;
            return (
              <CapInput
                inline
                label={<CapIconAvatar text={label} width={CAP_SPACE_28} height={CAP_SPACE_28} style={{borderRadius: CAP_SPACE_28}} />}
                labelPosition="left"
                id={`templateLinks${label}`}
                onChange={(event) => changeLinkUrls(event.target.value, label, index)}
                errorMessage={errorMessage}
                defaultValue={actionLinks[label]}
                className="template-links"
                placeholder={formatMessage(messages.linkUrl)}
              />
            )
          })}
        </>
      );
    }

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

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

    const onTemplateSelection = (template) => {
        const baseUrl = get(template, 'versions.base.content.messages[0].baseUrl', '');
        const baseSize = get(template, 'versions.base.content.messages[0].baseSize', '');
        const selectedTemplate = get(template, 'definition.selectedTemplate', '');
        const assetType = get(template, 'definition.assetType', '');
        const altText = get(template, 'versions.base.content.messages[0].altText', '');
        const actionLinks = get(template, 'definition.actionLinks', {});
        updateImageStatus(true);
        updateCreateNew(true);
        updateImageSrc(baseUrl);
        updateTitle(altText);
        updateBaseSize(baseSize);
        updateImageMapTemplate(selectedTemplate);
        updateAssetType(assetType);
        updateActionLinks(actionLinks);
        updateTemplateSchema(TEMPLATES_JSON[selectedTemplate]);
        updateTemplateDrawerRequirement(false);
    }

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

    const getLineImageMapSection = () => {
        if(isCreateNew) {
            return (
                <>
                    <CapHeader
                        title={formatMessage(messages.richMsgHeader)}
                        description={formatMessage(messages.richMsgDesc)}
                        size="label1"
                    />
                    <CapRow className="imagemap-container">
                        <CapColumn span={8}>
                            {templatePreviewLayout()}
                        </CapColumn>
                        <CapColumn span={16}>
                        {isImage &&
                            <CapButton
                            className="dragger-button"
                            type="flat"
                            style={{ top: 180 , position: 'absolute', right: 0, color: FONT_COLOR_05 }}
                            onClick={onReUpload}
                            >
                            <FormattedMessage {...messages.imageReUpload} />
                        </CapButton>}
                        <CapInput.TextArea
                            maxLength={MAX_ALLOWED_TITLE_LENGTH}
                            label={<FormattedMessage {...messages.titleLabel} />}
                            inductiveText={<FormattedMessage {...messages.titleDescription} />}
                            onChange={onTitleChange}
                            value={altText}
                            errorMessage={errorTitle}
                            className="title-textarea"
                        />
                        <CapHeading type="h4">{formatMessage(messages.uploadImageLabel)}</CapHeading>
                        <CapLabel type="label1" style={{paddingTop: CAP_SPACE_12, paddingBottom: CAP_SPACE_08}}>{formatMessage(messages.uploadImageDesc)}</CapLabel>
                        <CapError key={`${id}-with-label`}>{isImageError}</CapError>
                        <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/*"}
                            />
                            {getImageSection(isImage)}
                            <CapDrawer
                                content={getDrawerContent()}
                                title="Select image template - Rich message"
                                visible={isDrawerRequired}
                                width={620}
                                onClose={() => updateDrawerRequirement(false)}
                            />
                        </form>
                        {imageMapTemplate && templateLinksLayout()}
                        </CapColumn>
                    </CapRow>
                </>
            )
        } else {
            return (
                <div className="form-builder-dragger" style={{
                    textAlign: 'center',
                    border: '2px dashed lightgrey',
                    minHeight: 120,
                    padding: 60
                }}>
                <CapHeader
                    className="choice-title"
                    size="regular"
                    title={formatMessage(messages.textMessageAddLabel)}
                    style={{ marginBottom: 12 }}
                />
                
                <CapButton
                    className="create-button"
                    type="secondary"
                    style={{marginRight: CAP_SPACE_08}}
                    onClick={setNewContent}
                >
                    <FormattedMessage {...messages.textMessageCreateNew} />
                </CapButton>

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

                <CapButton
                    className="dragger-button"
                    type="secondary"
                    style={{marginLeft: CAP_SPACE_08}}
                    onClick={onSelectTemplate}
                >
                    <FormattedMessage {...messages.textMessageSelectTemplate} />
                </CapButton>
            </div>);
        }
    }

    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
            }
            {getLineImageMapSection()}
            <CapDrawer
                content={getLineImageMapDrawerContent()}
                visible={isTemplateDrawerRequired}
                width={624}
                onClose={() => updateTemplateDrawerRequirement(false)}
            />
        </div>
    )
}

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