'use client'
import type { UpdateFromMarketPlacePayload } from '../types'
import { Button } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import { Dialog, DialogCloseButton, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog'
import { toast } from '@langgenius/dify-ui/toast'
import * as React from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Badge, { BadgeState } from '@/app/components/base/badge/index'
import Card from '@/app/components/plugins/card'
import checkTaskStatus from '@/app/components/plugins/install-plugin/base/check-task-status'
import { pluginManifestToCardPluginProps } from '@/app/components/plugins/install-plugin/utils'
import { updateFromMarketPlace } from '@/service/plugins'
import { usePluginTaskList, useRemoveAutoUpgrade } from '@/service/use-plugins'
import useGetIcon from '../install-plugin/base/use-get-icon'
import { TaskStatus } from '../types'
import DowngradeWarningModal from './downgrade-warning'

const i18nPrefix = 'upgrade'

type Props = Readonly<{
  payload: UpdateFromMarketPlacePayload
  pluginId?: string
  onSave: () => void
  onCancel: () => void
  isShowDowngradeWarningModal?: boolean
}>

type FailedUpgradeResponse = {
  task?: {
    status?: TaskStatus
    plugins?: Array<{
      plugin_unique_identifier: string
      message: string
    }>
  }
}

const UploadStep = {
  notStarted: 'notStarted',
  upgrading: 'upgrading',
  installed: 'installed',
} as const

type UploadStep = (typeof UploadStep)[keyof typeof UploadStep]

const UpdatePluginModal = ({
  payload,
  pluginId,
  onSave,
  onCancel,
  isShowDowngradeWarningModal,
}: Props) => {
  const { originalPackageInfo, targetPackageInfo } = payload
  const { t } = useTranslation()
  const { getIconUrl } = useGetIcon()
  const [icon, setIcon] = useState<string>(originalPackageInfo.payload.icon)
  useEffect(() => {
    ;(async () => {
      const icon = await getIconUrl(originalPackageInfo.payload.icon)
      setIcon(icon)
    })()
  }, [originalPackageInfo, getIconUrl])
  const { check, stop } = checkTaskStatus()
  const handleCancel = () => {
    stop()
    onCancel()
  }

  const [uploadStep, setUploadStep] = useState<UploadStep>(UploadStep.notStarted)
  const { handleInstallTaskStart } = usePluginTaskList(payload.category)

  const configBtnText = useMemo(() => {
    return {
      [UploadStep.notStarted]: t(($) => $[`${i18nPrefix}.upgrade`], { ns: 'plugin' }),
      [UploadStep.upgrading]: t(($) => $[`${i18nPrefix}.upgrading`], { ns: 'plugin' }),
      [UploadStep.installed]: t(($) => $[`${i18nPrefix}.close`], { ns: 'plugin' }),
    }[uploadStep]
  }, [t, uploadStep])

  const handleConfirm = useCallback(async () => {
    if (uploadStep === UploadStep.notStarted) {
      setUploadStep(UploadStep.upgrading)
      try {
        const response = (await updateFromMarketPlace({
          original_plugin_unique_identifier: originalPackageInfo.id,
          new_plugin_unique_identifier: targetPackageInfo.id,
        })) as Awaited<ReturnType<typeof updateFromMarketPlace>> & FailedUpgradeResponse

        if (response.task?.status === TaskStatus.failed) {
          const failedPlugin =
            response.task.plugins?.find(
              (plugin) => plugin.plugin_unique_identifier === targetPackageInfo.id,
            ) ?? response.task.plugins?.[0]
          toast.error(failedPlugin?.message || t(($) => $.error, { ns: 'common' }))
          setUploadStep(UploadStep.notStarted)
          return
        }

        const { all_installed: isInstalled, task_id: taskId } = response

        if (isInstalled) {
          onSave()
          return
        }
        handleInstallTaskStart(response)
        const { status, error } = await check({
          taskId,
          pluginUniqueIdentifier: targetPackageInfo.id,
        })
        if (status === TaskStatus.failed) {
          toast.error(error!)
          setUploadStep(UploadStep.notStarted)
          return
        }
        onSave()
      } catch {
        setUploadStep(UploadStep.notStarted)
      }
      return
    }
    if (uploadStep === UploadStep.installed) onSave()
  }, [
    onSave,
    uploadStep,
    check,
    originalPackageInfo.id,
    handleInstallTaskStart,
    t,
    targetPackageInfo.id,
  ])

  const { mutateAsync } = useRemoveAutoUpgrade()
  const handleExcludeAndDownload = async () => {
    if (pluginId) {
      await mutateAsync({
        plugin_id: pluginId,
        category: payload.category,
      })
    }
    handleConfirm()
  }
  const doShowDowngradeWarningModal =
    isShowDowngradeWarningModal && uploadStep === UploadStep.notStarted

  return (
    <Dialog open onOpenChange={() => onCancel()}>
      <DialogContent
        backdropProps={{ forceRender: true }}
        className={cn('min-w-[560px]', doShowDowngradeWarningModal && 'min-w-[640px]')}
      >
        <DialogCloseButton />
        {doShowDowngradeWarningModal && (
          <DowngradeWarningModal
            onCancel={onCancel}
            onJustDowngrade={handleConfirm}
            onExcludeAndDowngrade={handleExcludeAndDownload}
          />
        )}
        {!doShowDowngradeWarningModal && (
          <>
            <DialogTitle className="title-2xl-semi-bold text-text-primary">
              {t(
                ($) =>
                  $[
                    `${i18nPrefix}.${uploadStep === UploadStep.installed ? 'successfulTitle' : 'title'}`
                  ],
                { ns: 'plugin' },
              )}
            </DialogTitle>
            <div className="mt-3 mb-2 system-md-regular text-text-secondary">
              {t(($) => $[`${i18nPrefix}.description`], { ns: 'plugin' })}
            </div>
            <div className="flex flex-wrap content-start items-start gap-1 self-stretch rounded-2xl bg-background-section-burn p-2">
              <Card
                installed={uploadStep === UploadStep.installed}
                payload={pluginManifestToCardPluginProps({
                  ...originalPackageInfo.payload,
                  icon: icon!,
                })}
                className="w-full"
                titleLeft={
                  <>
                    <Badge className="mx-1" size="s" state={BadgeState.Warning}>
                      {`${originalPackageInfo.payload.version} -> ${targetPackageInfo.version}`}
                    </Badge>
                  </>
                }
              />
            </div>
            <div className="flex items-center justify-end gap-2 self-stretch pt-5">
              {uploadStep === UploadStep.notStarted && (
                <Button onClick={handleCancel}>
                  {t(($) => $['operation.cancel'], { ns: 'common' })}
                </Button>
              )}
              <Button
                variant="primary"
                loading={uploadStep === UploadStep.upgrading}
                onClick={handleConfirm}
                disabled={uploadStep === UploadStep.upgrading}
              >
                {configBtnText}
              </Button>
            </div>
          </>
        )}
      </DialogContent>
    </Dialog>
  )
}
export default React.memo(UpdatePluginModal)
