/* eslint-disable camelcase */
/* eslint-disable react/jsx-indent */
import React, { useState, useEffect } from 'react';
import { bindActionCreators } from 'redux';
import { createStructuredSelector } from 'reselect';
import { FormattedMessage } from 'react-intl';
import { get, isEmpty } from 'lodash';
import styled from 'styled-components';
import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
import CapAlert from '@capillarytech/cap-ui-library/CapAlert';
import CapInput from '@capillarytech/cap-ui-library/CapInput';
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
import {
  CAP_SPACE_16,
  CAP_SPACE_24,
  CAP_SPACE_32,
  CAP_WHITE,
} from '@capillarytech/cap-ui-library/styled/variables';
import { makeSelectZalo, makeSelectAccount } from './selectors';
import { makeSelectMetaEntities, setInjectedTags, selectMetaDataStatus } from '../Cap/selectors';
import * as zaloActions from './actions';
import './index.scss';
import {
  SUCCESS_ALERT,
  REQUEST,
  EMBEDDED,
  DEFAULT,
  TAG,
  FULL,
  ALL,
  OUTBOUND,
  LIBRARY,
  ERROR_ALERT,
  WARNING_ALERT,
  ZALO_STATUSES,
} from './constants';
import { SMS, ZALO } from '../CreativesContainer/constants';
import messages from './messages';
import globalMessages from '../Cap/messages';
import withCreatives from '../../hoc/withCreatives';
import TagList from '../TagList';
import { validateTags } from '../../utils/tagValidations';
import TemplatePreview from '../../v2Components/TemplatePreview';
import injectSaga from '../../utils/injectSaga';
import injectReducer from '../../utils/injectReducer';
import * as globalActions from '../Cap/actions';
import v2ZaloReducer from './reducer';
import { v2ZaloSagas } from './saga';
import { CapIcon } from '@capillarytech/cap-ui-library';
import { isTagIncluded } from '../../utils/commonUtils';
import TestAndPreviewSlidebox from '../../v2Components/TestAndPreviewSlidebox';
import creativesMessages from '../CreativesContainer/messages';

