import React, { useState, useEffect } from 'react'; /*necesitas esto para usar el hook de state*/
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Button, TouchableOpacity, TextInput, ScrollView, FlatList, Alert, TouchableWithoutFeedback, Keyboard ,AsyncStorage } from 'react-native';/*view es como div en html, text es como p y stylesheet es como si fuera css. Button es eso, touchableopacity es como a tag y textinput es eso
ScrollView permite al usuario hacer un scroll, FlatList hace un echo de elementos por parte si la lista es muy grande
alert es eso, 
touchablewithoutfeedback te permite capturar clicks sin avisar, por ejemplo metes todo la app y al hacer clic donde sea
cierras el keyboard (y ese componente pues se usa para eso, mostrar ocultar)*/

//https://reactnative.dev/docs/asyncstorage
//con Async Storage puedes guardar datos de la aplicación para que se puedan guardar aun después de cerrar la aplicacion, aunque la información no se encripta... aguas. Para instalarlo usas este comando (aunque este depreciado por el momento)
//npm install @react-native-async-storage/async-storage
//Y a lo mejor tienes que correr 
//expo doctor --fix-dependencies
//por si asyncstorage requiere otra versión con tu expo, pero esto te lo dice al correr npm run start
//import { AsyncStorage } from 'react-native';//esto podría ir arriba, junto a stylesheet


//Puedes usar el import para traer otros componentes que pongas en otros archivos, por ejemplo un header
import Header from './components/Header';
import Lista from './components/Lista';
import AddLista from './components/AddLista';
import FlexEjemplo from './components/FlexEjemplo';

