'use client'
import type { RefObject } from 'react'
import type { Plugin, PluginCategoryEnum } from '@/app/components/plugins/types'
import { cn } from '@langgenius/dify-ui/cn'
import { RiArrowRightUpLine } from '@remixicon/react'
import { noop } from 'es-toolkit/function'
import { useEffect, useImperativeHandle, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import Link from '@/next/link'
import { getMarketplaceUrl } from '@/utils/var'
import useStickyScroll, { ScrollPosition } from '../use-sticky-scroll'
import Item from './item'

export type ListProps = {
  wrapElemRef: React.RefObject<HTMLElement | null>
  list: Plugin[]
  searchText: string
  tags: string[]
  category?: PluginCategoryEnum
  toolContentClassName?: string
  disableMaxWidth?: boolean
  hideFindMoreFooter?: boolean
  ref?: React.Ref<ListRef>
}

export type ListRef = { handleScroll: () => void }

const List = ({
  wrapElemRef,
  searchText,
  tags,
  list,
  category,
  toolContentClassName,
  disableMaxWidth = false,
  hideFindMoreFooter = false,
  ref,
}: ListProps) => {
  const { t } = useTranslation()
  const noFilter = !searchText && tags.length === 0
  const hasRes = list.length > 0
  const urlWithSearchText = getMarketplaceUrl('', { q: searchText, tags: tags.join(',') })
  const nextToStickyELemRef = useRef<HTMLDivElement>(null)

  const { handleScroll, scrollPosition } = useStickyScroll({
    wrapElemRef,
    nextToStickyELemRef: nextToStickyELemRef as RefObject<HTMLElement>,
  })
  const stickyClassName = useMemo(() => {
    switch (scrollPosition) {
      case ScrollPosition.aboveTheWrap:
        return 'top-0 h-9 pt-3 pb-2 shadow-xs bg-components-panel-bg-blur cursor-pointer'
      case ScrollPosition.showing:
        return 'bottom-0 pt-3 pb-1'
      case ScrollPosition.belowTheWrap:
        return 'bottom-0 items-center rounded-b-xl border-t border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg rounded-b-lg cursor-pointer'
    }
  }, [scrollPosition])

  useImperativeHandle(ref, () => ({
    handleScroll,
  }))

  useEffect(() => {
    handleScroll()
  }, [list])

  const handleHeadClick = () => {
    if (scrollPosition === ScrollPosition.belowTheWrap) {
      nextToStickyELemRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
      return
    }
    window.open(urlWithSearchText, '_blank')
  }

  if (noFilter) {
    if (hideFindMoreFooter)
      return null

    return (
      <Link
        className="sticky bottom-0 z-10 flex h-8 cursor-pointer items-center rounded-b-lg border-[0.5px] border-t border-components-panel-border bg-components-panel-bg-blur px-4 py-1 system-sm-medium text-text-accent-light-mode-only shadow-lg"
        href={getMarketplaceUrl('', { category })}
        target="_blank"
        rel="noopener noreferrer"
      >
        <span>{t('findMoreInMarketplace', { ns: 'plugin' })}</span>
        <RiArrowRightUpLine className="ml-0.5 size-3" />
      </Link>
    )
  }

  const maxWidthClassName = toolContentClassName || 'max-w-full'

  return (
    <>
      {hasRes && (
        <div
          className={cn('sticky z-10 flex h-8 cursor-pointer justify-between px-4 py-1 system-sm-medium text-text-primary', stickyClassName, !disableMaxWidth && maxWidthClassName)}
          onClick={handleHeadClick}
        >
          <span>{t('fromMarketplace', { ns: 'plugin' })}</span>
          <Link
            href={urlWithSearchText}
            target="_blank"
            rel="noopener noreferrer"
            className="flex items-center text-text-accent-light-mode-only"
            onClick={e => e.stopPropagation()}
          >
            <span>{t('searchInMarketplace', { ns: 'plugin' })}</span>
            <RiArrowRightUpLine className="ml-0.5 size-3" />
          </Link>
        </div>
      )}
      <div className={cn('p-1', !disableMaxWidth && maxWidthClassName)} ref={nextToStickyELemRef}>
        {list.map((item, index) => (
          <Item
            key={index}
            payload={item}
            onAction={noop}
          />
        ))}
      </div>
    </>
  )
}

List.displayName = 'List'

export default List
