import type { FC } from 'react'
import type { ChildChunkDetail, SegmentDetailModel } from '@/models/datasets'
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogCancelButton,
  AlertDialogConfirmButton,
  AlertDialogContent,
  AlertDialogTitle,
} from '@langgenius/dify-ui/alert-dialog'
import { cn } from '@langgenius/dify-ui/cn'
import { Switch } from '@langgenius/dify-ui/switch'
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
import { RiDeleteBinLine, RiEditLine } from '@remixicon/react'
import * as React from 'react'
import { useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Badge from '@/app/components/base/badge'
import Divider from '@/app/components/base/divider'
import ImageList from '@/app/components/datasets/common/image-list'
import { ChunkingMode } from '@/models/datasets'
import { formatNumber } from '@/utils/format'
import { isAfter } from '@/utils/time'
import StatusItem from '../../../status-item'
import { useDocumentContext } from '../../context'
import ChildSegmentList from '../child-segment-list'
import Dot from '../common/dot'
import { SegmentIndexTag } from '../common/segment-index-tag'
import SummaryLabel from '../common/summary-label'
import Tag from '../common/tag'
import ParentChunkCardSkeleton from '../skeleton/parent-chunk-card-skeleton'
import ChunkContent from './chunk-content'

type ISegmentCardProps = {
  loading: boolean
  detail?: SegmentDetailModel & { document?: { name: string }, status?: string }
  onClick?: () => void
  onChangeSwitch?: (enabled: boolean, segId?: string) => Promise<void>
  onDelete?: (segId: string) => Promise<void>
  onDeleteChildChunk?: (segId: string, childChunkId: string) => Promise<void>
  handleAddNewChildChunk?: (parentChunkId: string) => void
  onClickSlice?: (childChunk: ChildChunkDetail) => void
  onClickEdit?: () => void
  className?: string
  archived?: boolean
  embeddingAvailable?: boolean
  focused: {
    segmentIndex: boolean
    segmentContent: boolean
  }
}

const SegmentCard: FC<ISegmentCardProps> = ({
  detail = { status: '' },
  onClick,
  onChangeSwitch,
  onDelete,
  onDeleteChildChunk,
  handleAddNewChildChunk,
  onClickSlice,
  onClickEdit,
  loading = true,
  className = '',
  archived,
  embeddingAvailable,
  focused,
}) => {
  const { t } = useTranslation()
  const {
    id,
    position,
    enabled,
    content,
    sign_content,
    word_count,
    hit_count,
    answer,
    summary,
    keywords,
    child_chunks = [],
    created_at,
    updated_at,
    attachments = [],
  } = detail as Required<ISegmentCardProps>['detail']
  const [showModal, setShowModal] = useState(false)
  const docForm = useDocumentContext(s => s.docForm)
  const parentMode = useDocumentContext(s => s.parentMode)

  const isGeneralMode = useMemo(() => {
    return docForm === ChunkingMode.text
  }, [docForm])

  const isParentChildMode = useMemo(() => {
    return docForm === ChunkingMode.parentChild
  }, [docForm])

  const isParagraphMode = useMemo(() => {
    return docForm === ChunkingMode.parentChild && parentMode === 'paragraph'
  }, [docForm, parentMode])

  const isFullDocMode = useMemo(() => {
    return docForm === ChunkingMode.parentChild && parentMode === 'full-doc'
  }, [docForm, parentMode])

  const chunkEdited = useMemo(() => {
    if (docForm === ChunkingMode.parentChild && parentMode === 'full-doc')
      return false
    return isAfter(updated_at * 1000, created_at * 1000)
  }, [docForm, parentMode, updated_at, created_at])

  const contentOpacity = useMemo(() => {
    return (enabled || focused.segmentContent) ? '' : 'opacity-50 group-hover/card:opacity-100'
  }, [enabled, focused.segmentContent])

  const handleClickCard = useCallback(() => {
    if (docForm !== ChunkingMode.parentChild || parentMode !== 'full-doc')
      onClick?.()
  }, [docForm, parentMode, onClick])

  const wordCountText = useMemo(() => {
    const total = formatNumber(word_count)
    return `${total} ${t('segment.characters', { ns: 'datasetDocuments', count: word_count })}`
  }, [word_count, t])

  const labelPrefix = useMemo(() => {
    return isParentChildMode ? t('segment.parentChunk', { ns: 'datasetDocuments' }) : t('segment.chunk', { ns: 'datasetDocuments' })
  }, [isParentChildMode, t])

  const images = useMemo(() => {
    return attachments.map(attachment => ({
      name: attachment.name,
      mimeType: attachment.mime_type,
      sourceUrl: attachment.source_url,
      size: attachment.size,
      extension: attachment.extension,
    }))
  }, [attachments])

  if (loading)
    return <ParentChunkCardSkeleton />

  return (
    <div
      data-testid="segment-card"
      className={cn(
        'chunk-card group/card w-full rounded-xl px-3',
        isFullDocMode ? '' : 'pt-2.5 pb-2 hover:bg-dataset-chunk-detail-card-hover-bg',
        focused.segmentContent ? 'bg-dataset-chunk-detail-card-hover-bg' : '',
        className,
      )}
      onClick={handleClickCard}
    >
      <div className="relative flex h-5 items-center justify-between">
        <>
          <div className="flex items-center gap-x-2">
            <SegmentIndexTag
              className={cn(contentOpacity)}
              iconClassName={focused.segmentIndex ? 'text-text-accent' : ''}
              labelClassName={focused.segmentIndex ? 'text-text-accent' : ''}
              positionId={position}
              label={isFullDocMode ? labelPrefix : ''}
              labelPrefix={labelPrefix}
            />
            <Dot />
            <div className={cn('system-xs-medium text-text-tertiary', contentOpacity)}>{wordCountText}</div>
            <Dot />
            <div className={cn('system-xs-medium text-text-tertiary', contentOpacity)}>{`${formatNumber(hit_count)} ${t('segment.hitCount', { ns: 'datasetDocuments' })}`}</div>
            {chunkEdited && (
              <>
                <Dot />
                <Badge text={t('segment.edited', { ns: 'datasetDocuments' }) as string} uppercase className={contentOpacity} />
              </>
            )}
          </div>
          {!isFullDocMode
            ? (
                <div className="flex items-center">
                  <StatusItem status={enabled ? 'enabled' : 'disabled'} reverse textCls="text-text-tertiary system-xs-regular" />
                  {embeddingAvailable && (
                    <div className="absolute -top-2 -right-2.5 z-20 hidden items-center gap-x-0.5 rounded-[10px] border-[0.5px]
                      border-components-actionbar-border bg-components-actionbar-bg p-1 shadow-md backdrop-blur-[5px] group-hover/card:flex"
                    >
                      {!archived && (
                        <>
                          <Tooltip>
                            <TooltipTrigger
                              render={(
                                <button
                                  type="button"
                                  aria-label={t('operation.edit', { ns: 'common' })}
                                  className="flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-lg border-none bg-transparent p-0 hover:bg-state-base-hover"
                                  onClick={(e) => {
                                    e.stopPropagation()
                                    onClickEdit?.()
                                  }}
                                >
                                  <RiEditLine className="size-4 text-text-tertiary" aria-hidden="true" />
                                </button>
                              )}
                            />
                            <TooltipContent className="system-xs-medium text-text-secondary">Edit</TooltipContent>
                          </Tooltip>
                          <Tooltip>
                            <TooltipTrigger
                              render={(
                                <button
                                  type="button"
                                  aria-label={t('operation.delete', { ns: 'common' })}
                                  className="group/delete flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-lg border-none bg-transparent p-0 hover:bg-state-destructive-hover"
                                  onClick={(e) => {
                                    e.stopPropagation()
                                    setShowModal(true)
                                  }}
                                >
                                  <RiDeleteBinLine className="size-4 text-text-tertiary group-hover/delete:text-text-destructive" aria-hidden="true" />
                                </button>
                              )}
                            />
                            <TooltipContent className="system-xs-medium text-text-secondary">Delete</TooltipContent>
                          </Tooltip>
                          <Divider type="vertical" className="h-3.5 bg-divider-regular" />
                        </>
                      )}
                      <div
                        onClick={(e: React.MouseEvent<HTMLDivElement, MouseEvent>) =>
                          e.stopPropagation()}
                        className="flex items-center"
                      >
                        <Switch
                          size="md"
                          disabled={archived || detail?.status !== 'completed'}
                          checked={enabled}
                          onCheckedChange={async (val) => {
                            await onChangeSwitch?.(val, id)
                          }}
                        />
                      </div>
                    </div>
                  )}
                </div>
              )
            : null}
        </>
      </div>
      <ChunkContent
        detail={{
          answer,
          content,
          sign_content,
        }}
        isFullDocMode={isFullDocMode}
        className={contentOpacity}
      />
      {images.length > 0 && <ImageList images={images} size="md" className="py-1" />}
      {
        summary && (
          <SummaryLabel summary={summary} className="mt-2" />
        )
      }
      {isGeneralMode && (
        <div className={cn('flex flex-wrap items-center gap-2 py-1.5', contentOpacity)}>
          {keywords?.map(keyword => <Tag key={keyword} text={keyword} />)}
        </div>
      )}
      {
        isFullDocMode
          ? (
              <button
                type="button"
                className="mt-0.5 mb-2 border-none bg-transparent p-0 text-left system-xs-semibold-uppercase text-text-accent"
                onClick={() => onClick?.()}
              >
                {t('operation.viewMore', { ns: 'common' })}
              </button>
            )
          : null
      }
      {
        isParagraphMode && child_chunks.length > 0
        && (
          <ChildSegmentList
            parentChunkId={id}
            childChunks={child_chunks}
            enabled={enabled}
            onDelete={onDeleteChildChunk!}
            handleAddNewChildChunk={handleAddNewChildChunk}
            onClickSlice={onClickSlice}
            focused={focused.segmentContent}
          />
        )
      }
      <AlertDialog open={showModal} onOpenChange={open => !open && setShowModal(false)}>
        <AlertDialogContent>
          <div className="flex flex-col gap-2 px-6 pt-6 pb-4">
            <AlertDialogTitle className="w-full truncate title-2xl-semi-bold text-text-primary">
              {t('segment.delete', { ns: 'datasetDocuments' })}
            </AlertDialogTitle>
          </div>
          <AlertDialogActions>
            <AlertDialogCancelButton>{t('operation.cancel', { ns: 'common' })}</AlertDialogCancelButton>
            <AlertDialogConfirmButton onClick={async () => { await onDelete?.(id) }}>
              {t('operation.sure', { ns: 'common' })}
            </AlertDialogConfirmButton>
          </AlertDialogActions>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  )
}

export default React.memo(SegmentCard)
