import React,{useState,useEffect} from 'react';
import Container from '../components/container';
import { useRoute } from '@react-navigation/native';
import { globalStyles,customStyles,GetPageTheme, WP } from "../styles/Global";
import {Image,View,Text,ScrollView,TouchableOpacity,Platform,FlatList, DeviceEventEmitter} from 'react-native';
import { connect} from 'react-redux';
import { mapStateToProps,mapDispatchToProps } from '../reducers/contextProvider';
import {notify} from '../components/notify';
import moment from 'moment';
import {checkRange, marktext1,marktext2, resizeImage, restore_ImageWithMetaData, UpdateDistributorStatus, UpdateStoreStatus, UploadData, UploadData2, UploadFormData} from '../controller/functions';
import {get_item,set_item,clear_item} from '../components/localStorage';
import {AppVersion, common_ImagePath,ImageFolderPath, db,gMap_key, URL_IMAGE, CoverageImagePath} from '../constants/constants';
import CustomHeader from '../components/customHeader';
import CustomLoader from '../components/CustomLoader';
import LinearGradient from 'react-native-linear-gradient';
import MapView,{ Marker,AnimatedRegion ,Polyline,PROVIDER_GOOGLE} from 'react-native-maps';
import { _checkLocationPermission } from '../components/geolocation';
import Geolocation from 'react-native-geolocation-service';
import { useRef } from 'react';
import GradientButton from '../components/gradientButton';
import * as RNFS from 'react-native-fs';

import CameraImg from '../assets/performics/camera_front_image.svg'
import { AppTables } from '../constants/tableConstants';
import { getFolderName, getMethodName, METHODS } from '../constants/methodNames';
import { getAvailblQuery, getIfAvlbl, Q_DBMenuList, Q_MenuList } from '../constants/ConstantQueries';


