import TextField from "@mui/material/TextField"
import InputAdornment from "@mui/material/InputAdornment"
import IconButton from "@mui/material/IconButton"
import AddIcon from "@mui/icons-material/Add"
import RemoveIcon from "@mui/icons-material/Remove"
import {int_regex, float_regex} from "./utils"
import {render_description} from "./description"

export function render({model, el, view}) {
  const [color] = model.useState("color")
  const [disabled] = model.useState("disabled")
  const [format] = model.useState("format")
  const [label] = model.useState("label")
  const [placeholder] = model.useState("placeholder")
  const [step] = model.useState("step")
  const [min] = model.useState("start")
  const [max] = model.useState("end")
  const [size] = model.useState("size")
  const [variant] = model.useState("variant")
  const [sx] = model.useState("sx")
  const [value, setValue] = model.useState("value")

  const [oldValue, setOldValue] = React.useState(value)
  const [focused, setFocused] = React.useState(false)
  const [editableValue, setEditableValue] = React.useState(value)
  const [valueLabel, setValueLabel] = React.useState()

  const ref = React.useRef(null)
  model.on("msg:custom", (msg) => {
    ref.current?.focus()
  })

  const validate = (value) => {
    const regex = model.mode == "int" ? int_regex : float_regex
    if (value === "" || ["", "-", ".", "-."].includes(value)) {
      return null
    } else if (regex.test(value)) {
      return Number(value)
    } else {
      return oldValue
    }
  }

  React.useEffect(() => {
    if (focused) {
      setOldValue(value)
    } else {
      const newValue = validate(editableValue)
      setValue(newValue)
    }
  }, [focused])

  React.useEffect(() => {
    setEditableValue(value)
  }, [value])

  React.useEffect(() => {
    setValueLabel(format && !focused ? format.doFormat([value], {loc: 0})[0] : editableValue)
  }, [format, value, editableValue, focused])

  const increment = (multiplier = 1) => {
    setOldValue(value)
    if (value === null) {
      setValue(min != null ? min : 0)
    } else {
      const incremented = Math.round((value + (step * multiplier)) * 100000000000) / 100000000000
      setValue(max != null ? Math.min(max, incremented) : incremented)
    }
  }
  const decrement = (multiplier = 1) => {
    setOldValue(value)
    if (value === null) {
      setValue(max != null ? max : 0)
    } else {
      const decremented = Math.round((value - (step * multiplier)) * 100000000000) / 100000000000
      setValue(min != null ? Math.max(min, decremented) : decremented)
    }
  }

  const handleKeyDown = (e) => {
    if (e.key === "Enter") {
      setFocused(false)
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      increment();
    } else if (e.key === "ArrowDown") {
      e.preventDefault();
      decrement();
    } else if (e.key === "PageUp") {
      e.preventDefault();
      increment(model.page_step_multiplier);
    } else if (e.key === "PageDown") {
      e.preventDefault();
      decrement(model.page_step_multiplier);
    }
  }
  return (
    <TextField
      color={color}
      disabled={disabled}
      fullWidth
      inputRef={ref}
      label={model.description ? <>{label}{render_description({model, el, view})}</> : label}
      onBlur={() => setFocused(false)}
      onChange={(event) => { setEditableValue(event.target.value) }}
      onFocus={() => setFocused(true)}
      onKeyDown={handleKeyDown}
      placeholder={placeholder}
      size={size}
      sx={sx}
      value={valueLabel}
      variant={variant}
      InputProps={{
        inputMode: "decimal",
        sx: {padding: 0},
        startAdornment: (
          <InputAdornment position="start">
            <IconButton onClick={() => decrement()} size="small" color="default">
              <RemoveIcon fontSize="small" />
            </IconButton>
          </InputAdornment>
        ),
        endAdornment: (
          <InputAdornment position="end">
            <IconButton onClick={() => increment()} size="small" color="default">
              <AddIcon fontSize="small" />
            </IconButton>
          </InputAdornment>
        ),
      }}
    />
  );
}
