'use client'
import type { ChangeEvent, FC } from 'react'
import type { VarGroupItem as VarGroupItemType } from '../types'
import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
import { toast } from '@langgenius/dify-ui/toast'
import {
  RiDeleteBinLine,
} from '@remixicon/react'
import { useBoolean } from 'ahooks'
import { produce } from 'immer'
import * as React from 'react'
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { Folder } from '@/app/components/base/icons/src/vender/line/files'
import Field from '@/app/components/workflow/nodes/_base/components/field'
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
import { VarType } from '@/app/components/workflow/types'
import { checkKeys, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var'
import VarReferencePicker from '../../_base/components/variable/var-reference-picker'
import VarList from '../components/var-list'

const i18nPrefix = 'nodes.variableAssigner'

type Payload = VarGroupItemType & {
  group_name?: string
}

type Props = Readonly<{
  readOnly: boolean
  nodeId: string
  payload: Payload
  onChange: (newPayload: Payload) => void
  groupEnabled: boolean
  onGroupNameChange?: (value: string) => void
  canRemove?: boolean
  onRemove?: () => void
  availableVars: NodeOutPutVar[]
}>

const VarGroupItem: FC<Props> = ({
  readOnly,
  nodeId,
  payload,
  onChange,
  groupEnabled,
  onGroupNameChange,
  canRemove,
  onRemove,
  availableVars,
}) => {
  const { t } = useTranslation()

  const handleAddVariable = useCallback((value: ValueSelector | string, _varKindType: VarKindType, varInfo?: Var) => {
    const chosenVariables = payload.variables
    if (chosenVariables.some(item => item.join('.') === (value as ValueSelector).join('.')))
      return

    const newPayload = produce(payload, (draft: Payload) => {
      draft.variables.push(value as ValueSelector)
      if (varInfo && varInfo.type !== VarType.any)
        draft.output_type = varInfo.type
    })
    onChange(newPayload)
  }, [onChange, payload])

  const handleListChange = useCallback((newList: ValueSelector[], changedItem?: ValueSelector) => {
    if (changedItem) {
      const chosenVariables = payload.variables
      if (chosenVariables.some(item => item.join('.') === (changedItem as ValueSelector).join('.')))
        return
    }

    const newPayload = produce(payload, (draft) => {
      draft.variables = newList
      if (newList.length === 0)
        draft.output_type = VarType.any
    })
    onChange(newPayload)
  }, [onChange, payload])

  const filterVar = useCallback((varPayload: Var) => {
    if (payload.output_type === VarType.any)
      return true
    return varPayload.type === payload.output_type
  }, [payload.output_type])

  const [isEditGroupName, {
    setTrue: setEditGroupName,
    setFalse: setNotEditGroupName,
  }] = useBoolean(false)

  const handleGroupNameChange = useCallback((e: ChangeEvent<any>) => {
    replaceSpaceWithUnderscoreInVarNameInput(e.target)
    const value = e.target.value
    const { isValid, errorKey, errorMessageKey } = checkKeys([value], false)
    if (!isValid) {
      toast.error(t(`varKeyError.${errorMessageKey}`, { ns: 'appDebug', key: errorKey }))
      return
    }
    onGroupNameChange?.(value)
  }, [onGroupNameChange, t])

  return (
    <Field
      className="group"
      title={groupEnabled
        ? (
            <div className="flex items-center">
              <div className="flex items-center normal-case!">
                <Folder className="mr-0.5 size-3.5" />
                {(!isEditGroupName)
                  ? (
                      <div className="flex h-6 cursor-text items-center rounded-lg px-1 system-sm-semibold text-text-secondary hover:bg-gray-100" onClick={setEditGroupName}>
                        {payload.group_name}
                      </div>
                    )
                  : (
                      <input
                        type="text"
                        className="h-6 rounded-lg border border-gray-300 bg-white px-1 focus:outline-hidden"
                        // style={{
                        //   width: `${((payload.group_name?.length || 0) + 1) / 2}em`,
                        // }}
                        size={payload.group_name?.length} // to fit the input width
                        autoFocus
                        value={payload.group_name}
                        onChange={handleGroupNameChange}
                        onBlur={setNotEditGroupName}
                        maxLength={30}
                      />
                    )}

              </div>
              {canRemove && (
                <div
                  className="ml-0.5 hidden cursor-pointer rounded-md p-1 text-text-tertiary group-hover:block hover:bg-state-destructive-hover hover:text-text-destructive"
                  onClick={onRemove}
                >
                  <RiDeleteBinLine
                    className="size-4"
                  />
                </div>
              )}
            </div>
          )
        : t(`${i18nPrefix}.title`, { ns: 'workflow' })!}
      operations={(
        <div className="flex h-6 items-center space-x-2">
          {payload.variables.length > 0 && (
            <div className="flex h-[18px] items-center rounded-[5px] border border-divider-deep px-1 system-2xs-medium-uppercase text-text-tertiary">{payload.output_type}</div>
          )}
          {
            !readOnly
              ? (
                  <VarReferencePicker
                    isAddBtnTrigger
                    readonly={false}
                    nodeId={nodeId}
                    isShowNodeName
                    value={[]}
                    onChange={handleAddVariable}
                    defaultVarKindType={VarKindType.variable}
                    filterVar={filterVar}
                    availableVars={availableVars}
                  />
                )
              : undefined
          }
        </div>
      )}
    >
      <VarList
        readonly={readOnly}
        nodeId={nodeId}
        list={payload.variables}
        onChange={handleListChange}
        filterVar={filterVar}
      />
    </Field>
  )
}
export default React.memo(VarGroupItem)