export const Zalo = (props) => {
  const {
    intl,
    actions,
    isFullMode,
    templateData = {},
    editData = {},
    accountData: { selectedZaloAccount = {}, senderDetails = {} } = {},
    globalActions,
    location,
    getDefaultTags,
    supportedTags,
    metaEntities,
    injectedTags,
    getFormData,
    selectedOfferDetails,
    hostName: zaloHostName = '',
    eventContextTags,
    waitEventContextTags,
    metaDataStatus = "",
    // TestAndPreviewSlidebox props
    showTestAndPreviewSlidebox: propsShowTestAndPreviewSlidebox,
    handleTestAndPreview: propsHandleTestAndPreview,
    handleCloseTestAndPreview: propsHandleCloseTestAndPreview,
  } = props || {};
  // Since zalo supports now multiple accounts, we need to get the hostname from the selected account or passed props.
  const hostName = selectedZaloAccount?.hostName || zaloHostName;
  const { formatMessage } = intl;
  const [oa_id, setOaId] = useState('');
  const [token, setToken] = useState('');
  const [username, setUsername] = useState('');
  const [templateName, setTemplateName] = useState('');
  const [templateId, setTemplateId] = useState('');
  const [templateListParams, setTemplateListParams] = useState([]);
  const [templatePreviewUrl, setTemplatePreviewUrl] = useState('');
  const [showTestAndPreviewSlidebox, setShowTestAndPreviewSlidebox] = useState(false);
  const [templateStatus, setZaloTemplateStatus] = useState(
    ZALO_STATUSES.ENABLE,
  );
  const [tags, updateTags] = useState([]);
  const [textAreaId, updateTextAreaId] = useState('');
  const { zaloTemplateInfoValue = {}, zaloTemplateInfoStatus = REQUEST } =
    editData;
  const {
    _id = '',
    accountId = '',
    zaloAccountId = '',
    accountName = '',
    templateConfigs: { id = '', varMapped = {} } = {},
    token: zaloToken = '',
  } = templateData;
  const zaloTempId = _id || id;
  const ZaloFooter = styled.div`
    background-color: ${CAP_WHITE};
    position: fixed;
    bottom: 0;
    width: 100%;
    margin-left: -32px;
    padding: ${CAP_SPACE_32} ${CAP_SPACE_24};
    z-index: 1;
    
    .ant-btn {
      margin-right: ${CAP_SPACE_16};
    }
    }
`;
  //gets account details
  useEffect(() => {
    if (!isEmpty(selectedZaloAccount) || !isEmpty(templateData)) {
      const {
        sourceAccountIdentifier = '',
        configs: { token: accessToken = '' } = {},
        name = '',
      } = selectedZaloAccount;
      const oaId = getDefaultTags === OUTBOUND ? zaloAccountId : accountId;
      setOaId(sourceAccountIdentifier || oaId);
      setToken(accessToken || zaloToken);
      setUsername(name || accountName);
    }
  }, [selectedZaloAccount, templateData]);

  //gets template details
  useEffect(() => {
    if (zaloTempId && oa_id && token && username && hostName) {
      actions.getTemplateInfoById({
        username,
        oa_id,
        token,
        host: hostName,
        id: zaloTempId,
        actionCallback,
      });
    }
    //cleanup code
    return () => {
      actions.resetTemplateInfoData();
    };
  }, [zaloTempId, oa_id, token, username, hostName]);

  const handleSetValues = (paramsData = []) =>
    paramsData?.map((paramData) => {
      for (const key in varMapped) {
        if (paramData?.name === key) {
          paramData.value = varMapped[key];
        }
      }
      return paramData;
    });

  const setDataForEdit = (setValues) => {
    const {
      name = '',
      _id: zaloId = '',
      versions: {
        base: {
          content: {
            zalo: {
              listParams: paramsData = [],
              previewUrl = '',
              status = '',
            } = {},
          } = {},
        } = {},
      } = {},
    } = zaloTemplateInfoValue;
    setTemplateName(name);
    setTemplateId(zaloId);
    setTemplateListParams(setValues ? handleSetValues(paramsData) : paramsData);
    setTemplatePreviewUrl(previewUrl);
    setZaloTemplateStatus(status);
    updateTextAreaId(paramsData[0]?.name);
  };

  useEffect(() => {
    setDataForEdit(false);
  }, [zaloTemplateInfoValue]);

  useEffect(() => {
    if (!isEmpty(varMapped)) {
      setDataForEdit(true);
    }
  }, [varMapped, zaloTemplateInfoValue]);

  useEffect(() => {
    let tag = get(metaEntities, `tags.standard`, []);
    const { type, module } = location?.query || {};
    if (type === EMBEDDED && module === LIBRARY && !getDefaultTags) {
      tag = supportedTags;
    }
    updateTags(tag);
  }, [metaEntities]);

  useEffect(() => {
    //fetching tags
    const { type, module } = location?.query || {};
    const isEmbedded = type === EMBEDDED;
    const query = {
      layout: SMS,
      type: TAG,
      context: isEmbedded ? module : DEFAULT,
      embedded: isEmbedded ? type : FULL,
    };
    if (getDefaultTags) {
      query.context = getDefaultTags;
    }
    globalActions.fetchSchemaForEntity(query);
  }, []);

  const handleOnTagsContextChange = (data) => {
    const { type } = location?.query || {};
    const isEmbedded = type === EMBEDDED;
    const query = {
      layout: SMS,
      type: TAG,
      context:
        (data || '').toLowerCase() === ALL
          ? DEFAULT
          : (data || '').toLowerCase(),
      embedded: isEmbedded ? type : FULL,
    };
    globalActions.fetchSchemaForEntity(query);
  };

  const onTagSelect = (data) => {
    if (data && textAreaId) {
      const updatedZaloTemplateInfo = templateListParams?.map((listParams) => {
        const { name = '', value = '', minLength = '', maxLength = '' } = listParams;
        if (name === textAreaId) {
          const text = `${value}{{${data}}}`;
          const hasTag = isTagIncluded(text);
          const isLengthError = !hasTag && (text.length <= minLength || text.length > maxLength);
          return {
            ...listParams,
            value: text,
            error: isLengthError
              ? formatMessage(messages.maxMinLengthMessage, {
                  minLength,
                  maxLength,
                })
              : '',
          };
        }
        return listParams;
      });
      setTemplateListParams(updatedZaloTemplateInfo);
    }
  };

  const tagValidationErrorMessage = (message) => {
    const tagValidationResponse =
      validateTags({
        content: message,
        tagsParam: tags,
        location,
        tagModule: getDefaultTags,
        isFullMode,
      }) || {};
    const { isBraceError } = tagValidationResponse;
    if (isBraceError) {
      return formatMessage(globalMessages.unbalanacedCurlyBraces);
    }
    return '';
  };

  //this function is used for checking errror validation in this it validate tags error and length error
  const handleErrorValidation = (e, field) => {
    const { minLength = '', maxLength = '' } = field;
    let error = e ? tagValidationErrorMessage(e) : '';
    
    // Only check length validation if there are no tags in the content
    const hasTag = isTagIncluded(e);
    if (!hasTag && (!e || e.length <= minLength || e.length > maxLength)) {
      error = formatMessage(messages.maxMinLengthMessage, {
        minLength,
        maxLength,
      });
    }
    return error;
  };

  // this function is used for handle form data change in this also handle error validtion on change of value
  const handleFormDataChange = (e, field) => {
    const {
      target: { value },
    } = e;
    const updatedZaloTemplateInfo = templateListParams?.map((listParams) => {
      if (listParams?.name === field?.name) {
        const error = handleErrorValidation(value, field);
        return {
          ...listParams,
          value,
          error,
        };
      }
      return listParams;
    });
    setTemplateListParams(updatedZaloTemplateInfo);
  };

  const renderTextBoxesForListParams = (listParam) => {
    const { name = '', error = '', value = '' } = listParam;
    return (
      <CapInput
        id={`zalo-${name}`}
        onChange={(e) => handleFormDataChange(e, listParam)}
        errorMessage={error}
        placeholder={formatMessage(messages.addVariableWithMessage)}
        defaultValue={value || ''}
        value={value || ''}
        size="default"
        onFocus={() => setTextAreaId(name)}
      />
    );
  };

  const setTextAreaId = (fieldName) => {
    updateTextAreaId(fieldName);
  };

  const getTemplateStatusType = () => {
    switch (templateStatus) {
      case ZALO_STATUSES.ENABLE:
        return SUCCESS_ALERT;
      case ZALO_STATUSES.REJECT:
        return ERROR_ALERT;
      default:
        return WARNING_ALERT;
    }
  };

  const actionCallback = () => {
    CapNotification.error({
      message: formatMessage(messages.zaloFailureNotificationTemplate),
    });
  };

  const isEditDoneDisabled = () => {
    let disableCheck = false;
    templateListParams?.forEach((listParams) => {
      const { error = '', value = '' } = listParams;
      const hasTag = isTagIncluded(value);
      const errorMessage = !error && !hasTag
        ? handleErrorValidation(value, listParams)
        : error;
      if (errorMessage) {
        disableCheck = true;
      }
    });
    return disableCheck;
  };
  const createPayload = () => {
    const varMap = {};
    templateListParams?.forEach((listParam) => {
      const { name = '', value = '' } = listParam;
      varMap[name] = value;
    }
    );
    const payload = {
      channel: ZALO,
      accountId: oa_id,
      ...(getDefaultTags === OUTBOUND && {
        zaloAccountId: oa_id,
      }),
      accountName: username,
      templateConfigs: {
        id: templateId?.toString(),
        name: templateName,
        template: templatePreviewUrl,
        varMapped: varMap,
      },
      token,
    };
    return payload;
  };

  const saveToMessage = () => {
    getFormData({
      value: createPayload(),
      _id: templateId,
      validity: true,
      type: ZALO,
    });
  };

  const renderContent = () =>
    templateListParams?.map((listParam) => {
      const { name = '', value = '', maxLength = '' } = listParam;
      const hasTag = isTagIncluded(value);
      
      return (
        <>
          {renderTextBoxesForListParams(listParam)}
          <CapRow className="variable-field-container">
            <CapLabel className="variable-field-name">
              {formatMessage(messages.variableType, {
                name,
              })}
            </CapLabel>
            <CapLabel className="variable-field-length">
              {!hasTag && (
                formatMessage(messages.charactersCount, {
                  variableLength: value.length,
                  maxLength,
                })
              )}
            </CapLabel>
          </CapRow>
        </>
      );
    });

  const hasTag = templateListParams?.some((listParam) => {
    const { value = '' } = listParam;
    const isTagAvailable = isTagIncluded(value);
    return isTagAvailable;
  });

  // Get template content for Test and Preview
  // This function returns data for both preview and payload building
  const getTemplateContent = () => {
    // Build varMapped from templateListParams
    const varMapped = templateListParams?.reduce((acc, param) => {
      if (param?.name) {
        acc[param.name] = param.value || '';
      }
      return acc;
    }, {});

    return {
      // Preview structure (for ZaloPreviewContent component)
      templatePreviewUrl,
      templateStatus,
      templateName,
      templateListParams, // For tag extraction
      templateConfigs: {
        id: templateId?.toString(),
        name: templateName,
        template: templatePreviewUrl,
        varMapped,
      },
      // Payload fields (for test message API)
      accountId: oa_id || selectedZaloAccount?.oa_id || '',
      accountName: username || selectedZaloAccount?.username || '',
      token: token || selectedZaloAccount?.token || '',
      templateId: templateId?.toString() || '',
      varMapped,
      domainGatewayMapId: selectedZaloAccount?.domainGatewayMapId || 0,
      domainId: selectedZaloAccount?.domainId || 0,
    };
  };

  // Handle Test and Preview button click
  const handleTestAndPreview = () => {
    setShowTestAndPreviewSlidebox(true);
    if (propsHandleTestAndPreview) {
      propsHandleTestAndPreview();
    }
  };

  // Handle close Test and Preview slidebox
  const handleCloseTestAndPreview = () => {
    setShowTestAndPreviewSlidebox(false);
    if (propsHandleCloseTestAndPreview) {
      propsHandleCloseTestAndPreview();
    }
  };

  return (
    <CapSpin spinning={[zaloTemplateInfoStatus, metaDataStatus].includes(REQUEST)}>
      <CapRow type="flex" className="cap-zalo-creatives">
        <CapColumn span={14}>
          {templateStatus && (
            <CapAlert
              message={
                <CapLabel type="label2">
                  {formatMessage(messages.approvedStatusMsg, {
                    status: formatMessage(messages?.[templateStatus]),
                  })}
                </CapLabel>
              }
              type={getTemplateStatusType()}
            />
          )}
          <CapRow useLegacy>
            <CapRow useLegacy className="whatsapp-render-heading">
              <CapHeader
                className="zalo-variable-heading"
                title={
                  <CapHeading type="h4">
                    {formatMessage(messages.variables)}
                  </CapHeading>
                }
                suffix={
                  <TagList
                    label={formatMessage(globalMessages.addLabels)}
                    onTagSelect={onTagSelect}
                    location={location}
                    tags={tags || []}
                    onContextChange={handleOnTagsContextChange}
                    injectedTags={injectedTags || {}}
                    selectedOfferDetails={selectedOfferDetails}
                    eventContextTags={eventContextTags}
                    waitEventContextTags={waitEventContextTags}
                  />
                }
              />
            </CapRow>
            <CapRow useLegacy className="zalo-variable-list">
              {renderContent()}
              {
                hasTag && (
                  <CapAlert
                    message={
                      <CapLabel type="label2" className='zalo-warning-message-label'>
                        <CapIcon type="warning" className="alert-icon-zalo" />
                        {formatMessage(messages.tagLengthWarning)}
                      </CapLabel>
                    }
                    type="warning"
                    className="zalo-warning-message"
                  />
                )
              }
            </CapRow>
          </CapRow>
        </CapColumn>
        <CapColumn span={10}>
          <TemplatePreview
            channel={ZALO}
            templateData={{ templatePreviewUrl, fullMode: isFullMode }}
          />
        </CapColumn>
      </CapRow>
      <ZaloFooter>
        {!isFullMode && (
          <CapTooltip
            title={
              isEditDoneDisabled()
                ? formatMessage(messages.btnDisabledTooltip)
                : ''
            }
            placement={'right'}
          >
            <div className="button-disabled-tooltip-wrapper">
              <CapButton
                onClick={saveToMessage}
                disabled={isEditDoneDisabled()}
              >
                <FormattedMessage {...globalMessages.done} />
              </CapButton>
            </div>
          </CapTooltip>
        )}
        <CapButton
          onClick={handleTestAndPreview}
          className="test-and-preview-button-zalo"
          type="secondary"
        >
          <FormattedMessage {...creativesMessages.testAndPreview} />
        </CapButton>
      </ZaloFooter>
      {/* Test and Preview Slidebox */}
      <TestAndPreviewSlidebox
        show={showTestAndPreviewSlidebox || propsShowTestAndPreviewSlidebox}
        onClose={handleCloseTestAndPreview}
        channel={ZALO}
        formData={getTemplateContent()} // Pass templateContent as formData (contains all payload fields)
        content={getTemplateContent()} // Also pass as content for preview
        formatMessage={formatMessage}
      />
    </CapSpin>
  );
};

const mapStateToProps = createStructuredSelector({
  editData: makeSelectZalo(),
  accountData: makeSelectAccount(),
  metaEntities: makeSelectMetaEntities(),
  injectedTags: setInjectedTags(),
  metaDataStatus: selectMetaDataStatus(),
});

const mapDispatchToProps = (dispatch) => ({
  actions: bindActionCreators(zaloActions, dispatch),
  globalActions: bindActionCreators(globalActions, dispatch),
});


const withReducer = injectReducer({ key: 'zalo', reducer: v2ZaloReducer });
const withZaloSaga = injectSaga({ key: 'zalo', saga: v2ZaloSagas });

export default withCreatives({
  WrappedComponent: Zalo,
  mapStateToProps,
  mapDispatchToProps,
  userAuth: true,
  reducers: [withReducer],
  sagas: [withZaloSaga],
});
