import React, { useContext, useEffect, useRef, useState } from "react";
import { useDispatch } from "react-redux";
import { processOptions, FormContext, appActions, localStorageGetItem, localStorageSetItem } from "../..";
/**
* Componente que renderiza un input únicamente cuando tiene propiedades asignadas por parametros o variables (de lo contrario el componente será nativo)
* @name Reactor.Components.Input.Input
* @param {string} [options = {}] Json string con las propiedades React que se quieran asignar al componente
* @param {("true"|"false")} [use_local_storage = "false"] Si es true el dato se guarda en el storage del explorador y la próxima vez que se renderice recordará el valor
* @param {string?} storage_name El nombre que usara para guardar el dato en el storage, si no se pasa este parámetro se usara el name del input
* @param {string?} change_var Variable que tomará el valor del control cuando se modifique
* @param {string?} context Contexto donde se encuentra la variable
* @param {("true"|"false")} [disabled = "false"] Si es true deshabilita el control
* @param {("true"|"false")} [use_change = "true"] Si es true, al modificarse su valor desencadena el evento change del form que lo contiene
* @class
* @example
<input
name="{{InputName}}"
use_local_storage="true"
storage_name="_nombre"
options='{"className":"input-class"}'
value="Pepe"
/>
<input_oqt
name="nombre"
value="Pepe"
change_var="variable"
context="contexto"
/>
*/
export const InputOqt = React.memo( ({defaultValue, use_local_storage, storage_name, disabled = "false", options, children, ...props}) => {
const inputRef = useRef();
const use_storage = use_local_storage === "true" && (storage_name || props.name);
const var_storage = use_storage && `input_${storage_name || props.name}`;
const use_options = processOptions(options);
const dispatch = useDispatch();
const [value, setValue] = useState(() => use_storage ? localStorageGetItem(var_storage) : (defaultValue || props.value));
const [loaded, setLoaded] = useState(false);
const [selectionStart, setSelectionStart] = useState(0);
const formContext = useContext(FormContext)
const handleChange = (event) => {
setSelectionStart(event.target.selectionStart);
if (props.change_var && props.context) {
dispatch(appActions.setVariable(props.change_var, event.target.value, props.context));
}else{
setValue(event.target.value);
}
if(use_storage){
localStorageSetItem(var_storage, event.target.value);
}
}
useEffect(()=>{
if (inputRef.current.getAttribute("use_change") === "false") return;
if (props.type!=="submit" && loaded) {
formContext.change({target: inputRef.current});
}
}, [value]);
useEffect(()=>{
if(!use_storage && (defaultValue || props.value)){
setValue(defaultValue || props.value);
if(props.change_var && props.context && inputRef.current.selectionStart){
setTimeout(
()=>{
inputRef.current.selectionStart = selectionStart;
inputRef.current.selectionEnd = selectionStart;
}, 10
)
}
}
if(!loaded) setLoaded(true);
}, [defaultValue, use_storage, props.value, loaded]);
useEffect(()=>{
if(props.autoFocus || (use_options && use_options.autoFocus)){
inputRef && inputRef.current && inputRef.current.focus()
}
}, [])
const newProps = {ref: inputRef, disabled: disabled === "true", value, onChange: handleChange, ...props, ...use_options};
return <><input {...newProps} /> {children}</>
});