// global.Buffer = require('buffer').Buffer;
import React, { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import { Alert, Animated, Keyboard } from 'react-native';
import {
  TextInput,
  Button,
  PermissionsAndroid,
  StatusBar,
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity,
  ScrollView,
  FlatList,
  Dimensions
} from 'react-native';


import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { SelectList } from 'react-native-dropdown-select-list';
import DatePicker from 'react-native-date-picker';
import AsyncStorage from '@react-native-async-storage/async-storage';
import DocumentPicker from "react-native-document-picker";
import NetInfo from "@react-native-community/netinfo";
import RNFS from 'react-native-fs';

import MapLibreGL from '@maplibre/maplibre-react-native';
import { MapView,ShapeSource,Camera,UserLocation,PointAnnotation,FillLayer,LineLayer,VectorSource } from "@maplibre/maplibre-react-native";
import Moment from 'moment';
import { RadioButton } from 'react-native-paper';
import AwesomeAlert from 'react-native-awesome-alerts';
import RNFetchBlob from 'rn-fetch-blob';

import { PJU_API_URL } from "../../urlConfig";

type collectScreenProps = {route: any,navigation: any};

function CollectScreen({route,navigation}: collectScreenProps) {
  const apiKey = "JoJs2pcDv5o0yQlQLMfI";
  const [basemap, setBasemap] = useState("streets-v2");
  const styleURL = `https://api.maptiler.com/maps/${basemap}/style.json?key=${apiKey}`;
  const {fixCoordinate} = route.params;
  const [imgUrl, setImgUrl] = useState([]);
  const [files, setFiles] = useState([]);
  const [fileDocument, setFileDocument] = useState([]);
  const [currentIndex, setCurrentIndex] = useState(0);
  const [connected, setConnected] = useState(true)
  
  const openCameraLib = async () => {
    const result = await launchCamera({
      mediaType: 'photo',
      quality: 1,
      includeBase64: true,
      saveToPhotos: true
    });
    const newObj = {
      file_type: result?.assets![0]?.type,
      file: result?.assets![0]?.base64,
      fileSize: result?.assets![0]?.fileSize,
    }
    setFiles([...files,newObj]);
    setImgUrl([...imgUrl,result?.assets![0]?.base64]);
  };
  const openLib = async () => {
    const result = await launchImageLibrary({
      quality: 1,
      mediaType: 'photo',
      selectionLimit: 0,
      includeExtra: true,
      includeBase64: true
    });
    result?.assets?.forEach(asset => {
      const newObj = {
        file_type: asset.type,
        file: asset.base64,
        fileSize: asset.fileSize
      }
      setFiles([...files,newObj]);
      setImgUrl(oldArray => [...oldArray,asset.base64]);
    });
  };
  const PrevImg = ({isIndex}) => {
    if(isIndex===0){
      return (
          <TouchableOpacity disabled style={{width:'10%',alignSelf:'center'}}>
            <Image source={require('../../assets/icon/left-arrow.png')} />
          </TouchableOpacity>
      )
    }
    return (
      <TouchableOpacity style={{width:'10%',alignSelf:'center'}} onPress={()=> {
        setCurrentIndex(currentIndex-1)
        ref.current.scrollToIndex({
          animated: true,
          index: currentIndex-1
        });
      }}>
        <Image source={require('../../assets/icon/left-arrow.png')} />
      </TouchableOpacity>
    )
  };
  const NextImg = ({isIndex}) => {
    if(imgUrl.length<=1){
      return (
        <TouchableOpacity disabled style={{width:'10%',alignSelf:'center'}}>
          <Image style={{alignSelf:'flex-end'}} source={require('../../assets/icon/right-arrow.png')} />
        </TouchableOpacity>
      )
    }
    else{
      if (isIndex === (imgUrl.length-1)) {
        return (
          <TouchableOpacity disabled style={{width:'10%',alignSelf:'center'}}>
            <Image style={{alignSelf:'flex-end'}} source={require('../../assets/icon/right-arrow.png')} />
          </TouchableOpacity>
        )
      }
      else{
        return (
          <TouchableOpacity style={{width:'10%',alignSelf:'center'}} onPress={()=> {
            setCurrentIndex(currentIndex+1)
            ref.current.scrollToIndex({
              animated: true,
              index: currentIndex+1
            });
          }}>
            <Image style={{alignSelf:'flex-end'}} source={require('../../assets/icon/right-arrow.png')} />
          </TouchableOpacity>
        )
      }
    }
  };
  const PJU_Type = [
    {key:'Lampu 20 W', value:'Lampu 20 W'},
    {key:'Lampu 15 W', value:'Lampu 15 W'},
    {key:'Lampu 10 W', value:'Lampu 10 W'},
    {key:'Lampu 5 W', value:'Lampu 5 W'},
  ]
  const ref = useRef();
  const [open, setOpen] = useState(false)
  const [pju_name, setPJUname] = useState('');
  const [selectedPJUType, setselectedPJUType] = useState("");
  const [pju_info, setPJUinfo] = useState('');
  const [checkedStatus, setCheckedStatus] = useState('');
  const [install_date, setInstallDate] = useState(new Date());
  const momentDate = Moment(install_date).format('YYYY-MM-DD')
  const [attachmentImgError, setattachmentImgError] = useState(false);
  const [pjuNameError, setPJUNameError] = useState(false);
  const [PJUTypeError, setPJUTypeError] = useState(false);
  const [PJUStatusError, setPJUStatusError] = useState(false);
  const [PJUInfoError, setPJUInfoError] = useState(false);
  const [attachmentSuccess, setAttachmentSuccess] = useState(0)
  
  useEffect(()=> {
    navigation.addListener('beforeRemove', (e:any)=> {
      console.log("Event",e);
      if (e.data.action.type !== "NAVIGATE"){
        e.preventDefault();
        Alert.alert(
          'Unsave Case',
          'There are unsave case. Please chose what you want.',
          [
            {
              text: 'Ok',
              onPress: () => navigation.dispatch(e.data.action)
            },
            {
              text: 'Continue',
              style: 'cancel'
            }
          ]
        )
      }
    })
    const unsubscribe = NetInfo.addEventListener((state) => {
      setConnected(state.isConnected!)
    });
    return () => {
      unsubscribe();
    };
    
  },[]);

  const collectDataOnline = async() => {
    try {
      const result = {
        status: 0,
        body: {},
      }
      await RNFetchBlob.config({
        trusty : true
      }).fetch('POST', `${PJU_API_URL}/addData`,{
          "Accept": 'application/json',
          "Content-Type": "application/json",
      },
        JSON.stringify({
          nama: pju_name,
          jenis: selectedPJUType,
          tanggal_installasi: momentDate,
          status: checkedStatus,
          keterangan: pju_info,
          geom: `POINT(${fixCoordinate.long} ${fixCoordinate.lat})`
        })
      ).then(async (resp) => {
          const json = resp.json()
          const status = resp.respInfo.status;
          result.status = status;
          result.body = json;
          if (status == 201) {
            insertAttachment(json,files)
            const storeData = async () => {
              try {
                await AsyncStorage.setItem(json[0].id+" / "+pju_name+" / "+selectedPJUType+" / "+momentDate+" / "+checkedStatus+" / "+pju_info+" / "+fixCoordinate.long+" / "+fixCoordinate.lat+" / sentPJU","Value");
              } catch (e) {
              }
            };
            storeData()
          }
      })
    } catch (error) {
      
    }
    
  }
  const collectDataOffline = async() => {
    const storeData = async () => {
        try {
          await AsyncStorage.setItem(pju_name+" / "+selectedPJUType+" / "+momentDate+" / "+checkedStatus+" / "+pju_info+" / "+fixCoordinate.long+" / "+fixCoordinate.lat+" / draftPJU","Value");
        } catch (e) {
        }
      };
      storeData()
      setAlertOffline(false);
      navigation.navigate('Survey Penerangan Jalan Umum', { screen: 'Survey Penerangan Jalan Umum'})
  }
  const getMyObject = async () => {
    try {
      const jsonValue = await AsyncStorage.getItem('draft')
      console.log(JSON.parse(jsonValue!));
      
      // return jsonValue != null ? JSON.parse(jsonValue) : null
    } catch(e) {
      // read error
    }
  }
  const removeValue = async () => {
    try {
      await AsyncStorage.removeItem('Test mobile offline / Lampu 20 W / 2024-11-20 / Baik / - / [object Object] / draftPJU')
    } catch(e) {
      // remove error
    }
  }
  const getAllKeys = async () => {
    // let keys = []
    try {
      const keys = await AsyncStorage.getAllKeys()
      console.log(keys);
      
    } catch(e) {
      // read key error
    }
    // example console.log result:
    // ['@MyApp_user', '@MyApp_key']
  }
  const insertAttachment = async (json: any,files: any) => {
    try {
      files.forEach(async function(file:any) {
        const url = `${PJU_API_URL}/addAttachment`;
        await RNFetchBlob.config({
          trusty : true
        }).fetch('POST', url,{
          "Content-Type": "application/json",
        },
          JSON.stringify({
            pju_id:json[0].id, 
            file:file.file, 
            mimetype:file.file_type, 
            size:file.fileSize})
        ).then(async (resp) => {
            Alert.alert("Success")
            setAlertOnline(false);
            navigation.navigate('Survey Penerangan Jalan Umum', { screen: 'Survey Penerangan Jalan Umum'})
          }
        )
    });
    } catch (error) {
      console.log(error);
    }
  }
  const uploadFileOnHandler = async () => {
    try {
      const pickedFile = await DocumentPicker.pickSingle({
        type: [DocumentPicker.types.allFiles],
        // allowMultiSelection:true
      })
      await RNFS.readFile(pickedFile.uri, 'base64').then(data => {
        console.log('base64', data);
        let your_bytes = btoa(data);
        const newObj = {
          file_type: pickedFile.type,
          file: your_bytes
        }
        setFiles([...files,newObj]);
        setFileDocument([...fileDocument,pickedFile]);
      });
    } catch (error) {
      console.error(error)
    }
  }
  const deleteByIndex = (index:number) => {
    setFileDocument(oldValues => {
      return oldValues.filter((_: any, i: number) => i !== index)
    })
  }
  const [alertOnline, setAlertOnline] = useState(false);
  const [alertOffline, setAlertOffline] = useState(false);

  const showDialog = () => {
    // if (imgUrl.length === 0) {
    //   setattachmentImgError(true);
    // }
    // else{
    //   setattachmentImgError(false);
    // }
    if (!pju_name) {
      setPJUNameError(true);
    }
    else{
      setPJUNameError(false);
    }
    if (!selectedPJUType) {
      setPJUTypeError(true);
    }
    else{
      setPJUTypeError(false);
    }
    if (!checkedStatus) {
      setPJUStatusError(true);
    }
    else{
      setPJUStatusError(false);
    }
    if (!pju_info) {
      setPJUInfoError(true);
    }
    else{
      setPJUInfoError(false);
    }
    if(!pju_name || !pju_info || !selectedPJUType || !checkedStatus) {
      return false
    }
    if(connected){
      setAlertOnline(true);
    }
    else{
      setAlertOffline(true)
    }
  };
  const handleCancelAlertOnline = () => {
    setAlertOnline(false);
  };
  const handleCancelAlertOffline = () => {
    setAlertOffline(false);
  };
  return(
    <View style={styles.mainContainer}>
      <ScrollView style={styles.container}>
        <Text style={styles.title}>Form Survey PJU</Text>
        <View>
          <Text style={styles.label}>Image</Text>
          <View style={styles.borderImg}>
            <Text style={{justifyContent: 'center', alignItems: 'center', alignSelf: 'center', color: 'black'}}>{imgUrl.length === 0 ? currentIndex :currentIndex+1}/{imgUrl.length}</Text>
            <View style={{flexDirection: 'row'}}>
              <PrevImg isIndex={currentIndex}/>
              <Animated.FlatList
                ref={ref}
                style={{width:'80%'}}
                data={imgUrl} 
                showsHorizontalScrollIndicator={false}
                pagingEnabled
                onScroll={e=>{
                  const x = e.nativeEvent.contentOffset.x;
                  setCurrentIndex(parseFloat((x/330).toFixed(0)));
                }}
                horizontal
                renderItem={({item,index}) => {
                  return(
                      <Animated.Image resizeMode='center' style={{width: 295,
                        height: 500,
                        borderRadius: 6,}} source={{uri: `data:image/jpeg;base64,${imgUrl[index]}`}} />
                  )
                }}
              />
              <NextImg isIndex={currentIndex}/>
            </View>
            <View style={styles.btnCameraContainer}>
              <TouchableOpacity style={styles.btnCamera} onPress={openCameraLib}>
                <Image
                    source={require('../../assets/icon/camera.png')}
                    style={styles.buttonImageIconStyle}
                />
                {/* <Text>
                  Open Camera
                </Text> */}
              </TouchableOpacity>
              <TouchableOpacity style={styles.btnCamera} onPress={openLib}>
              <Image
                  source={require('../../assets/icon/gallery.png')}
                  style={styles.buttonImageIconStyle}
              />
              </TouchableOpacity>
            </View>
          </View>
        </View>
        <View
          style={{
            marginTop: 15
          }}
        />
        <View style={{flexDirection:'column'}}>
          <MapView
                style={{width:'80%',height:160,alignSelf:'center'}}
                mapStyle={styleURL}
                rotateEnabled={false}
                zoomEnabled={false}
                pitchEnabled={false}
                attributionPosition={{bottom: 8, right: 8}}
                scrollEnabled={false}
              >
                <PointAnnotation 
                  children={<></>}
                  id={"pjuCoordinate"}
                  coordinate={[fixCoordinate.long, fixCoordinate.lat]}
                />
                <Camera
                  centerCoordinate={[fixCoordinate.long, fixCoordinate.lat]!}   
                  pitch={50}
                  zoomLevel={15}
                  minZoomLevel={5}
                  maxZoomLevel={20}
                />
          </MapView>
          <TouchableOpacity style={{alignSelf:'center',paddingTop:10}} onPress={()=>navigation.navigate('PJU Map Collect', { screen: 'PJU Map Collect'})}>
            <View style={{backgroundColor:'#217dd3',flexDirection:'row',width:150,height:30,borderRadius:20,justifyContent:'center'}}>
                <Text style={{alignSelf:'center',fontWeight:'bold',fontSize:16,color:'white'}}>Change Location</Text>
            </View>
          </TouchableOpacity>
        </View>
        <View
          style={{
            marginTop: 15
          }}
        />
        <View>
          <Text style={styles.label}>Name<Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
          <TextInput
            style={styles.input}
            onChangeText={(text) => {
              setPJUname(text)
            }}
            onChange={()=> {
              setPJUNameError(false)
            }}
          />
          {pjuNameError ? <Text style={styles.errorInput}>Name is Required!</Text>:null}
        </View>
        <View
          style={{
            marginTop: 15
          }}
        />
        <View>
          <Text style={styles.label}>PJU Type <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
          <SelectList
            search={false}
            placeholder="Select PJU Type"
            boxStyles={{borderRadius:50,borderWidth:2}}
            inputStyles={{color:'black'}}
            dropdownTextStyles={{color:'black'}}
            data={PJU_Type}
            setSelected={setselectedPJUType}
            onSelect={()=> (
              [setPJUTypeError(false)]
            )}
          />
          {PJUTypeError ? <Text style={styles.errorInput}>PJU Type is Required!</Text>:null}
        </View>
        <View
          style={{
            marginTop: 15
          }}
        />
        <Text style={styles.label}>Status <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
        <View style={{flexDirection:'row',alignItems:'center'}}>
          <RadioButton
            value="Baik"
            status={ checkedStatus === 'Baik' ? 'checked' : 'unchecked' }
            onPress={() => {setCheckedStatus('Baik'); setPJUStatusError(false)}}
          />
          <Text style={{color:"black"}}>Baik</Text>
        </View>
        <View style={{flexDirection:'row',alignItems:'center'}}>
          <RadioButton
            value="Rusak"
            status={ checkedStatus === 'Rusak' ? 'checked' : 'unchecked' }
            onPress={() => {setCheckedStatus('Rusak'); setPJUStatusError(false); }}
          />
          <Text style={{color:"black"}}>Rusak</Text>
        </View>
        {PJUStatusError ? <Text style={styles.errorInput}>Status is Required!</Text>:null}
        <View
          style={{
            marginTop: 15
          }}
        />
        <View>
          <Text style={styles.label}>Information <Text style={{color:'red',fontWeight:'bold'}}>*</Text></Text>
          <TextInput style={{borderWidth:1,borderRadius:20,padding: 10,color:'black',textAlignVertical:'top'}}
            multiline
            numberOfLines={5}
            maxLength={255}
            onChangeText={(text) => {
              setPJUinfo(text)
            }}
            onChange={()=> {
              setPJUInfoError(false)
            }}
          />
          {PJUInfoError ? <Text style={styles.errorInput}>Information is Required!</Text>:null}
        </View>
        <View
          style={{
            marginTop: 15
          }}
        />
        <View>
          <Text style={styles.label}>Installation Date</Text>
          <TextInput
            style={styles.input}
            onPress={() => setOpen(true)}
            value={String(momentDate)}
          />
          <DatePicker
            locale='en'
            theme='dark'
            mode="date"
            modal
            open={open}
            date={install_date}
            onConfirm={(survey_date) => {
              setOpen(false)
              setInstallDate(survey_date)
            }}
            onCancel={() => {
              setOpen(false)
            }}
          />
        </View>
        <View
          style={{
            marginTop: 15
          }}
        />
        <View></View>
        
      </ScrollView>
      <Button title='Send' onPress={showDialog} />
      {/* <Button title='Get Local' onPress={getMyObject} />
      <Button title='Delete' onPress={removeValue} />
      <Button title='GetAll' onPress={getAllKeys} /> */}
      
      {/* Online Mode Alert */}
      <AwesomeAlert
          show={alertOnline}
          showProgress={false}
          title="Collecting Data"
          message="Are you sure for Collecting PJU data?"
          closeOnTouchOutside={false}
          closeOnHardwareBackPress={false}
          showCancelButton={true}
          showConfirmButton={true}
          cancelText="No, cancel"
          confirmText="Yes, Collect it"
          confirmButtonColor="#137997"
          onCancelPressed={() => {
            handleCancelAlertOnline();
          }}
          onConfirmPressed={() => {
            collectDataOnline();
          }}
          overlayStyle={{width:'100%'}}
          contentContainerStyle={{width:'70%',borderRadius:10}}
          titleStyle={{fontSize:20}}
          messageStyle={{fontSize:16}}
        />

        {/* Offline Mode Alert */}
        <AwesomeAlert
          show={alertOffline}
          showProgress={false}
          title="You are offline"
          message="You want to add data to the draft?"
          closeOnTouchOutside={false}
          closeOnHardwareBackPress={false}
          showCancelButton={true}
          showConfirmButton={true}
          cancelText="No, cancel"
          confirmText="Yes, Add it"
          confirmButtonColor="#DD6B55"
          onCancelPressed={() => {
            handleCancelAlertOffline();
          }}
          onConfirmPressed={() => {
            collectDataOffline();
          }}
          overlayStyle={{width:'100%'}}
          contentContainerStyle={{width:'70%',borderRadius:10}}
          titleStyle={{fontSize:20}}
          messageStyle={{fontSize:16}}
        />
    </View>
  )
}

const styles = StyleSheet.create({
    errorInput: {
      color: 'red',
      marginLeft: 20
    },
    inputLong: {
      height: 40,
      borderWidth: 1,
      padding: 10,
      width: 180,
      marginRight: 20
    },
    inputLat: {
      height: 40,
      borderWidth: 1,
      padding: 10,
      borderRadius: 50,
      width: 180,
      color: 'black'
    },
    input: {
      height: 40,
      borderWidth: 1,
      padding: 10,
      borderRadius: 50,
      color: 'black'
    },
    container: {
      flex: 1,
      backgroundColor: '#ecf0f1',
      padding: 10,
    },
    mainContainer: {
      flex: 1,
    },
    label: {
      fontSize: 21,
      color: 'black',
      // marginBottom: 20
    },
    title: {
      alignItems: 'center',
      justifyContent: 'center',
      alignSelf: 'center',
      fontWeight: 'bold',
      fontSize: 22,
      color: 'black',
      marginBottom: 10
    },
    borderImg: {
      borderColor: 'black',
      borderWidth: 1,
      borderRadius: 20,
    },
    img: {
      width: 295,
      height: 500,
      borderRadius: 6,
    },
    btnCameraContainer: {
      flexDirection: 'row',
      justifyContent: 'space-around',
      top:10,
      
    },
    btnCamera: {
      alignItems: 'center',
      justifyContent: 'center',
      alignSelf: 'center',
      width: 100,
      height: 40,
      bottom:20,
      borderRadius: 6,
      backgroundColor: '#80CBD3'
    },
    textBtn: {
      color: '#fff'
    },
    buttonImageIconStyle: {
      padding: 10,
      margin: 5,
      height: 25,
      width: 25,
      resizeMode: 'stretch',
    },
});

export default CollectScreen;