import React, { useCallback, useState } from 'react'
import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'

import ModuleEditor from '../ModuleEditor'
import EmptyModule from './EmptyModule'

import { useTypedSelector } from 'redux/rootReducer'
import { selectLocalizationSelected } from 'redux/User/selector'

import { Text } from 'components/Typography'
import DragDropContext from 'components/DragDropContext'
import PortalComponent from 'components/PortalComponent/PortalComponent'

import {
  BaseItem,
  DataCaptureActivationItemNew,
  TalentProfileModule
} from 'models/talent/talent-profile-module.model'

import { ArrayServices } from 'utils/array'

import { useAnalytics } from 'hooks/useAnalytics'
import { useModules } from 'hooks/useModules'

import { SEGMENT_EVENTS } from 'constants/segment'
import { isEmptyModule } from 'utils/modules'
import DataCaptureModuleCard from 'components/DataCaptureAudience/DataCaptureModuleCard'
import DataCaptureCreationModal from 'components/DataCaptureAudience/DataCaptureCreationModal'
import { DCAFormStepsProps } from 'components/DataCaptureAudience/CreationModalForms/schemas'
import {
  dcaFormValuesToItem,
  dcaItemToFormValues
} from 'components/DataCaptureAudience/dca-item-mapping-fns'

import { ModuleType } from '@komi-app/shared-types'
import { FLAGS, useFeatureIsOn } from '@komi-app/flags-sdk'
import { useCreatorTracking, CreatorEvent } from '@komi-app/analytics-sdk'
import { trackingProps } from 'utils/tracking'
import { useAnalyticsStartItemCreation } from 'hooks/useAnalyticsStartItemCreation'
import { useAnalyticsCompleteItemCreation } from 'hooks/useAnalyticsCompleteItemCreation'

export interface ModuleCardProps<T extends BaseItem> {
  module: TalentProfileModule<T>
  disableDragDrop: boolean
  index: number
  disableDrag: boolean
  item: T
  onEdit: (item: T) => void
  onDelete: (item: T) => void
  onCopySmartLink: () => void
  dragHandleProps?: DraggableProvidedDragHandleProps
}
interface CollapsedCardListProps<T extends BaseItem> {
  module: TalentProfileModule<T>
  items: T[]
  CardModule: React.FC<ModuleCardProps<T>>
  onCopySmartLink: () => void
  onDelete: (item: T) => void
  onDropEndCallback: (item: T[]) => void
  onEdit: (item: T) => void
}
const CollapsedCardList = <T extends BaseItem>({
  module,
  items = [],
  CardModule,
  onCopySmartLink = () => {},
  onDelete = () => {},
  onDropEndCallback = () => {},
  onEdit = () => {},
  ...props
}: CollapsedCardListProps<T>): React.ReactElement => (
  <React.Fragment>
    <DragDropContext
      droppableId="product-child-drop"
      listClassName="product-list"
      itemIdPrefix="product"
      direction="vertical"
      list={items.slice(0, 2)}
      onDropEndCallback={onDropEndCallback}
    >
      {(dragProvided, snapshot, item, productIndex) => (
        <PortalComponent
          innerRef={dragProvided.innerRef}
          key={productIndex}
          namespaceClass="product-list"
          provided={dragProvided}
          snapshot={snapshot}
          single={items.length === 1}
        >
          <CardModule
            disableDragDrop={items.length <= 1}
            index={productIndex}
            disableDrag={items.length === 1}
            item={item}
            onEdit={onEdit}
            onDelete={onDelete}
            dragHandleProps={dragProvided.dragHandleProps}
            onCopySmartLink={onCopySmartLink}
            module={module}
            {...props}
          />
        </PortalComponent>
      )}
    </DragDropContext>

    {items.length > 2 && (
      <div className="d--flex justify__content--end align__items--center m__t--20 cursor-pointer">
        <Text preset="medium14" className="opacity-6">
          +{items.length - 2} More
        </Text>
      </div>
    )}
  </React.Fragment>
)

interface DataCaptureActivationModuleProps {
  module: TalentProfileModule<DataCaptureActivationItemNew>
  dragHandleProps?: DraggableProvidedDragHandleProps
  active: boolean
}
interface DcaEditState {
  isEdit: boolean
  dataCapture?: DataCaptureActivationItemNew
  dataCaptureEditIndex?: number
}