export default function App() {
	
  const [todos, setTodos] = useState([
    { text: 'Presiona restaurar data, para leer lo que salvaste', key: '1' },
    { text: 'Antes de irte dale guardar', key: '2' },
    { text: 'si quieres borrar todo ya te imaginaras...', key: '3' }
  ]);
	const [primerRender, setPrimerRender] = useState(false);//para que cargue solo la primera vez los valores pre cargados
	const [nuevaTodo, setNuevaTodo] = useState(false);//para que use effect solo corra al agregarTodos()
	useEffect(()=>{//esto corre cada vez que hay un cambio de useState porque los valores solo se actualizan al renderizar
		if(!primerRender){//solo que haga esto en la carga inicial
			console.log("Carga inicial de asyncStorage");
			LeerData();//que cargue lo que sea que este almacenado
			setPrimerRender(true);
		}
		if(nuevaTodo){//solo que haga esto en la carga inicial
			console.log("Guarda autom de asyncStorage");
			GuardarData();//que cargue lo que sea que este almacenado
			setNuevaTodo(false);
		}		
	});
	//siempre cargue por default
  const borrarTodos = (key) => {
    setTodos(prevTodos => {
      return prevTodos.filter(todo => todo.key != key);
    });
	setNuevaTodo(true);//para que también salve los cambios en auto, usando useEffect	  
  };
  const sigKey = () => {
	let max=0;
	todos.map((feach) => {
		console.log("va "+feach.key);
		if(max < feach.key){
			max=feach.key;
			console.log("nuevo max "+max);
		}
	});
	max=(max*1)+1;
	console.log("sigue "+max);
	return max;
  };
	
  const agregarTodos = (text) => {
	const siguiente=sigKey();
	console.log("siguiente key: "+siguiente );
  
    if(text.length > 3){
     // setText('');//el resetear tiene que estar dentro del component
      setTodos(prevTodos => {
        return [
          { text, key: siguiente },//math random no es la mejor forma de hacer un key pero funciona por el momento... supongo podrias guardar en async el valor del ultimo key, o podrias hacer un loop con map que te diera el valor maximo...
          ...prevTodos
        ];
      } );
		setNuevaTodo(true);//para que también salve los cambios en auto, usando useEffect
    } else {
      Alert.alert('OOPS', 'Todo must be over 3 characters long', [
        {text: 'Understood', onPress: () => console.log('alert closed') }
      ]);
    }
  };
	
	const VaciarTodo = () =>{
		setTodos(prevTodos => {//primero borras todo lo que haya en Todo
			return prevTodos.filter(todo => todo.key == 0);//aqui regresarias solo los key que son 0, pero eso no existe aasi que vacia en teoria Todo, aunque no se  si es la mejor manera de hacerlo pero funciona
		});
	};
	//Ahora guardando data en asyncstorage
	const GuardaData = async (key,data) => {
	  try {
		await AsyncStorage.setItem(key,data);
		  // save data!!
		  //console.log("Salvado "+key+":"+data);
		  alert("Salvado "+key+":"+data);
	  } catch (error) {
		// Error saving data
		  console.log("Error salvar "+error);
	  }
	};
	/*useEffect(()=>{//Cada vez que se usa setTodos se corre esta función para que se actualice
		console.log("todos actual: "+JSON.stringify(todos));
		 GuardarData();
	},[todos]);/*Pero no logre hacerlo funcionar así que el guardado que sea manual...*/
	const LeeData = async (key) => {
	  try {
		const value = await AsyncStorage.getItem(key);
		if (value !== null) {
			let obj=JSON.parse(value);
			//alert(obj[2]["text"]);
			VaciarTodo();
			obj.map((feach) => {
				setTodos(prevTodos => {
					return [
						...prevTodos,//aqui va al reves por la función map que es un feach
						{ text:feach.text, key: feach.key }
					];
				});				
    			console.log(feach.key+"-"+feach.text);
			});
			//setTodos(value);//asi haces que se guarden los valores
		  // We have data!!
		  alert("leido "+key+":"+value);
		  return value;
		}else{
		  console.log("Error leer vacio");			
		}
	  } catch (error) {
		// Error retrieving data
		  console.log("Error leer "+error);
	  }
	};	
	const BorraData = async (key) => {
	  try {
		await AsyncStorage.removeItem(key);
		  alert("Borrado "+key);
	  } catch (error) {
		// Error retrieving data
		  console.log("Error borrar "+error);
	  }
	};		
	const GuardarData = () => {
		//JSON.stringify(data) así guardas todo como json o puedes 
		GuardaData("Que",JSON.stringify(todos));
		console.log(" voy a guardar "+JSON.stringify(todos));
	};
	const LeerData = () => {
		LeeData("Que");
		console.log(" voy a leer ");
	};
	const BorrarData = () => {
		BorraData("Que");
		console.log(" voy a borrar ");
		VaciarTodo();//para que borre lo que haya, total ya no esta en async
	};
	//esto no funciona porque cae en loops raros
	// GuardarData();//esto salva la info cada vez que se renderea...
	//LeerData();//y muestra lo ultimo
  return (
	<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>{/*esto hace que puedas capturar clicks en cualquier lugar*/}
    <View style={styles.container}>
      <Header />{/*Asi importas de otro jsx componentes*/}
	  {/*<FlexEjemplo />Ejemplo de como funciona el flex*/}
      <View style={styles.content}>
        <AddLista addTodos={agregarTodos}/>{/* add todo form */}
        <View style={styles.list}>
			{/*Si el id se llama key no requieres el keyextractor, pero es bueno acostumbrarte a tenerlo por si se llama item.id o algo asi*/}
          <FlatList
			keyExtractor={(item) => item.key} 
            data={todos}
            renderItem={({ item }) => (
				<Lista item={item} pressHandler={borrarTodos}/>
            )}
          />
        </View>
		<View style={styles.boton}><Button color="green" title="Salvar data (lo hace solo)" onPress={GuardarData}/></View>
		<View style={styles.boton}><Button color="orange" title="Restaurar data (lo hace solo)" onPress={LeerData}/></View>
		<View style={styles.boton}><Button color="red" title="Vaciar lista" onPress={BorrarData}/></View>
		{/*<View style={styles.boton}><Button color="orange" title="sig key" onPress={VaciarTodo}/></View>*/}
      </View>
    </View>
	</TouchableWithoutFeedback>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  content: {
    flex: 1,
    padding: 40,
	//backgroundColor: "lightblue",
  },
  list: {
    flex: 1,/*al tener un flex el elemento que se desborda, sale un scroll. Los parents también deben de tener flex*/
    marginTop: 20,
	//backgroundColor: "lightyellow",
  },
  boton: {
    marginTop: 5,
  },	
});