import { DigitalProductItem } from '@komi-app/profiles-sdk'
import { Button, Col, Row } from 'antd'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'
import { useHistory } from 'react-router-dom'
import When from '@komi-app/when'
import { FLAGS, useFeatureIsOn } from '@komi-app/flags-sdk'

import DigitalProductModule from 'components/DigitalProductModule/DigitalProductModule'
import DragDropContext from 'components/DragDropContext'
import { Icon } from 'components/Icon'
import PortalComponent from 'components/PortalComponent/PortalComponent'
import { Paragraph, Text } from 'components/Typography'
import { useWindowSize } from 'hooks'
import { useModules } from 'hooks/useModules'
import reduce from 'lodash/reduce'
import { TalentProfileModule } from 'models/talent/talent-profile-module.model'
import ModuleEditor from '../ModuleEditor'
import { getSalesServiceV1 } from 'services'
import { InlineMessage } from '@komi-app/components'
import { Link } from 'react-router-dom'
import { DataStripeAccountStatus } from '@komi-app/sales-sdk'
import { InlineMessageType } from 'components/SubscriptionBanner/SubscriptionBanner'
import { useIsConnectedAccountDisabled } from 'hooks/useIsConnectedAccountDisabled'
import { useDigitalProductFeatures } from 'hooks/useDigitalProductFeatures'
import { useAnalyticsStartItemCreation } from 'hooks/useAnalyticsStartItemCreation'

interface ModuleDigitalProductProps {
  module: TalentProfileModule<DigitalProductItem>
  dragHandleProps?: DraggableProvidedDragHandleProps
  active: boolean
}