function DistributorCheckin(props) { 
    const route = useRoute();
    const ST=props.StaticText || {};
    // get all theme styles acc to current theme set 
    const PageTheme=GetPageTheme(props.DarkMode,route.name);
    const customStyle=customStyles(props.DarkMode,route.name);
    const [processing, setProcessing] = useState(false);
    
    const [storeData, setStoreData] = useState({});
    const [StoreImage, setStoreImage] = useState('');
    const [StoreImgPath, setStoreImgPath] = useState('');
    
    const [currentLocation, setCurrentLocation] = useState({});
    const [markerCoordinate, setMarkerCoordinate] = useState();
    const [markerPos, setMarkerPos] = useState({});
    const [markerTitle, setMarkerTitle] = useState('');
    const [markerPlaceText, setMarkerPlaceText] = useState('');
    const [loaderTitle, setLoaderTitle] = useState();
    const [isAdhocScreen, setIsAdhocScreen] = useState(false);
    const [storeDistanceText, setStoreDistanceText] = useState('0 m');
    const [storeDistance, setStoreDistance] = useState(0);
    const [showCamera, setShowCamera] = useState(false);
    const [getImageProps,setGetImageProps]= useState({});

    const MyMap=useRef(null);
    const MyMarker=useRef(null);
    const isCancelled = useRef(false);
    const d1=new Date();
    const d2=moment(d1).format('MM/DD/YYYY');
   
    useEffect(() => { 
      setLoaderTitle(ST.Loading+'...')
      let params=props.route.params? props.route.params:{};
      let storeData1=params.storeData || {};
      setStoreData(storeData1);
      calLocatDistance(storeData1);

      const onImageCapturedSubs=DeviceEventEmitter.addListener('onImageCaptured',(imgData)=>{ getImage(imgData,storeData1)});
      const unsubscribe=props.navigation.addListener('beforeRemove', onBeforeRemove);
        

      return function cleanup() {
        isCancelled.current = true; 
        Geolocation.clearWatch()
        onImageCapturedSubs.remove();
        return unsubscribe;
      };
      
    }, []);

    useEffect(() => {
      console.log('show camera changes:',showCamera);
      const unsubscribe=props.navigation.addListener('beforeRemove', onBeforeRemove);
      return unsubscribe;
    }, [showCamera]); 
    
    function  onBeforeRemove(e){
      console.log('onBeforeRemove:',showCamera);
      if(showCamera==true){
        e.preventDefault();
        setShowCamera(false);
      }
      else{
        return;
      } 
    }

    async function calLocatDistance(storeData1){
      if(storeData1.Latitude !='' && storeData1.Latitude!=null){
        const hasPermission=await _checkLocationPermission();
        if(hasPermission==true)
        {    
          getCurrentPosition(storeData1);
          getLocationUpdates(storeData1);          
        }
        else{
          notify(ST.Pleaseallowlocationpermission);
        }
      }
      else{
        notify(ST.Storelocationnotavailable);
      }      
    }

    async function getCurrentPosition(storeData1){
      Geolocation.getCurrentPosition(
        async (position) => {
          OnLocation(position,storeData1);   
        },
        (error) => {
            notify(ST.Cannotgetuserposition);
        },
        { enableHighAccuracy: true, distanceFilter: 10, interval: 1000, fastestInterval: 2000 }
      );
    }

    async function getLocationUpdates(storeData1){
      Geolocation.watchPosition(
        async (position) => {
          OnLocation(position,storeData1);                 
        },
        (error) => {
          notify(ST.Cannotgetuserposition);
        },
        { enableHighAccuracy: true, distanceFilter: 20, interval: 1000, fastestInterval: 2000, }
      )
    }

    async function OnLocation(position,storeData1){
      let loc={lat:position.coords.latitude,lng:position.coords.longitude};
      let storeLat=parseFloat(storeData1.Latitude),storeLng=parseFloat(storeData1.Longitude);
      setMarkerPos({ lat:storeLat, lng: storeLng });
      setMarkerCoordinate(new AnimatedRegion({ latitude:storeLat, longitude: storeLng }));
      setMarkerInfo({ latitude:storeLat, longitude: storeLng });
      setCurrentLocation(loc);


      var distance = checkRange(loc.lat,loc.lng,storeData1.Latitude,storeData1.Longitude);
      // console.log('distance:',distance);
      let dinKM=(distance / 1000);
      let distanceinM=(distance=='' || distance==null || isNaN(distance))?' 0 m':( dinKM > 1 ? dinKM.toFixed(1) + ' Km' : distance + ' m');
      setStoreDistanceText(distanceinM);
      setStoreDistance(distance);   
    }

    async function getPosition_global(successCallback){
      Geolocation.getCurrentPosition(
        async (position) => {
          successCallback(position);  
        },
        (error) => {
            notify(ST.Cannotgetuserposition);
        },
        { enableHighAccuracy: true, distanceFilter: 0, interval: 1000, fastestInterval: 2000 }
      );
    }

    async function submitCheckIn(){
      if(validate()){
        setLoaderTitle(ST.ProcessingCheckIn+'...');
        setProcessing(true);

        async function posSuccessCallback(position){          
          let loc={lat:position.coords.latitude,lng:position.coords.longitude};
          uploadCheckIn(loc);
        }
        await getPosition_global(posSuccessCallback);
      }
    }    

    
    async function onStoreStatusUpdate(txnres2){
      setProcessing(false);          
      notify(ST.CheckInDataUploadedsuccessfully,'SHORT');
      let MenuLen=await getMenuListLen();
      if(MenuLen>0){
        props.navigation.replace('DB_StoreDailyMenu',{storeData:storeData});
      }
      else{
        props.navigation.goBack();
      }
    }

    async function getMenuListLen(){
      let {StoreId,ChannelId,RegionId,StoreTypeId}=storeData;
      return new Promise((resolve,reject)=>{
        db.transaction(async function (txn) {   
          let q=Q_DBMenuList(storeData); 
          await txn.executeSql(q,[],async function (txn2, txnres) { 
            resolve(txnres.rows.length);
          },function (txnE,txnerr) { console.log(txnerr); resolve(0); },);
        });   
      }).then((val)=>{
        return val;
      }).catch((err)=>{
        console.log('')
        return 0
      })
    }

    async function uploadCheckIn(loc){
      let d1=new Date();
      let d2=moment(d1).format('MM/DD/YYYY');    
      let fpath=Platform.OS=='ios'?StoreImgPath.replace('file://',''):StoreImgPath;
      console.log(fpath);
      // var data1 = new FormData();          
      // data1.append('file', {
      //   uri: fpath ,
      //   type: 'image/jpg',
      //   name: StoreImage,
      // });

   
      // data1.append('Foldername','DBCoverageImages');
      // data1.append('Path', d2);
      let data={
        "DistributorId":storeData.StoreId,
        "VisitDate":d2,
        "Latitude":(loc.lat || ''),
        "Longitude":(loc.lng || ''),
        "ReasonId":0,
        // "Remark":"",
        // "Appversion":AppVersion,
        "UploadStatus":"I",
        "UserId":(props.UserId || ''),
        "CheckInImage":StoreImage,
        "CheckoutImage":"",
      }

      const url=props.baseurl+getMethodName(METHODS.DISTRIBUTOR_COVERAGE);
      const url1=(props.imageUploadUrl || URL_IMAGE)+getMethodName(METHODS.UPLOADIMAGES_METHOD);
      console.log(url,data);

      await UploadData2(url,data)
      .then(async(res)=>{         
        console.log('res of dbcheckin:',res);
        if(parseInt(res)>0){
          InsertCoverageData(res,loc);
          // Upload Image 
          // await UploadFormData(url1,data1)
          // .then(async(res1)=>{         
          //   console.log('res1 image upload:',res1);            
          // })
          // .catch((err)=>{
          //   console.log(err);
          // });

        }
        else{
          setProcessing(false);
        }
      })
      .catch((err)=>{
        console.log(err);setProcessing(false);
      });
    }

    async function InsertCoverageData(MID=0,loc){
      console.log('InsertCoverageData');
      try{
        let d1=new Date();
        let d2=moment(d1).format('MM/DD/YYYY');
        let now=moment(d1).format('MM/DD/YYYY HH:mm:ss');
        await db.transaction(async function (txn) {  
          
          let {StoreId}=storeData;
          let {lat,lng}=loc;
          let JcpType='Master_Distributor';


          let q2=`delete from ${AppTables.DISTRIBUTOR_CHECKIN} where DISTRIBUTOR_ID='${StoreId}' and VISIT_DATE='${d2}' `; 
          let values2=` ('${StoreId}','${d2}','${lat}','${lng}','${now}','${StoreImage}','','','','${d2}')`; 
          let insert_q2=` INSERT INTO ${AppTables.DISTRIBUTOR_CHECKIN}(DISTRIBUTOR_ID,VISIT_DATE,LATITUDE,LONGITUDE,CHECKIN_TIME,CHECKIN_IMAGE,CHECKOUT_TIME,CHECKOUT_IMAGE,REMARK,ADDED_DATE) values ${values2}`;
         
          await txn.executeSql(q2,[],async function (txn2, txnres2) {
            console.log('removed'); 
            await txn.executeSql(insert_q2,[],async function (txn2, txnres3) {
              console.log('checkin data added');  

              let q=`UPDATE ${JcpType} SET UploadStatus='I',DMID='${MID}' WHERE DistributorId='${StoreId}' `;
              await txn.executeSql(q,[],async function (txn2, txnres2) { 
                  console.log('distributor status and MID updated');
                  onStoreStatusUpdate();
                 
              },function(Etxn,txnerr){console.log(txnerr);}); 

            },function(Etxn,txnerr){console.log(txnerr);});
          },function(Etxn,txnerr){console.log(txnerr);});
          
        }); 
      }
      catch(e){
        console.log('error:',e);
        setProcessing(false);
        notify(ST.CouldnotaddCheckIndata,'SHORT');
      }
    }


    function validate(){
      if(StoreImage=='' || StoreImage==null){
        notify('Please click selfie in front of Distributor','SHORT');
        return false;
      }
      return true;
    }

    async function getImage(imgdata,storeData1){
      let storeData2=imgdata.storeData ||(Object.keys(storeData).length>0?storeData:storeData1)
        if(typeof imgdata =='object' && imgdata.errorCode=='camera_unavailable'){
            notify(ST.Cameraunavailable);
        }
        else if(typeof imgdata =='object' && imgdata.uri!=null){
          const img=imgdata;
          const imgurl=img.uri, imgWidth=img.width, imgHeight=img.ExtendedHeight;
          let isImgFromGallery=img.fromGallery!=null?img.fromGallery:false;
          let picture_clickedd=isImgFromGallery==true?img.datetime:new Date();
           ////change by jeevanp
          let picture_clicked_time=moment(picture_clickedd).format('MM-DD-YYYY HH:mm:ss')
          let picture_clicked_time_for_pic_name=moment(picture_clickedd).format('MMDDYYYY_HHmmss')
          console.log("time", picture_clicked_time);
          console.log("time1", picture_clicked_time_for_pic_name);
           
          let calculate_tym_date_for_filename = picture_clicked_time_for_pic_name;
          let calculate_tym_date_over_img = picture_clicked_time;
            
          let filename=storeData2.StoreId+'_'+(props.UserId || '')+'_DBStoreImg-'+calculate_tym_date_for_filename+'.jpg';
           console.log(filename,"file_name");                  
           setStoreImage(filename);

          const mark_text1=calculate_tym_date_over_img;
          const mark_text2='Distributor Name:'+storeData2.StoreName+' | Distributor Id:'+storeData2.StoreId+' | User Id:'+storeData2.EmpId+' | Image Type: DB Check In'+' | Date:'+calculate_tym_date_over_img;      

          console.log(mark_text1+"\n"+mark_text2,"mark_text2");
          
          let imagePath=`${CoverageImagePath}${filename}`;
          RNFS.copyFile(imgurl,imagePath)
          .then(async(resn) => {
            // render data with clicked image
            let uri='file://'+imagePath;
            setStoreImgPath(uri);
            // add metdata then resize image and restored back to the imagePath
            let restore_data={"destFilePath":imagePath,"imgurl":imgurl,imgWidth,imgHeight,mark_text1,mark_text2}
            let is_restored=await restore_ImageWithMetaData(restore_data,imgdata);
            console.log("image restored:",is_restored);
          })
          .catch(err => {
            console.log('ERROR: image file write failed!!!');
            console.log(err.message, err.code);
          }); 
          
      }        
  }

  async function openCamera(){  
      props.navigation.navigate('CameraScreen',{'getImage':getImage,'cameraType':'front','CheckInCameraGallery':props.CheckInCameraGallery,storeData:storeData})
  }

    function moveMarkerToPos(e){
      let coords=e.nativeEvent.coordinate;
      animateCamera(coords);
      animateMarkerToRegion(coords);
      setMarkerInfo(coords);
      let loc={lat:coords.latitude,lng:coords.longitude};
      setMarkerPos(loc);
    }

    function animateMarkerToRegion(coords) {
      const newCoordinate = coords;  
      if (Platform.OS === 'android') {
        if (MyMarker) {
          MyMarker.current.animateMarkerToCoordinate(newCoordinate, 1000);
        }
      } else {
        // `useNativeDriver` defaults to false if not passed explicitly
        markerCoordinate.timing({ ...newCoordinate, useNativeDriver: false,duration:1000 }).start();
      }
      setTimeout(()=>{setMarkerCoordinate(coords);},1000);
      
    }

    async function setMarkerInfo(coords){
      if(MyMap.current!=null){
        MyMap.current.addressForCoordinate(coords)
        .then((res)=>{
          console.log('res:',res);
          let title=res.name;
          let placeText=`${res.subLocality}, ${res.locality}, ${res.administrativeArea} ${res.postalCode}`;
          setMarkerTitle(title);
          setMarkerPlaceText(placeText);
          
        })
      }
    }

    async function animateCamera(coords) {
      if(MyMap.current!=null){
      const camera = await MyMap.current.getCamera();
      camera.heading = 7;
      camera.pitch = 7;
      camera.altitude = 100;
      camera.zoom = 19;
      camera.center.latitude = coords.latitude;
      camera.center.longitude = coords.longitude;
      MyMap.current.animateCamera(camera, { duration: 2000 });
      }
    }


    function _renderMap(){
      const lat =currentLocation.lat?currentLocation.lat:28.579660;
      const lng=currentLocation.lng?currentLocation.lng:77.321110;

      // const latt=storeData.Latitude?parseFloat(storeData.Latitude):lat;
      // const long=storeData.Longitude?parseFloat(storeData.Longitude):lng;
      
      if(currentLocation.lat!=null)
      {
        return (
          <View style={[customStyle.mapWrapCon,(Platform.OS==='ios'?customStyle.mapWrapConIOS:{})]}>
          <View style={[customStyle.mapWrapper,customStyle.mapWrapperSmall]}>   
          <MapView  
              ref={MyMap}
              provider={PROVIDER_GOOGLE}
              style={customStyle.mapStyle}               
              showsUserLocation={true}  
              zoomEnabled={true} 
              // initialRegion={{  
              //   latitude: lat,   
              //   longitude: lng,  
              //   latitudeDelta: 0.0922,  
              //   longitudeDelta: 0.0421,  
              // }}  
              initialCamera={{
                center: {
                  latitude: lat,   
                  longitude: lng,
                },
                pitch: 7,
                heading: 7,
                altitude: 100,
                zoom: 19,
              }}
          >
              <Marker.Animated 
                ref={MyMarker}
                coordinate={ markerCoordinate}                  
                pinColor={'#ff78b6'}
                title={markerTitle}  
                description={markerPlaceText}      
              />  
              <Polyline
                coordinates={[{latitude:currentLocation.lat,longitude:currentLocation.lng},{latitude:markerPos.lat,longitude:markerPos.lng}]}
                strokeColor={'#00a4eb'} // fallback for when `strokeColors` is not supported by the map-provider
                strokeColors={['#00a4eb']}
                strokeWidth={4}
              />
          </MapView>  
          </View>  
          {_render_captureImage()} 
          </View>            
        );
      }
      else{
        return(<View></View>)
      }
    }

    function _render_captureImage(){
      const isImageAvlbl=StoreImage!='' && StoreImage!=null && StoreImgPath!='' && StoreImgPath!=null;
      
      return (
        <View style={[customStyle.gtag_sImageWrap,{bottom:-40}]}>          
          <View style={customStyle.gtag_sImagelbl}>
            <TouchableOpacity style={customStyle.gtag_sImage_View} onPress={()=>{openCamera()}}>
              {!isImageAvlbl && <CameraImg width={80} height={80}/>}  
              {isImageAvlbl && <Image style={[customStyle.gTag_Image,(Platform.OS=='ios' ?customStyle.android_flipIMageView:{})]} source={{uri:StoreImgPath}}/>}    
            </TouchableOpacity>
            <Text style={[customStyle.gtag_sImagelblText,{marginTop:0}]}>{'Click selfie in front of Distributor'}</Text>
          </View>
           
        </View>
      );
    }
  
    return ( 
      <Container {...props} pt={0} avoidSafeArea={(Platform.OS=='ios'?true:false)}>
        {processing && <CustomLoader fullHeight={true} title={loaderTitle}/>}
        <CustomHeader {...props} showaddstore={true} title={'Distributor Check-In'}/>        
        {/* <CustomCamera cameraType={'front'} enableGallerForScreen={props.CheckInCameraGallery} onImageCaptured={(imgData)=>{setShowCamera(false);getImage(imgData)}} showCamera={showCamera} onHideCamera={()=>{setShowCamera(false);}}/>    */}
        
        <LinearGradient colors={[PageTheme.$gradient1,PageTheme.$primary_color]} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={customStyle.roundScrollWrapper}>
          <View style={[customStyle.pageContentWrapper]}>
          { Object.keys(storeData).length>0 &&
            <ScrollView contentContainerStyle={customStyle.geotag_scroll} style={{}}>            
            
              <View style={[customStyle.storel,customStyle.storeInfo_wrap]}>

            
              <View style={customStyle.storel_card_outer}> 
                <View style={customStyle.storel_card}>
                  <View style={customStyle.storel_card_content}>
                    <Text style={customStyle.storel_card_title}>{storeData.StoreName}</Text>
                  </View>                  
                </View>
                <View style={customStyle.storel_details}>
                  <View style={customStyle.storel_code}>
                    <View style={[customStyle.storel_codeCon,customStyle.storel_codeBorder]}>
                      <Text style={customStyle.storel_codeLbl}>{ST.StoreId+':'}</Text>
                      <Text style={customStyle.storel_codeText}>{storeData.StoreId}</Text>
                    </View>                    
                    <View style={[customStyle.storel_codeCon]}>
                      <Text style={customStyle.storel_codeLbl}>{ST.StoreCode+':'}</Text>
                      <Text style={customStyle.storel_codeText}>{storeData.StoreCode}</Text>
                    </View>
                  </View>
                  <View style={customStyle.storel_code}>                    
                    <View style={[customStyle.storel_codeCon]}>
                      <Text style={customStyle.storel_codeLbl}>{ST.Address+':'}</Text>
                      <Text style={customStyle.storel_codeText}>{storeData.Address}</Text>
                    </View>
                  </View>                                 
                </View>                
              </View> 
            
              </View>
              {
              // isCancelled.current==false &&  
              _renderMap()
              } 
              
              
              <View style={[customStyle.gTag_btnWrap,customStyle.gTag_btnWrapCI]}>
                {
                  storeDistance>500 && 
                  <View  style={customStyle.gTag_distanceAway}>
                  <Text style={customStyle.gTag_distanceAwayLbl}>{`${ST.Youare} ${storeDistanceText} ${ST.Awayfromthestore}`}</Text>
                  </View>
                }
                <GradientButton {...props} title={ST.CheckIn} onPress={()=>{submitCheckIn()}}/> 
              </View>    
                 
            </ScrollView>
          }
         </View>      
       </LinearGradient>       
        
      </Container>   
    ); 
  }
  


export default connect(mapStateToProps, mapDispatchToProps)(DistributorCheckin);