import type { FC } from 'react'
import type { ExternalDataTool } from '@/models/common'
import { Button } from '@langgenius/dify-ui/button'
import { Dialog, DialogContent } from '@langgenius/dify-ui/dialog'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectItemIndicator,
  SelectItemText,
  SelectTrigger,
  SelectValue,
} from '@langgenius/dify-ui/select'
import { toast } from '@langgenius/dify-ui/toast'
import { noop } from 'es-toolkit/function'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import EmojiPicker from '@/app/components/base/emoji-picker'
import FormGeneration from '@/app/components/base/features/new-feature-panel/moderation/form-generation'
import { BookOpen01 } from '@/app/components/base/icons/src/vender/line/education'
import { ApiBasedExtensionSelector } from '@/app/components/header/account-setting/api-based-extension-page/selector'
import { useDocLink, useLocale } from '@/context/i18n'
import { useCodeBasedExtensions } from '@/service/use-common'
import {
  buildProviders,
  formatExternalDataTool,
  getProviderDefaultConfig,
  getValidationError,
} from './external-data-tool-modal-utils'

type ExternalDataToolModalProps = {
  data: ExternalDataTool
  onCancel: () => void
  onSave: (externalDataTool: ExternalDataTool) => void
  onValidateBeforeSave?: (externalDataTool: ExternalDataTool) => boolean
}
const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
  data,
  onCancel,
  onSave,
  onValidateBeforeSave,
}) => {
  const { t } = useTranslation()
  const docLink = useDocLink()
  const locale = useLocale()
  const [localeData, setLocaleData] = useState(data.type ? data : { ...data, type: 'api' })
  const [showEmojiPicker, setShowEmojiPicker] = useState(false)
  const { data: codeBasedExtensionList } = useCodeBasedExtensions('external_data_tool')

  const providers = buildProviders({
    codeBasedExtensionList,
    locale,
    t,
  })
  const currentProvider = providers.find((provider) => provider.key === localeData.type)

  const handleDataTypeChange = (type: string) => {
    setLocaleData({
      ...localeData,
      type,
      config: getProviderDefaultConfig(type, providers),
    })
  }

  const handleDataExtraChange = (extraValue: Record<string, string>) => {
    setLocaleData({
      ...localeData,
      config: {
        ...localeData.config,
        ...extraValue,
      },
    })
  }

  const handleValueChange = (value: Record<string, string>) => {
    setLocaleData({
      ...localeData,
      ...value,
    })
  }

  const handleDataApiBasedChange = (apiBasedExtensionId: string) => {
    setLocaleData({
      ...localeData,
      config: {
        ...localeData.config,
        api_based_extension_id: apiBasedExtensionId,
      },
    })
  }

  const handleSave = () => {
    const validationError = getValidationError({
      currentProvider,
      locale,
      localeData,
      t,
    })
    if (validationError) {
      toast.error(validationError)
      return
    }

    const formattedData = formatExternalDataTool(localeData, currentProvider, !!data.type)

    if (onValidateBeforeSave && !onValidateBeforeSave(formattedData)) return

    onSave(formattedData)
  }

  const action = data.type
    ? t(($) => $['operation.edit'], { ns: 'common' })
    : t(($) => $['operation.add'], { ns: 'common' })

  return (
    <Dialog open onOpenChange={noop}>
      <DialogContent className="w-[640px]! max-w-none! p-8! pb-6!">
        <div className="mb-2 text-xl font-semibold text-text-primary">
          {`${action} ${t(($) => $['variableConfig.apiBasedVar'], { ns: 'appDebug' })}`}
        </div>
        <div className="py-2">
          <div className="text-sm/9 font-medium text-text-primary">
            {t(($) => $['apiBasedExtension.type'], { ns: 'common' })}
          </div>
          <Select
            defaultValue={localeData.type}
            onValueChange={(value) => value && handleDataTypeChange(value)}
          >
            <SelectTrigger
              className="w-full"
              aria-label={t(($) => $['apiBasedExtension.type'], { ns: 'common' })}
            >
              <SelectValue />
            </SelectTrigger>
            <SelectContent popupClassName="w-[354px]">
              {providers.map((option) => (
                <SelectItem key={option.key} value={option.key}>
                  <SelectItemText>{option.name}</SelectItemText>
                  <SelectItemIndicator />
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div className="py-2">
          <div className="text-sm/9 font-medium text-text-primary">
            {t(($) => $['feature.tools.modal.name.title'], { ns: 'appDebug' })}
          </div>
          <div className="flex items-center">
            <input
              value={localeData.label || ''}
              onChange={(e) => handleValueChange({ label: e.target.value })}
              className="mr-2 block h-9 grow appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-components-input-text-filled outline-hidden"
              placeholder={
                t(($) => $['feature.tools.modal.name.placeholder'], { ns: 'appDebug' }) || ''
              }
            />
            <AppIcon
              size="large"
              onClick={() => {
                setShowEmojiPicker(true)
              }}
              className="h-9! w-9! cursor-pointer rounded-lg border-[0.5px] border-components-panel-border"
              icon={localeData.icon}
              background={localeData.icon_background}
            />
          </div>
        </div>
        <div className="py-2">
          <div className="text-sm/9 font-medium text-text-primary">
            {t(($) => $['feature.tools.modal.variableName.title'], { ns: 'appDebug' })}
          </div>
          <input
            value={localeData.variable || ''}
            onChange={(e) => handleValueChange({ variable: e.target.value })}
            className="block h-9 w-full appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-components-input-text-filled outline-hidden"
            placeholder={
              t(($) => $['feature.tools.modal.variableName.placeholder'], { ns: 'appDebug' }) || ''
            }
          />
        </div>
        {localeData.type === 'api' && (
          <div className="py-2">
            <div className="flex h-9 items-center justify-between text-sm font-medium text-text-primary">
              {t(($) => $['apiBasedExtension.selector.title'], { ns: 'common' })}
              <a
                href={docLink('/use-dify/workspace/api-extension/api-extension')}
                target="_blank"
                rel="noopener noreferrer"
                className="group flex items-center text-xs font-normal text-text-tertiary hover:text-text-accent"
              >
                <BookOpen01 className="mr-1 size-3 text-text-tertiary group-hover:text-text-accent" />
                {t(($) => $['apiBasedExtension.link'], { ns: 'common' })}
              </a>
            </div>
            <ApiBasedExtensionSelector
              value={localeData.config?.api_based_extension_id || ''}
              onChange={handleDataApiBasedChange}
            />
          </div>
        )}
        {localeData.type !== 'api' && currentProvider?.form_schema && (
          <FormGeneration
            forms={currentProvider?.form_schema}
            value={localeData.config}
            onChange={handleDataExtraChange}
          />
        )}
        <div className="mt-6 flex items-center justify-end">
          <Button onClick={onCancel} className="mr-2">
            {t(($) => $['operation.cancel'], { ns: 'common' })}
          </Button>
          <Button variant="primary" onClick={handleSave}>
            {t(($) => $['operation.save'], { ns: 'common' })}
          </Button>
        </div>
        {showEmojiPicker && (
          <EmojiPicker
            open={showEmojiPicker}
            onOpenChange={setShowEmojiPicker}
            onSelect={(icon, icon_background) => {
              handleValueChange({ icon, icon_background })
            }}
          />
        )}
      </DialogContent>
    </Dialog>
  )
}

export default ExternalDataToolModal
