import type { FormInputItem, FormInputItemDefault } from '@/app/components/workflow/nodes/human-input/types'
import type { ValueSelector } from '@/app/components/workflow/types'
import { Button } from '@langgenius/dify-ui/button'
import { Kbd, KbdGroup } from '@langgenius/dify-ui/kbd'
import { formatForDisplay } from '@tanstack/react-hotkeys'
import { produce } from 'immer'
import * as React from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '@/app/components/base/input'
import { InputVarType } from '@/app/components/workflow/types'
import PrePopulate from './pre-populate'

const i18nPrefix = 'nodes.humanInput.insertInputField'

type InputFieldProps = {
  nodeId: string
  isEdit: boolean
  payload?: FormInputItem
  onChange: (newPayload: FormInputItem) => void
  onCancel: () => void
}
const defaultPayload: FormInputItem = {
  type: InputVarType.paragraph,
  output_variable_name: '',
  default: { type: 'constant', selector: [], value: '' },
}
const InputField: React.FC<InputFieldProps> = ({
  nodeId,
  isEdit,
  payload,
  onChange,
  onCancel,
}) => {
  const { t } = useTranslation()
  const [tempPayload, setTempPayload] = useState(payload || defaultPayload)
  const nameValid = useMemo(() => {
    const name = tempPayload.output_variable_name.trim()
    if (!name)
      return false
    if (name.includes(' '))
      return false
    return /^[a-z_]\w{0,29}$/.test(name)
  }, [tempPayload.output_variable_name])
  const handleSave = useCallback(() => {
    if (!nameValid)
      return
    onChange(tempPayload)
  }, [nameValid, onChange, tempPayload])
  const defaultValueConfig = tempPayload.default
  const handleDefaultValueChange = useCallback((key: keyof FormInputItemDefault) => {
    return (value: ValueSelector | string) => {
      const nextValue = produce(tempPayload, (draft) => {
        if (!draft.default)
          draft.default = { type: 'constant', selector: [], value: '' }
        if (key === 'selector') {
          draft.default.type = 'variable'
          draft.default.selector = value as ValueSelector
        }
        else if (key === 'value') {
          draft.default.type = 'constant'
          draft.default.value = value as string
        }
        else if (key === 'type') {
          draft.default.type = value as 'constant' | 'variable'
        }
      })
      setTempPayload(nextValue)
    }
  }, [tempPayload])

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
        e.preventDefault()
        handleSave()
      }
    }
    window.addEventListener('keydown', handleKeyDown)
    return () => {
      window.removeEventListener('keydown', handleKeyDown)
    }
  }, [handleSave])

  return (
    <div className="w-[372px]
     rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-3 shadow-lg backdrop-blur-[5px]"
    >
      <div className="system-md-semibold text-text-primary">{t(`${i18nPrefix}.title`, { ns: 'workflow' })}</div>
      <div className="mt-3">
        <div className="system-xs-medium text-text-secondary">
          {t(`${i18nPrefix}.saveResponseAs`, { ns: 'workflow' })}
          <span className="relative system-xs-regular text-text-destructive-secondary">*</span>
        </div>
        <Input
          className="mt-1.5"
          placeholder={t(`${i18nPrefix}.saveResponseAsPlaceholder`, { ns: 'workflow' })}
          value={tempPayload.output_variable_name}
          onChange={(e) => {
            setTempPayload(prev => ({ ...prev, output_variable_name: e.target.value }))
          }}
          autoFocus
        />
        {tempPayload.output_variable_name && !nameValid && (
          <div className="mt-1 px-1 system-xs-regular text-text-destructive-secondary">
            {t(`${i18nPrefix}.variableNameInvalid`, { ns: 'workflow' })}
          </div>
        )}
      </div>
      <div className="mt-4">
        <div className="mb-1.5 system-xs-medium text-text-secondary">
          {t(`${i18nPrefix}.prePopulateField`, { ns: 'workflow' })}
        </div>
        <PrePopulate
          isVariable={defaultValueConfig?.type === 'variable'}
          onIsVariableChange={(isVariable) => {
            handleDefaultValueChange('type')(isVariable ? 'variable' : 'constant')
          }}
          nodeId={nodeId}
          valueSelector={defaultValueConfig?.selector}
          onValueSelectorChange={handleDefaultValueChange('selector')}
          value={defaultValueConfig?.value}
          onValueChange={handleDefaultValueChange('value')}
        />
      </div>
      <div className="mt-4 flex justify-end space-x-2">
        <Button onClick={onCancel}>{t('operation.cancel', { ns: 'common' })}</Button>
        {isEdit
          ? (
              <Button
                variant="primary"
                onClick={handleSave}
                disabled={!nameValid}
              >
                {t('operation.save', { ns: 'common' })}
              </Button>
            )
          : (
              <Button
                className="flex"
                variant="primary"
                disabled={!nameValid}
                onClick={handleSave}
              >
                <span className="mr-1">{t(`${i18nPrefix}.insert`, { ns: 'workflow' })}</span>
                <KbdGroup>
                  {['Mod', 'Enter'].map(key => (
                    <Kbd key={key} color="white">{formatForDisplay(key)}</Kbd>
                  ))}
                </KbdGroup>
              </Button>
            )}

      </div>
    </div>
  )
}

export default InputField
