import type { PipelineTemplate } from '@/models/pipeline'
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogCancelButton,
  AlertDialogConfirmButton,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogTitle,
} from '@langgenius/dify-ui/alert-dialog'
import { Dialog, DialogContent } from '@langgenius/dify-ui/dialog'
import { toast } from '@langgenius/dify-ui/toast'
import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { trackEvent } from '@/app/components/base/amplitude'
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
import { useRouter } from '@/next/navigation'
import { useCreatePipelineDatasetFromCustomized } from '@/service/knowledge/use-create-dataset'
import { useInvalidDatasetList } from '@/service/knowledge/use-dataset'
import {
  useDeleteTemplate,
  useExportTemplateDSL,
  useInvalidCustomizedTemplateList,
  usePipelineTemplateById,
} from '@/service/use-pipeline'
import { downloadBlob } from '@/utils/download'
import Actions from './actions'
import Content from './content'
import Details from './details'
import EditPipelineInfo from './edit-pipeline-info'

type TemplateCardProps = {
  pipeline: PipelineTemplate
  showMoreOperations?: boolean
  type: 'customized' | 'built-in'
}

const TemplateCard = ({ pipeline, showMoreOperations = true, type }: TemplateCardProps) => {
  const { t } = useTranslation()
  const { push } = useRouter()
  const [showEditModal, setShowEditModal] = useState(false)
  const [showDeleteConfirm, setShowConfirmDelete] = useState(false)
  const [showDetailModal, setShowDetailModal] = useState(false)

  const { refetch: getPipelineTemplateInfo } = usePipelineTemplateById(
    {
      template_id: pipeline.id,
      type,
    },
    false,
  )
  const { mutateAsync: createDataset } = useCreatePipelineDatasetFromCustomized()
  const { handleCheckPluginDependencies } = usePluginDependencies()
  const invalidDatasetList = useInvalidDatasetList()

  const handleUseTemplate = useCallback(async () => {
    const { data: pipelineTemplateInfo } = await getPipelineTemplateInfo()
    if (!pipelineTemplateInfo) {
      toast.error(t(($) => $['creation.errorTip'], { ns: 'datasetPipeline' }))
      return
    }
    const request = {
      yaml_content: pipelineTemplateInfo.export_data,
    }
    await createDataset(request, {
      onSuccess: async (newDataset) => {
        toast.success(t(($) => $['creation.successTip'], { ns: 'datasetPipeline' }))
        invalidDatasetList()
        if (newDataset.pipeline_id)
          await handleCheckPluginDependencies(newDataset.pipeline_id, true)
        trackEvent('create_datasets_with_pipeline', {
          template_name: pipeline.name,
          template_id: pipeline.id,
          template_type: type,
        })
        push(`/datasets/${newDataset.dataset_id}/pipeline`)
      },
      onError: () => {
        toast.error(t(($) => $['creation.errorTip'], { ns: 'datasetPipeline' }))
      },
    })
  }, [
    getPipelineTemplateInfo,
    createDataset,
    t,
    handleCheckPluginDependencies,
    push,
    invalidDatasetList,
    pipeline.name,
    pipeline.id,
    type,
  ])

  const handleShowTemplateDetails = useCallback(() => {
    setShowDetailModal(true)
  }, [])

  const openEditModal = useCallback(() => {
    setShowEditModal(true)
  }, [])

  const closeEditModal = useCallback(() => {
    setShowEditModal(false)
  }, [])

  const closeDetailsModal = useCallback(() => {
    setShowDetailModal(false)
  }, [])

  const { mutateAsync: exportPipelineDSL, isPending: isExporting } = useExportTemplateDSL()

  const handleExportDSL = useCallback(async () => {
    if (isExporting) return
    await exportPipelineDSL(pipeline.id, {
      onSuccess: (res) => {
        const blob = new Blob([res.data], { type: 'application/yaml' })
        downloadBlob({ data: blob, fileName: `${pipeline.name}.pipeline` })
        toast.success(t(($) => $['exportDSL.successTip'], { ns: 'datasetPipeline' }))
      },
      onError: () => {
        toast.error(t(($) => $['exportDSL.errorTip'], { ns: 'datasetPipeline' }))
      },
    })
  }, [t, isExporting, pipeline.id, pipeline.name, exportPipelineDSL])

  const handleDelete = useCallback(() => {
    setShowConfirmDelete(true)
  }, [])

  const onCancelDelete = useCallback(() => {
    setShowConfirmDelete(false)
  }, [])

  const { mutateAsync: deletePipeline } = useDeleteTemplate()
  const invalidCustomizedTemplateList = useInvalidCustomizedTemplateList()

  const onConfirmDelete = useCallback(async () => {
    await deletePipeline(pipeline.id, {
      onSuccess: () => {
        invalidCustomizedTemplateList()
        setShowConfirmDelete(false)
      },
    })
  }, [pipeline.id, deletePipeline, invalidCustomizedTemplateList])

  return (
    <div className="group relative flex h-[132px] cursor-pointer flex-col rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg pb-3 shadow-xs shadow-shadow-shadow-3">
      <Content
        name={pipeline.name}
        description={pipeline.description}
        iconInfo={pipeline.icon}
        chunkStructure={pipeline.chunk_structure}
      />
      <Actions
        onApplyTemplate={handleUseTemplate}
        handleShowTemplateDetails={handleShowTemplateDetails}
        showMoreOperations={showMoreOperations}
        openEditModal={openEditModal}
        handleExportDSL={handleExportDSL}
        handleDelete={handleDelete}
      />
      {showEditModal && (
        <Dialog
          open={showEditModal}
          onOpenChange={(open) => {
            if (!open) closeEditModal()
          }}
        >
          <DialogContent className="w-[calc(100vw-2rem)] max-w-[520px]! overflow-hidden! border-none p-0 text-left align-middle">
            <EditPipelineInfo pipeline={pipeline} onClose={closeEditModal} />
          </DialogContent>
        </Dialog>
      )}
      <AlertDialog open={showDeleteConfirm} onOpenChange={(open) => !open && onCancelDelete()}>
        <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(($) => $['deletePipeline.title'], { ns: 'datasetPipeline' })}
            </AlertDialogTitle>
            <AlertDialogDescription className="w-full system-md-regular wrap-break-word whitespace-pre-wrap text-text-tertiary">
              {t(($) => $['deletePipeline.content'], { ns: 'datasetPipeline' })}
            </AlertDialogDescription>
          </div>
          <AlertDialogActions>
            <AlertDialogCancelButton>
              {t(($) => $['operation.cancel'], { ns: 'common' })}
            </AlertDialogCancelButton>
            <AlertDialogConfirmButton onClick={onConfirmDelete}>
              {t(($) => $['operation.confirm'], { ns: 'common' })}
            </AlertDialogConfirmButton>
          </AlertDialogActions>
        </AlertDialogContent>
      </AlertDialog>
      {showDetailModal && (
        <Dialog
          open={showDetailModal}
          onOpenChange={(open) => {
            if (!open) closeDetailsModal()
          }}
        >
          <DialogContent className="h-[calc(100dvh-64px)] max-h-[calc(100dvh-64px)] w-[calc(100vw-2rem)] max-w-[1680px]! overflow-hidden! rounded-3xl border-none p-0 text-left align-middle">
            <Details
              id={pipeline.id}
              type={type}
              onClose={closeDetailsModal}
              onApplyTemplate={handleUseTemplate}
            />
          </DialogContent>
        </Dialog>
      )}
    </div>
  )
}

export default React.memo(TemplateCard)
