/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react/no-unescaped-entities */

import { CircularProgress } from '@mui/material'
import { Form, Formik } from 'formik'
import _identity from 'lodash/identity'
import _map from 'lodash/map'
import React, { useEffect, useState } from 'react'
import { Tooltip } from 'react-tooltip'

import { FEES_STYLES } from '../../constants'
import { currencyNormalizerCreator } from '../../normalizers'
import { CONFIGS, createMarkup, getQueryVariable, isBrowser } from '../../utils'
import { VerificationPendingModal } from '../idVerificationContainer/VerificationPendingModal'
import InfoIcon from '../ticketsContainer/InfoIcon'
import TimerWidget from '../timerWidget'
import AddonComponent from './AddonComponent'
import { getNormalizedPrice } from './normalizers'
import { isAtLeastOneAddonSelected } from './utils'
import { useAddons } from './useAddons'

export interface IAddonContainterProps {
  classNamePrefix?: string;
  enableBillingInfoAutoCreate?: boolean;
  enableTimer?: boolean;
  onGetAddonsPageInfoSuccess?: (res: any) => void;
  onGetAddonsPageInfoError?: (error: any) => void;
  onPostCheckoutSuccess?: (res: any) => void;
  onPostCheckoutError?: (error: any) => void;
  onConfirmSelectionSuccess?: (res: any) => void;
  onConfirmSelectionError?: (error: any) => void;
  onCountdownFinish?: () => void;
  onPendingVerification?: () => void;
  samePage?: boolean;
  descriptionTrigger?: 'click' | 'hover' | 'always';
  addOnDataWithCustomFields: any;
  configs: any;

  onAddOnSelect?: (id: string, value: string, addon: any) => void;
  useStepperQty?: boolean;
  addonMaxQuantityGroups?: number;
}


