import type { StartNodeType } from '../nodes/start/types'
import { Button } from '@langgenius/dify-ui/button'
import { memo, useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useNodes } from 'reactflow'
import { useCheckInputsForms } from '@/app/components/base/chat/chat/check-input-forms-hooks'
import { getProcessedInputs } from '@/app/components/base/chat/chat/utils'
import { TransferMethod } from '../../base/text-generation/types'
import { useWorkflowRun } from '../hooks'
import { useHooksStore } from '../hooks-store'
import FormItem from '../nodes/_base/components/before-run-form/form-item'
import { useStore, useWorkflowStore } from '../store'
import { BlockEnum, InputVarType, WorkflowRunningStatus } from '../types'

type Props = Readonly<{
  onRun: () => void
}>

const InputsPanel = ({ onRun }: Props) => {
  const { t } = useTranslation()
  const workflowStore = useWorkflowStore()
  const inputs = useStore((s) => s.inputs)
  const fileSettings = useHooksStore((s) => s.configsMap?.fileSettings)
  const canRunWorkflow = useHooksStore((s) => s.accessControl.canRun)
  const nodes = useNodes<StartNodeType>()
  const files = useStore((s) => s.files)
  const workflowRunningData = useStore((s) => s.workflowRunningData)
  const { handleRun } = useWorkflowRun()
  const startNode = nodes.find((node) => node.data.type === BlockEnum.Start)
  const startVariables = startNode?.data.variables
  const { checkInputsForm } = useCheckInputsForms()

  const initialInputs = useMemo(() => {
    const result = { ...inputs }
    if (startVariables) {
      startVariables.forEach((variable) => {
        if (variable.default) result[variable.variable] = variable.default
        if (inputs[variable.variable] !== undefined)
          result[variable.variable] = inputs[variable.variable]!
      })
    }
    return result
  }, [inputs, startVariables])

  const variables = useMemo(() => {
    const data = startVariables || []
    if (fileSettings?.image?.enabled) {
      return [
        ...data,
        {
          type: InputVarType.files,
          variable: '__image',
          required: false,
          label: 'files',
        },
      ]
    }

    return data
  }, [fileSettings?.image?.enabled, startVariables])

  const handleValueChange = (variable: string, v: any) => {
    const { inputs, setInputs } = workflowStore.getState()
    if (variable === '__image') {
      workflowStore.setState({
        files: v,
      })
    } else {
      setInputs({
        ...inputs,
        [variable]: v,
      })
    }
  }

  const canRun = useMemo(() => {
    const canUploadReady = !files?.some(
      (item) => (item.transfer_method as any) === TransferMethod.local_file && !item.upload_file_id,
    )
    return canRunWorkflow && canUploadReady
  }, [canRunWorkflow, files])

  const doRun = useCallback(() => {
    if (!canRun) return
    if (!checkInputsForm(initialInputs, variables as any)) return
    onRun()
    handleRun({ inputs: getProcessedInputs(initialInputs, variables as any), files })
  }, [canRun, files, handleRun, initialInputs, onRun, variables, checkInputsForm])

  return (
    <>
      <div className="px-4 pt-3 pb-2">
        {variables.map((variable, index) => (
          <div key={variable.variable} className="mb-2 last-of-type:mb-0">
            <FormItem
              autoFocus={index === 0}
              className="block!"
              payload={variable}
              value={initialInputs[variable.variable]}
              onChange={(v) => handleValueChange(variable.variable, v)}
            />
          </div>
        ))}
      </div>
      <div className="flex items-center justify-between px-4 py-2">
        <Button
          variant="primary"
          disabled={
            !canRun || workflowRunningData?.result?.status === WorkflowRunningStatus.Running
          }
          className="w-full"
          onClick={doRun}
        >
          {t(($) => $['singleRun.startRun'], { ns: 'workflow' })}
        </Button>
      </div>
    </>
  )
}

export default memo(InputsPanel)
