import type { FC } from 'react'
import {
  DropdownMenu,
  DropdownMenuItem,
  DropdownMenuPopup,
  DropdownMenuPortal,
  DropdownMenuPositioner,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@langgenius/dify-ui/dropdown-menu'
import { useSuspenseQuery } from '@tanstack/react-query'
import { Fragment, memo } from 'react'
import { useTranslation } from 'react-i18next'
import { useReactFlow, useViewport } from 'reactflow'
import { systemFeaturesQueryOptions } from '@/features/system-features/client'
import { useNodesSyncDraft } from '../hooks/use-nodes-sync-draft'
import { useWorkflowReadOnly } from '../hooks/use-workflow'
import { ShortcutKbd } from '../shortcuts/shortcut-kbd'
import TipPopup from './tip-popup'

const ZoomType = {
  zoomToFit: 'zoomToFit',
  zoomTo25: 'zoomTo25',
  zoomTo50: 'zoomTo50',
  zoomTo75: 'zoomTo75',
  zoomTo100: 'zoomTo100',
  zoomTo200: 'zoomTo200',
  toggleUserComments: 'toggleUserComments',
  toggleUserCursors: 'toggleUserCursors',
  toggleMiniMap: 'toggleMiniMap',
} as const

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

type ZoomInOutProps = {
  showMiniMap?: boolean
  onToggleMiniMap?: () => void
  showUserCursors?: boolean
  onToggleUserCursors?: () => void
  showUserComments?: boolean
  onToggleUserComments?: () => void
  isCommentMode?: boolean
}

const ZoomInOut: FC<ZoomInOutProps> = ({
  showMiniMap = true,
  onToggleMiniMap,
  showUserCursors = true,
  onToggleUserCursors,
  showUserComments = true,
  onToggleUserComments,
  isCommentMode = false,
}) => {
  const { t } = useTranslation()
  const { zoomIn, zoomOut, zoomTo, fitView } = useReactFlow()
  const { zoom } = useViewport()
  const { handleSyncWorkflowDraft } = useNodesSyncDraft()
  const { workflowReadOnly, getWorkflowReadOnly } = useWorkflowReadOnly()
  const { data: isCollaborationEnabled } = useSuspenseQuery({
    ...systemFeaturesQueryOptions(),
    select: (s) => s.enable_collaboration_mode,
  })

  const zoomOptions = [
    [
      {
        key: ZoomType.zoomTo200,
        text: '200%',
      },
      {
        key: ZoomType.zoomTo100,
        text: '100%',
      },
      {
        key: ZoomType.zoomTo75,
        text: '75%',
      },
      {
        key: ZoomType.zoomTo50,
        text: '50%',
      },
      {
        key: ZoomType.zoomTo25,
        text: '25%',
      },
      {
        key: ZoomType.zoomToFit,
        text: t(($) => $['operator.zoomToFit'], { ns: 'workflow' }),
      },
    ],
    isCollaborationEnabled
      ? [
          {
            key: ZoomType.toggleUserComments,
            text: t(($) => $['operator.showUserComments'], { ns: 'workflow' }),
          },
          {
            key: ZoomType.toggleUserCursors,
            text: t(($) => $['operator.showUserCursors'], { ns: 'workflow' }),
          },
          {
            key: ZoomType.toggleMiniMap,
            text: t(($) => $['operator.showMiniMap'], { ns: 'workflow' }),
          },
        ]
      : [
          {
            key: ZoomType.toggleMiniMap,
            text: t(($) => $['operator.showMiniMap'], { ns: 'workflow' }),
          },
        ],
  ]

  const handleZoom = (type: ZoomType) => {
    if (workflowReadOnly) return

    if (type === ZoomType.zoomToFit) fitView()

    if (type === ZoomType.zoomTo25) zoomTo(0.25)

    if (type === ZoomType.zoomTo50) zoomTo(0.5)

    if (type === ZoomType.zoomTo75) zoomTo(0.75)

    if (type === ZoomType.zoomTo100) zoomTo(1)

    if (type === ZoomType.zoomTo200) zoomTo(2)

    if (type === ZoomType.toggleUserComments) {
      if (!isCommentMode) onToggleUserComments?.()

      return
    }

    if (type === ZoomType.toggleUserCursors) {
      onToggleUserCursors?.()
      return
    }

    if (type === ZoomType.toggleMiniMap) {
      onToggleMiniMap?.()
      return
    }

    handleSyncWorkflowDraft()
  }

  return (
    <div
      className={`h-9 cursor-pointer rounded-lg border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg p-0.5 text-[13px] shadow-lg backdrop-blur-[5px] hover:bg-state-base-hover ${workflowReadOnly && 'cursor-not-allowed! opacity-50'} `}
    >
      <div className="flex h-8 w-24.5 items-center justify-between rounded-lg">
        <TipPopup
          title={t(($) => $['operator.zoomOut'], { ns: 'workflow' })}
          shortcut="workflow.zoom-out"
        >
          <button
            type="button"
            aria-label={t(($) => $['operator.zoomOut'], { ns: 'workflow' })}
            disabled={zoom <= 0.25}
            className={`flex size-8 items-center justify-center rounded-lg ${zoom <= 0.25 ? 'cursor-not-allowed' : 'cursor-pointer hover:bg-black/5'}`}
            onClick={(e) => {
              if (zoom <= 0.25) return

              e.stopPropagation()
              zoomOut()
            }}
          >
            <span
              aria-hidden
              className="i-ri-zoom-out-line size-4 text-text-tertiary hover:text-text-secondary"
            />
          </button>
        </TipPopup>
        <DropdownMenu>
          <DropdownMenuTrigger
            disabled={getWorkflowReadOnly()}
            className="flex h-8 w-8.5 items-center justify-center rounded-lg system-sm-medium text-text-tertiary hover:bg-black/5 hover:text-text-secondary data-popup-open:bg-black/5 data-popup-open:text-text-secondary"
          >
            {Number.parseFloat(`${zoom * 100}`).toFixed(0)}%
          </DropdownMenuTrigger>
          <DropdownMenuPortal>
            <DropdownMenuPositioner placement="top-start" sideOffset={4} alignOffset={-2}>
              <DropdownMenuPopup>
                <div className="w-48 rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-[5px]">
                  {zoomOptions.map((options, groupIndex) => (
                    <Fragment key={options[0]!.key}>
                      {groupIndex !== 0 && <DropdownMenuSeparator className="my-0" />}
                      <div className="p-1">
                        {options.map((option) => (
                          <DropdownMenuItem
                            key={option.key}
                            className="justify-between px-3 py-1.5 system-md-regular text-text-secondary"
                            disabled={option.key === ZoomType.toggleUserComments && isCommentMode}
                            onClick={() => handleZoom(option.key)}
                          >
                            <div className="flex items-center gap-2">
                              {option.key === ZoomType.toggleUserComments && showUserComments && (
                                <span
                                  aria-hidden
                                  className="i-ri-check-line size-4 text-text-accent"
                                />
                              )}
                              {option.key === ZoomType.toggleUserComments && !showUserComments && (
                                <span aria-hidden className="size-4" />
                              )}
                              {option.key === ZoomType.toggleUserCursors && showUserCursors && (
                                <span
                                  aria-hidden
                                  className="i-ri-check-line size-4 text-text-accent"
                                />
                              )}
                              {option.key === ZoomType.toggleUserCursors && !showUserCursors && (
                                <span aria-hidden className="size-4" />
                              )}
                              {option.key === ZoomType.toggleMiniMap && showMiniMap && (
                                <span
                                  aria-hidden
                                  className="i-ri-check-line size-4 text-text-accent"
                                />
                              )}
                              {option.key === ZoomType.toggleMiniMap && !showMiniMap && (
                                <span aria-hidden className="size-4" />
                              )}
                              {option.key === ZoomType.zoomToFit && (
                                <span
                                  aria-hidden
                                  className="i-ri-fullscreen-line size-4 text-text-tertiary"
                                />
                              )}
                              {option.key !== ZoomType.toggleUserComments &&
                                option.key !== ZoomType.toggleUserCursors &&
                                option.key !== ZoomType.toggleMiniMap &&
                                option.key !== ZoomType.zoomToFit && (
                                  <span aria-hidden className="size-4" />
                                )}
                              <span>{option.text}</span>
                            </div>
                            <div className="flex items-center space-x-0.5">
                              {option.key === ZoomType.zoomToFit && (
                                <ShortcutKbd shortcut="workflow.zoom-to-fit" />
                              )}
                              {option.key === ZoomType.zoomTo50 && (
                                <ShortcutKbd shortcut="workflow.zoom-to-50" />
                              )}
                              {option.key === ZoomType.zoomTo100 && (
                                <ShortcutKbd shortcut="workflow.zoom-to-100" />
                              )}
                            </div>
                          </DropdownMenuItem>
                        ))}
                      </div>
                    </Fragment>
                  ))}
                </div>
              </DropdownMenuPopup>
            </DropdownMenuPositioner>
          </DropdownMenuPortal>
        </DropdownMenu>
        <TipPopup
          title={t(($) => $['operator.zoomIn'], { ns: 'workflow' })}
          shortcut="workflow.zoom-in"
        >
          <button
            type="button"
            aria-label={t(($) => $['operator.zoomIn'], { ns: 'workflow' })}
            disabled={zoom >= 2}
            className={`flex size-8 items-center justify-center rounded-lg ${zoom >= 2 ? 'cursor-not-allowed' : 'cursor-pointer hover:bg-black/5'}`}
            onClick={(e) => {
              if (zoom >= 2) return

              e.stopPropagation()
              zoomIn()
            }}
          >
            <span
              aria-hidden
              className="i-ri-zoom-in-line size-4 text-text-tertiary hover:text-text-secondary"
            />
          </button>
        </TipPopup>
      </div>
    </div>
  )
}

export default memo(ZoomInOut)