export const AddonsContainter = ({
  classNamePrefix = 'add_on',
  enableBillingInfoAutoCreate = true,
  enableTimer = false,
  onGetAddonsPageInfoSuccess = _identity,
  onGetAddonsPageInfoError = _identity,
  onPostCheckoutSuccess = _identity,
  onPostCheckoutError = _identity,
  onConfirmSelectionSuccess = _identity,
  onConfirmSelectionError = _identity,
  onCountdownFinish = _identity,
  onPendingVerification = _identity,
  samePage,
  descriptionTrigger = 'click',
  addOnDataWithCustomFields,
  configs,
  onAddOnSelect = _identity,
  useStepperQty = false,
}: IAddonContainterProps) => {
  const eventId = getQueryVariable('event_id') || null

  const {
    addons,
    addonsOptions,
    loading,
    cartExpirationTime,
    pendingVerificationMessage,
    initialValues,
    onFieldChange,
    handleConfirm,
    handleClearAddons,
  } = useAddons(eventId, {
    enableBillingInfoAutoCreate,
    addOnDataWithCustomFields,
    onGetAddonsPageInfoSuccess,
    onGetAddonsPageInfoError,
    onPostCheckoutSuccess,
    onPostCheckoutError,
    onConfirmSelectionSuccess,
    onConfirmSelectionError,
  })

  const [visibleDescription, setVisibleDescription] = useState<string | null>(null)

  const handleDescriptionToggle = (ticketId: string) => {
    setVisibleDescription(current => (current === ticketId ? null : ticketId))
  }

  useEffect(() => {
    if (samePage) {
      window.localStorage.removeItem('add_ons')
    }
  }, [])

  if (loading) {
    return (
      <div className={`${classNamePrefix}_loader`}>
        <CircularProgress size={50} />
      </div>
    )
  }

  if (addons?.length === 0) {
    return null
  }

  const params = new URL(`${window.location}`).searchParams
  const addOnIsIncluded = params.get('include_add_on') === 'true'
  const isResale = params.get('resale') === 'true'

  return (
    <>
      {!!cartExpirationTime && enableTimer && !samePage && (
        <TimerWidget
          expires_at={cartExpirationTime}
          onCountdownFinish={() => {
            handleClearAddons()
            onCountdownFinish()
          }}
        />
      )}
      <div className={`${classNamePrefix}_container`}>
        <div className={`${classNamePrefix}_block`}>
          <div className={`${classNamePrefix}_line_block`}>
            {samePage ? null : (
              <p className={`${classNamePrefix}_info_title`}>Get Your Tickets</p>
            )}
            {(!addons?.length || (isResale && addOnIsIncluded)) && samePage ? null : (
              <div className={`${classNamePrefix}_title`}>UPGRADES & ADD-ONS</div>
            )}
            {samePage ? null : (
              <button
                type="button"
                className={`${classNamePrefix}_skip`}
                onClick={() => {
                  handleClearAddons()
                  handleConfirm({}, true)
                }}
              >
                Skip
              </button>
            )}
          </div>
          {(!addons?.length || (isResale && addOnIsIncluded)) && samePage ? null : (
            <div className={`${classNamePrefix}_subtitle`}>
              PLEASE SELECT FROM THE OPTIONAL ADD-ONS BELOW
            </div>
          )}
          <Formik
            initialValues={initialValues}
            onSubmit={values => {
              handleConfirm(values)
            }}
            validate={
              samePage
                ? values => {
                    if (isBrowser) {
                      window.localStorage.setItem('add_ons', JSON.stringify(values))
                    }
                  }
                : undefined
            }
          >
            {({ values, errors, setFieldTouched }) => {
              const isConfirmDisabled = !isAtLeastOneAddonSelected(values)

              return (
                <Form autoComplete="off" className="form_holder">
                  <>
                    {(isResale && addOnIsIncluded ? [] : addons).map((addon: any) => {
                      const price = addon.feeIncluded ? addon.price : addon.cost
                      const isAddonFree = Number(addon?.price) === 0

                      const addOnNormalizedCost = isAddonFree
                        ? 'FREE'
                        : currencyNormalizerCreator(
                            getNormalizedPrice(addon?.cost ?? 0),
                            addon.currency
                          )

                      const addonNormalizedPrice = isAddonFree
                        ? 'FREE'
                        : currencyNormalizerCreator(
                            getNormalizedPrice(
                              CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH
                                ? addon?.price ?? price
                                : price
                            ),
                            addon.currency
                          )

                      return (
                        <div
                          key={addon.id}
                          className={`${classNamePrefix}_product_block`}
                        >
                          <div className={`${classNamePrefix}_product_images`}>
                            {addon.imageUrl && (
                              <div className={`${classNamePrefix}_product_image_block`}>
                                <img src={addon.imageUrl} alt="No Data" />
                              </div>
                            )}
                          </div>
                          <div className={`${classNamePrefix}_product_info_block`}>
                            <div className={`${classNamePrefix}_product_title`}>
                              {addon.name}
                              {addon.description && descriptionTrigger !== 'always' && (
                                <>
                                  <span
                                    aria-hidden
                                    className="info-icon"
                                    onClick={
                                      descriptionTrigger === 'click'
                                        ? () => handleDescriptionToggle(addon.id)
                                        : undefined
                                    }
                                    onMouseEnter={
                                      descriptionTrigger === 'hover'
                                        ? () => setVisibleDescription(addon.id)
                                        : undefined
                                    }
                                    onMouseLeave={
                                      descriptionTrigger === 'hover'
                                        ? () => setVisibleDescription(null)
                                        : undefined
                                    }
                                    style={{
                                      marginLeft: 8,
                                      cursor: 'pointer',
                                      display: 'flex',
                                    }}
                                    data-tooltip-id={`tooltip-${addon.id}`}
                                    data-tooltip-content="View Add-On info"
                                  >
                                    <InfoIcon size={14} />
                                  </span>
                                  <Tooltip id={`tooltip-${addon.id}`} place="top">
                                    {addon.description || 'No description available'}
                                  </Tooltip>
                                </>
                              )}
                            </div>
                            <div className={`${classNamePrefix}_product_price`}>
                              {CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL
                                ? addonNormalizedPrice
                                : addOnNormalizedCost}
                              {!isAddonFree &&
                                CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL && (
                                  <span className={`${classNamePrefix}_product_fee`}>
                                    {addon.feeIncluded ? '(incl. Fees)' : '(excl. Fees)'}
                                  </span>
                                )}
                              {!isAddonFree &&
                                CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH && (
                                  <>
                                    <span className={`${classNamePrefix}_product_fee`}>
                                      {`(${addonNormalizedPrice} with fees)`}
                                    </span>
                                  </>
                                )}
                            </div>
                          </div>
                          {(visibleDescription === addon.id ||
                            descriptionTrigger === 'always') && (
                            <div
                              className={`${classNamePrefix}_product_desc`}
                              dangerouslySetInnerHTML={createMarkup(addon.description)}
                            />
                          )}
                          <div className={`${classNamePrefix}_product_select_container`}>
                            {addon.variants ? (
                              addon.variants.map((variant: any) => (
                                // Group Variants
                                <AddonComponent
                                  key={variant.id}
                                  data={variant}
                                  selectOptions={addonsOptions[variant.id]}
                                  classNamePrefix={classNamePrefix}
                                  siblingIds={addon.variants.map((v: any) => v.id).filter((vid: string) => vid !== variant.id)}
                                  handleAddonChange={(id, value) => {
                                    onAddOnSelect(id, value, addon)
                                    onFieldChange(id, value, addon)
                                  }}
                                  addOnDataWithCustomFields={addOnDataWithCustomFields}
                                  configs={configs}
                                  values={values}
                                  errors={errors}
                                  useStepperQty={useStepperQty}
                                />
                              ))
                            ) : (
                              // Simple Addon
                              <AddonComponent
                                key={addon.id}
                                data={addon}
                                selectOptions={addonsOptions[addon.id]}
                                classNamePrefix={classNamePrefix}
                                handleAddonChange={(id, value) => {
                                  onAddOnSelect(id, value, addon)
                                  onFieldChange(id, value, addon)

                                  _map(addOnDataWithCustomFields.fields, fieldGroup => {
                                    const { id, groupItems } = fieldGroup
                                    _map(groupItems, field => {
                                      setFieldTouched(
                                        `${addon.id}-${id}-${field.name}`,
                                        true,
                                        true
                                      )
                                    })
                                  })
                                }}
                                addOnDataWithCustomFields={addOnDataWithCustomFields}
                                configs={configs}
                                values={values}
                                errors={errors}
                              />
                            )}
                          </div>
                        </div>
                      )
                    })}
                    {samePage ? null : (
                      <button
                        type="submit"
                        className={`${
                          isConfirmDisabled ? `${classNamePrefix}_is_disabled` : ''
                        } ${classNamePrefix}_submit_button`}
                        disabled={isConfirmDisabled}
                      >
                        CONFIRM SELECTION
                      </button>
                    )}
                  </>
                </Form>
              )
            }}
          </Formik>
        </div>
      </div>
      <VerificationPendingModal
        message={pendingVerificationMessage}
        onClose={() => {
          onPendingVerification()
        }}
      />
    </>
  )
}
