import { FC, useCallback, useMemo } from "react"
import { useSelector } from "react-redux"
import { CodeEditor } from "@/components/CodeEditor"
import {
  CODE_LANG,
  CODE_TYPE,
} from "@/components/CodeEditor/CodeMirror/extensions/interface"
import { BaseInputSetterProps } from "../interface"
import { getContainerListDisplayNameMappedChildrenNodeDisplayName } from "@/redux/currentApp/components/componentsSelector"
import { hasDynamicStringSnippet } from "@/redux/utils"
import { getNeedComputedValueWithList, realInputValueWithList } from "../util"
import { applyInputSetterWrapperStyle } from "../BaseInput/style"


const BaseUpload: FC<BaseInputSetterProps> = (props) => {
  const {
    className,
    isSetterSingleRow,
    placeholder,
    attrName,
    handleUpdateDsl,
    expectedType,
    value,
    widgetDisplayName,
    // isInList,
    labelName,
    detailedDescription,
    labelDesc,
    // widgetType,
    wrappedCodeFunc,
  } = props

  const listWidgets = useSelector(
    getContainerListDisplayNameMappedChildrenNodeDisplayName,
  )

  const currentListDisplayName = useMemo(() => {
    const listWidgetDisplayNames = Object.keys(listWidgets)
    for (let i = 0; i < listWidgetDisplayNames.length; i++) {
      if (listWidgets[listWidgetDisplayNames[i]].includes(widgetDisplayName)) {
        return listWidgetDisplayNames[i]
      }
    }
    return ""
  }, [listWidgets, widgetDisplayName])

  const finalWrapperCode = useMemo(() => {
    if (
      currentListDisplayName &&
      hasDynamicStringSnippet(value ?? "") &&
      value?.includes("currentItem")
    ) {
      return (value: string) => {
        return getNeedComputedValueWithList(value, currentListDisplayName)
      }
    }
    return wrappedCodeFunc
  }, [currentListDisplayName, value, wrappedCodeFunc])

  const finalValue = useMemo(() => {
    if (currentListDisplayName) {
      return realInputValueWithList(value, currentListDisplayName)
    }
    return value || ""
  }, [currentListDisplayName, value])

  const onChange = useCallback(
    (value: string) => {
      let output = value
      if (
        currentListDisplayName &&
        hasDynamicStringSnippet(value ?? "") &&
        value.includes("currentItem")
      ) {
        output = getNeedComputedValueWithList(value, currentListDisplayName)
      }
      handleUpdateDsl(attrName, output)
    },
    [attrName, currentListDisplayName, handleUpdateDsl],
  )

  return (
    <div css={applyInputSetterWrapperStyle(isSetterSingleRow)}>
      <CodeEditor
        scopeOfAutoComplete="page"
        className={className}
        value={finalValue}
        onChange={onChange}
        showLineNumbers={false}
        placeholder={placeholder}
        expectValueType={currentListDisplayName ? undefined : expectedType}
        lang={CODE_LANG.JAVASCRIPT}
        maxHeight="208px"
        maxWidth="100%"
        codeType={CODE_TYPE.EXPRESSION}
        modalTitle={labelName}
        modalDescription={detailedDescription ?? labelDesc}
        // onFocus={onFocus}
        // onBlur={onBlur}
        wrappedCodeFunc={finalWrapperCode}
      />
    </div>
  )
}

BaseUpload.displayName = "BaseInput"
export default BaseUpload