const ModuleDigitalProduct: React.FC<ModuleDigitalProductProps> = ({
  module,
  dragHandleProps,
  active
}) => {
  const profileContext = useModules()

  const { width } = useWindowSize()
  const isMobileStyleChangesEnabled = width && width <= 768

  const productList = useMemo(() => module.items, [module.items])

  const { isFreeDownloadOn, isPaidDownloadOn, useNewForms } =
    useDigitalProductFeatures()

  const isUpdateFlowOn = useFeatureIsOn(
    FLAGS.FEAT_STRIPE_CONNECT_FLOW_ENHANCEMENTS
  )
  const [stripeAccountStatusData, setStripeAccountStatusData] =
    useState<DataStripeAccountStatus | null>(null)
  const [isStripeAccountStatusLoading, setIsStripeAccountStatusLoading] =
    useState(true)

  const { trackStartAddingItemToModule } = useAnalyticsStartItemCreation()

  useEffect(() => {
    const fetchStripeAccountStatus = async () => {
      try {
        setIsStripeAccountStatusLoading(true)
        const data = await getSalesServiceV1().getStripeAccountStatus()
        setStripeAccountStatusData(data)
      } catch (error) {
        console.error('Failed to fetch Stripe account status:', error)
        setStripeAccountStatusData(null)
      } finally {
        setIsStripeAccountStatusLoading(false)
      }
    }

    fetchStripeAccountStatus()
  }, [])

  const constructStripeAccountMessage = (
    stripeAccountStatusData?: DataStripeAccountStatus
  ): {
    message: string
    messageType: InlineMessageType
    redirectionLabel: string
    redirectionLink: string
    showMissingInfoErrorMessage: boolean
  } => {
    //When stripe account is not connected/created
    if (!stripeAccountStatusData || !stripeAccountStatusData.isEmailConnected) {
      return {
        message: 'A free Stripe account is required to sell digital product.',
        messageType: 'warning',
        redirectionLabel: 'Go to Settings',
        redirectionLink: '/admin/settings/subscription',
        showMissingInfoErrorMessage: true
      }
    }

    const { isPaymentEnabled, isPayoutEnabled, hasPendingActions } =
      stripeAccountStatusData

    let message

    if (!isPaymentEnabled && !isPayoutEnabled) {
      message =
        'Your Stripe account has missing information or pending actions. Complete these to ensure you receive payments and payouts for your sales.'
    } else if (!isPaymentEnabled) {
      message =
        'Your Stripe account has missing information or pending actions. Complete these to ensure you receive payments for your sales.'
    } else if (!isPayoutEnabled) {
      message =
        'Your Stripe account has missing information or pending actions. Complete these to ensure you receive payouts for your sales.'
    } else if (hasPendingActions) {
      message =
        'Your Stripe account has missing information or pending actions. Complete these as soon as possible to keep your account active.'
    } else {
      // Everything is connected and enabled, no message needed
      message = ''
    }

    return {
      message,
      messageType: 'error',
      redirectionLabel: 'Go to Stripe dashboard',
      redirectionLink: 'https://dashboard.stripe.com/',
      showMissingInfoErrorMessage: message !== ''
    }
  }

  const {
    message,
    showMissingInfoErrorMessage,
    messageType,
    redirectionLabel,
    redirectionLink
  } = constructStripeAccountMessage(stripeAccountStatusData)

  const router = useHistory()

  const onEditModuleCallback = useCallback(
    (moduleEdit: TalentProfileModule<DigitalProductItem>) => {
      profileContext.setModule?.(moduleEdit)
    },
    [profileContext]
  )

  const onDropEnd = useCallback(
    (list: DigitalProductItem[]) => {
      const moduleEdit = {
        ...module,
        items: list.map((item, index) => ({ ...item, order: index })),
        isUpdate: true
      }
      onEditModuleCallback(moduleEdit)
    },
    [module, onEditModuleCallback]
  )

  const onAddItemClicked = useCallback(() => {
    trackStartAddingItemToModule(module)

    const url =
      useNewForms || productList?.[0]?.landingPage?.regularPrice
        ? 'digital-product'
        : 'free-download'
    router.push(`/admin/modules/${url}?moduleId=${module.id}`)
  }, [])

  const onEditItemClicked = useCallback((item: DigitalProductItem) => {
    const url =
      useNewForms || item.landingPage?.regularPrice
        ? 'digital-product'
        : 'free-download'
    router.push(
      `/admin/modules/${url}/edit?moduleId=${module.id}&itemId=${item.id}`
    )
  }, [])

  const onDeleteItem = useCallback(
    (product: DigitalProductItem) => {
      const items = reduce(
        module.items,
        (results: any, item: any) => {
          if (item.order !== product.order) {
            return [...results, { ...item, order: results.length }]
          }
          return results
        },
        []
      )

      onEditModuleCallback({
        ...module,
        items,
        isUpdate: true
      })
    },
    [module, profileContext.setModule]
  )

  const isConnectedAccountDisabled = useIsConnectedAccountDisabled(
    stripeAccountStatusData
  )

  //Determines if item visibility is enabled or disabled
  const isItemVisiblityDisabled = !isUpdateFlowOn
    ? !stripeAccountStatusData?.isEnabled &&
      !!productList?.[0]?.landingPage?.regularPrice
    : isConnectedAccountDisabled &&
      !!productList?.[0]?.landingPage?.regularPrice

  const renderContent = () => {
    const [firstItem] = module.items as DigitalProductItem[]
    const hasPrice = (firstItem?.landingPage?.regularPrice || 0) > 0
    const isDownloadEnabled =
      (hasPrice && isPaidDownloadOn) || (!hasPrice && isFreeDownloadOn)

    if (!module.items.length) {
      return (
        <React.Fragment>
          <Row justify="center">
            <Col span={24} className="text__align--center">
              <Icon name="empty-module" />
            </Col>
            <Col span={24} className="text__align--center max-w-393">
              <Paragraph preset="semibold18" className="d--block m__b--4">
                Nothing Here Yet
              </Paragraph>
              <Paragraph preset="regular14" className="d--block text--grey4">
                Click the button below to get started
              </Paragraph>
            </Col>
            <Col span={24} className="height--32 m__t--20">
              <Row justify="center">
                <Button
                  className="add-item-btn p--0"
                  type="link"
                  onClick={onAddItemClicked}
                >
                  {isDownloadEnabled && (
                    <div className="d--flex justify__content--center align__items--center">
                      <Icon name="add-blue" />
                      <Text preset="semibold18" className="text--blue m__l--4">
                        Add New Item
                      </Text>
                    </div>
                  )}
                </Button>
              </Row>
            </Col>
          </Row>
        </React.Fragment>
      )
    }

    return (
      <React.Fragment>
        <Row
          align="middle"
          justify="space-between"
          className={isMobileStyleChangesEnabled ? 'm__b--8' : 'm__b--24'}
        >
          <Col className="height--32">
            <Button
              className="add-item-btn p--0"
              type="link"
              onClick={onAddItemClicked}
            >
              {isDownloadEnabled && (
                <div className="d--flex justify__content--center align__items--center">
                  <Icon name="add-blue" />
                  <Text preset="semibold18" className="text--blue m__l--4">
                    Add New Item
                  </Text>
                </div>
              )}
            </Button>
          </Col>
          <Col>
            <Text preset="medium14" className="text--default opacity-6">
              {productList.length}&nbsp;
              {productList.length > 1 ? 'items added' : 'item added'}
            </Text>
          </Col>
        </Row>
        <When
          value={!isUpdateFlowOn}
          then={
            <When
              value={
                !isStripeAccountStatusLoading &&
                !stripeAccountStatusData?.isEnabled &&
                hasPrice
              }
              then={
                <InlineMessage
                  className={
                    isMobileStyleChangesEnabled ? 'm__b--8' : 'm__b--24'
                  }
                  type="warning"
                  message={
                    <span className="text--black">
                      A free Stripe account is required to receive payouts for
                      your digital product sales.
                      <Link to="/admin/settings/subscription">
                        &nbsp;Go to Settings
                      </Link>
                    </span>
                  }
                />
              }
            />
          }
          otherwise={
            <When
              value={
                showMissingInfoErrorMessage &&
                hasPrice &&
                !isStripeAccountStatusLoading
              }
              then={
                <InlineMessage
                  className={
                    isMobileStyleChangesEnabled ? 'm__b--8' : 'm__b--24'
                  }
                  type={messageType}
                  message={
                    <span className="text--black">
                      {message}
                      <When
                        value={redirectionLink.includes('stripe')}
                        then={
                          <a
                            href={redirectionLink}
                            target="_blank"
                            rel="noopener noreferrer"
                            style={{ display: 'block' }}
                          >
                            {redirectionLabel}
                          </a>
                        }
                        otherwise={
                          <Link
                            to={redirectionLink}
                            style={{ display: 'block' }}
                          >
                            {redirectionLabel}
                          </Link>
                        }
                      />
                    </span>
                  }
                />
              }
            />
          }
        />
        <DragDropContext
          droppableId="product-child-drop"
          listClassName="product-list"
          itemIdPrefix="product"
          direction="vertical"
          list={productList}
          onDropEndCallback={onDropEnd}
        >
          {(dragProvided, snapshot, item, productIndex) => {
            const isRender = active ? active : productIndex < 2

            const isConnectedAccountDisabled = useIsConnectedAccountDisabled(
              stripeAccountStatusData
            )

            //Calculate disableItemVisibility
            const isItemVisiblityDisabled = !isUpdateFlowOn
              ? !stripeAccountStatusData?.isEnabled &&
                !!productList?.[0]?.landingPage?.regularPrice
              : isConnectedAccountDisabled &&
                !!productList?.[0]?.landingPage?.regularPrice

            return isRender ? (
              <PortalComponent
                innerRef={dragProvided.innerRef}
                key={productIndex}
                namespaceClass="product-list"
                provided={dragProvided}
                snapshot={snapshot}
                single={productList?.length === 1}
              >
                <DigitalProductModule
                  titleShortcut
                  disableDragDrop={module.items?.length <= 1}
                  index={productIndex}
                  disableDrag={productList?.length === 1}
                  item={item}
                  onEdit={onEditItemClicked}
                  onDelete={onDeleteItem}
                  dragHandleProps={dragProvided.dragHandleProps ?? undefined}
                  disableItemVisibility={isItemVisiblityDisabled}
                  module={module}
                  isInCollection={false}
                />
              </PortalComponent>
            ) : (
              <></>
            )
          }}
        </DragDropContext>
        {!active && productList.length > 2 && (
          <div className="d--flex justify__content--end align__items--center m__t--20 cursor-pointer">
            <Text preset="medium14" className="opacity-6">
              +{productList.length - 2} More
            </Text>
          </div>
        )}
      </React.Fragment>
    )
  }

  return (
    <React.Fragment>
      <ModuleEditor
        module={module}
        dragHandleProps={dragHandleProps}
        disableModuleVisibility={isItemVisiblityDisabled}
      >
        {renderContent()}
      </ModuleEditor>
    </React.Fragment>
  )
}

export default React.memo(ModuleDigitalProduct)