const DataCaptureActivationModule: React.FC<
  DataCaptureActivationModuleProps
> = ({ module, dragHandleProps }) => {
  const { sendSegmentEvent } = useAnalytics()
  const useAnalyticsSDK = useFeatureIsOn(FLAGS.USE_ANALYTICS_SDK_TALENT)
  const { createTracker } = useCreatorTracking()
  const elementCreate = createTracker(CreatorEvent.ELEMENT_CREATED)

  const [showContentModal, setShowContentModal] = useState(false)
  const [formState, setFormState] = useState<DcaEditState>({
    isEdit: false
  })

  const profileContext = useModules()
  const { trackStartAddingItemToModule } = useAnalyticsStartItemCreation()
  const { trackCompleteAddingItemToModule } = useAnalyticsCompleteItemCreation()

  const localizationSelected = useTypedSelector(selectLocalizationSelected)

  const onAddDataCapture = useCallback(async () => {
    trackStartAddingItemToModule(module)
    setFormState(preState => ({
      ...preState,
      isEdit: false,
      dataCapture: undefined,
      dataCaptureIndex: undefined
    }))
    setShowContentModal(true)
  }, [])

  const onEditDataCapture = useCallback(() => {
    const dataCapture = module.items[0]
    setFormState(preState => ({
      ...preState,
      isEdit: true,
      dataCapture: dataCapture,
      dataCaptureIndex: dataCapture.order
    }))
    setShowContentModal(true)
  }, [module.items])

  const onDeleteDataCapture = useCallback(
    (dataCapture: DataCaptureActivationItemNew) => {
      const moduleItems = Array.from(module.items)
      const updatedItems = moduleItems.splice(dataCapture.order + 1)
      profileContext.setModule({
        ...module,
        items: updatedItems,
        isUpdate: true
      })
    },
    [module, profileContext.setModule]
  )

  const onDropEndDataCaptures = useCallback(
    (list: DataCaptureActivationItemNew[]) => {
      profileContext.setModule({
        ...module,
        items: list.map((item, index) => ({ ...item, order: index })),
        isUpdate: true
      })
    },
    [module, profileContext.setModule]
  )

  const onSaveProductCallback = useCallback(
    (formValues: DCAFormStepsProps) => {
      const existing = formState.dataCapture
      const dcaElement = dcaFormValuesToItem(formValues, {
        ...existing,
        order: existing?.order ?? module.items.length,
        name: existing?.name ?? 'New Module'
      })

      const moduleItems = formState.isEdit
        ? ArrayServices.updateWithIndex(
            module.items,
            dcaElement.order as number,
            dcaElement
          )
        : [...module.items, dcaElement]

      const moduleEdit = {
        ...module,
        items: moduleItems,
        isUpdate: true
      }

      profileContext.setModule(moduleEdit)
      trackCompleteAddingItemToModule(moduleEdit)
      const { pageId, pageName, type } = trackingProps(
        moduleEdit.type,
        localizationSelected
      )

      useAnalyticsSDK
        ? elementCreate({ pageId, pageName, type })
        : sendSegmentEvent(SEGMENT_EVENTS.ELEMENT_CREATED, {
            'Page ID': localizationSelected?.id || null,
            'Page Name': localizationSelected?.name || 'Default'
          })
    },
    [
      module,
      formState,
      localizationSelected,
      profileContext.setModule,
      sendSegmentEvent
    ]
  )
  return (
    <ModuleEditor
      module={module}
      dragHandleProps={dragHandleProps}
      onEditDataCapture={onEditDataCapture}
    >
      <DataCaptureCreationModal
        initialValues={
          formState.dataCapture
            ? dcaItemToFormValues(formState.dataCapture)
            : undefined
        }
        type={module.type as ModuleType}
        visible={showContentModal}
        onChangeVisible={setShowContentModal}
        onConfirmCallback={onSaveProductCallback}
      />

      {isEmptyModule(module) ? (
        <EmptyModule titleAction="Add a module" onClick={onAddDataCapture} />
      ) : (
        <>
          <CollapsedCardList
            module={module}
            items={module.items}
            onCopySmartLink={() => {}}
            CardModule={DataCaptureModuleCard}
            onDelete={onDeleteDataCapture}
            onDropEndCallback={onDropEndDataCaptures}
            onEdit={onEditDataCapture}
          />
        </>
      )}
    </ModuleEditor>
  )
}

export default DataCaptureActivationModule
