package com.project.ilsaenterprise;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.fingerprint.FingerprintManager;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.project.ilsaenterprise.models.Attendance;
import com.project.ilsaenterprise.models.Employees;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class AttendanceWfh extends FragmentActivity implements OnMapReadyCallback {

    private static final String TAG = "MapActivity";
    private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
    private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
    private static final int PLAY_SERVICE_RESOLUTION_REQUEST = 4799;
    private static final float DEFAULT_ZOOM = 16.5f;
    private static final int ERROR_DIALOG_REQUEST = 9001;
    //vars
    private Boolean mLocationPermissionsGranted = false;
    private GoogleMap mMap;
    CheckBox checkBox;
    SeekBar seekRed, seekGreen, seekBlue;
    Button btDraw;
    ImageButton btClear;
    FusedLocationProviderClient mFusedLocationProviderClient;
    FloatingActionButton onLocation;
    Location currentLocation;
    Employees employees;

    private FirebaseDatabase mFirebaseDatabase;
    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;

    DatabaseReference databaseReference;
    private static int UPDATE_INTERVAL = 5000;
    private static int FASTEST_INTERVAL = 3000;
    private static int DISPLACEMENT = 10;
    private MapView mapView;
    Boolean cek;

    Polygon polygon = null;
    ArrayList<String> latLngList = new ArrayList<>();
    List<Marker> markerList = new ArrayList<>();
    ArrayList<String> geoPosition = new ArrayList<>();

    private String currentDate = new SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format(new Date());//Untuk Database jgn diganti format

    private TextView textView, txtInfo;
    private ImageView imageView;
    private FingerprintManager fingerprintManager;
    private FingerprintManager.AuthenticationCallback authenticationCallback;
    DatabaseReference historyRef;
    private Button startScanBtn;

    private DatabaseReference checkHadir = FirebaseDatabase.getInstance().getReference();
    private String lat, lng;
    private BottomSheetDialog bottomSheetDialog;
    private  DatabaseReference checkAttendanceRef = FirebaseDatabase.getInstance().getReference().child("attendanceWFH").child(currentDate);
    private DatabaseReference userPhotoRef;
    private String currentUser, userImageUrl;
    Task location;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_attendance_wfh);
//        getSupportActionBar().hide();
        getLocationPermission();

        checkAtt();
        btDraw = (Button) findViewById(R.id.bt_draw);
        btClear = (ImageButton) findViewById(R.id.bt_clear);
        userPhotoRef = FirebaseDatabase.getInstance().getReference().child("usersPhoto");
        currentUser = FirebaseAuth.getInstance().getCurrentUser().getUid();

        textView = findViewById(R.id.textScanner);
        bottomSheetDialog = new BottomSheetDialog(
                AttendanceWfh.this, R.style.BottomSheetDialogTheme
        );

        employees = new Employees();
        btDraw.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                View bottomSheetView = LayoutInflater.from(getApplicationContext())
                        .inflate(
                                R.layout.layout_popup_fingerprint,
                                (LinearLayout)findViewById(R.id.bottomSheetContainer)
                        );
                startScan();
                fingerprintManager.authenticate(null, null, 0, authenticationCallback, null);
                bottomSheetDialog.setContentView(bottomSheetView);
                bottomSheetDialog.show();
            }
        });

        btClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getLocationPermission();
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        if(isServicesOK()){
            initMap();
            getLocationPermission();
        }
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        currentLocation = null;
        mMap.clear();
        mMap.setLocationSource(null);
    }

    private void clockCheck()
    {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    while (!isInterrupted()) {
                        Thread.sleep(1000);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                TextView thour = (TextView) findViewById(R.id.textHour);
                                long date = System.currentTimeMillis();
                                @SuppressLint("SimpleDateFormat") SimpleDateFormat adf = new SimpleDateFormat("hh : mm : ss");
                                String hourString = adf.format(date);
                                thour.setText(hourString);
                            }
                        });
                    }
                } catch (InterruptedException e) {

                }
            }
        };
        t.start();
    }

    private void checkAtt()
    {
        final FirebaseUser user = mAuth.getInstance().getCurrentUser();
        final String userID = user.getUid();
        final TextView checkUser = (TextView) findViewById(R.id.checkKehadiran);
        final TextView textIO = findViewById(R.id.textInOut);
        cek = false;
        checkAttendanceRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //long count= dataSnapshot.getChildrenCount();
                if(!dataSnapshot.child("Check In").hasChild(userID)){
                    checkUser.setText("Belum Tapping");
                    textIO.setText("Jam Masuk");
                    btDraw.setText("Check In");
                    btDraw.setEnabled(true);
                    clockCheck();
                    cek = false;
                }
                else if(!dataSnapshot.child("Check Out").hasChild(userID)){
                    checkUser.setText("Sedang Bekerja");
                    textIO.setText("Jam Keluar");
                    btDraw.setText("Check Out");
                    clockCheck();
                    cek = false;
                }
                else{
                    checkUser.setText("Absensi Selesai");
                    textIO.setVisibility(View.INVISIBLE);
                    btDraw.setText("Terima Kasih");
                    startTime();
                    cek = true;
                    btDraw.setEnabled(false);
                    btClear.setEnabled(false);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

    private void startTime(){
        final FirebaseUser user = mAuth.getInstance().getCurrentUser();
        final String userID = user.getUid();

        checkAttendanceRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                Attendance history = dataSnapshot.child("Check In").child(userID).getValue(Attendance.class);
                Attendance history2 = dataSnapshot.child("Check Out").child(userID).getValue(Attendance.class);
                String firstTime = history.getTime();
                String endtime = history2.getTime();

                SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
                Date start, end;
                try{
                    start = format.parse(firstTime);
                    end = format.parse(endtime);

                    long diff = end.getTime() - start.getTime();

                    long diffSeconds = diff / 1000 % 60;
                    long diffMinutes = diff / (60 * 1000) % 60;
                    long diffHour = diff / (60 * 60 * 1000) % 24;

                    TextView totalWork = findViewById(R.id.textHour);
                    totalWork.setTextSize(20);
                    totalWork.setText(diffHour + " Jam " + diffMinutes + " Menit " + diffSeconds + " Detik");

                }catch (Exception e){
                    e.printStackTrace();
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    }

    private void moveCamera(LatLng latLng, float zoom){
        //LatLng markerLoc = new LatLng(latLng.latitude, latLng.longitude);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
        mMap.clear();
    }

    public boolean isServicesOK(){

        int available = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(AttendanceWfh.this);

        if(available == ConnectionResult.SUCCESS){
            return true;
        }
        else if(GoogleApiAvailability.getInstance().isUserResolvableError(available)){
            Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(AttendanceWfh.this, available, ERROR_DIALOG_REQUEST);
            dialog.show();
        }else{
            Toast.makeText(this, "You can't make map requests", Toast.LENGTH_SHORT).show();
        }
        return false;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.isIndoorEnabled();

        try {
            boolean success = googleMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.new_map));
            if(!success){
                return;
            }
        }catch (Resources.NotFoundException e){
            Log.e(TAG, "Error", e);
        }

        if (mLocationPermissionsGranted) {
            getDeviceLocation();

            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }

            mMap.setMyLocationEnabled(true);
            mMap.getUiSettings().setMyLocationButtonEnabled(false);
        }
    }

    private void getDeviceLocation(){
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        try{
            if(mLocationPermissionsGranted){
                //&& task.getResult() != null
                location = mFusedLocationProviderClient.getLastLocation();
                location.addOnCompleteListener(new OnCompleteListener() {
                    @SuppressLint("SetTextI18n")
                    @Override
                    public void onComplete(@NonNull Task task) {
                        if(task.isSuccessful() && task.getResult() != null){
                            currentLocation = (Location) task.getResult();

                            moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()), DEFAULT_ZOOM);
                            MarkerOptions marker = new MarkerOptions().position(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()));
                            //mMap.addMarker(marker);

//                            boolean isPoint = pointInPolygon(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()));

                            String newLat = String.valueOf(currentLocation.getLatitude());
                            String newLng = String.valueOf(currentLocation.getLongitude());
                            latLngList.add(newLat);
                            latLngList.add(newLng);

                        } else{
                            Toast.makeText(getBaseContext(), "Pencarian Titik Gagal", Toast.LENGTH_SHORT).show();
                            mFusedLocationProviderClient.getLastLocation();
                        }
                    }
                });
            }
        }catch (SecurityException e){
            Log.e(TAG, "getDeviceLocation: SecurityException: " + e.getMessage() );
        }
    }

    private void initMap(){
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapView);

        assert mapFragment != null;
        mapFragment.getMapAsync(AttendanceWfh.this);
    }

    private void getLocationPermission(){
        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION};

        if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
                FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
            if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
                    COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
            {
                mLocationPermissionsGranted = true;
                initMap();
            }else{
                ActivityCompat.requestPermissions(this,
                        permissions,
                        LOCATION_PERMISSION_REQUEST_CODE);
            }
        }else{
            ActivityCompat.requestPermissions(this,
                    permissions,
                    LOCATION_PERMISSION_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        mLocationPermissionsGranted = false;

        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0) {
                for (int grantResult : grantResults) {
                    if (grantResult != PackageManager.PERMISSION_GRANTED) {
                        mLocationPermissionsGranted = false;
                        return;
                    }
                }
                mLocationPermissionsGranted = true;
                //initialize our map
                initMap();
            }
        }
    }

    private void startScan(){
        fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);

        authenticationCallback = new FingerprintManager.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode, CharSequence errString) {
                //textView.setText("Error");
                //Toast.makeText(MapActivity.this, "Otentikasi Error", Toast.LENGTH_LONG).show();
//                imageView.setImageResource(R.drawable.image2);
                super.onAuthenticationError(errorCode, errString);
            }

            @Override
            public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
                super.onAuthenticationHelp(helpCode, helpString);
            }
            @Override
            public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {

                final String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();

                databaseReference = FirebaseDatabase.getInstance().getReference("attendanceWFH");
//                String check = databaseReference.push().getKey();
                historyRef = FirebaseDatabase.getInstance().getReference("historyWFH");
                String timeStamp = String.valueOf(System.currentTimeMillis());

                databaseReference.child(currentDate).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if(!dataSnapshot.child("Check In").hasChild(userID)){
                            Attendance attendance = new Attendance(userID, timeStamp, "Masuk", "WFH", latLngList.get(0), latLngList.get(1));
                            databaseReference.child(currentDate).child("Check In").child(userID).setValue(attendance);
                            historyRef.child(userID).child(timeStamp).setValue(attendance);
                        }
                        else if (!dataSnapshot.child("Check Out").hasChild(userID)){
                            Attendance attendance = new Attendance(userID, timeStamp, "Keluar", "WFH", latLngList.get(0), latLngList.get(1));
                            databaseReference.child(currentDate).child("Check Out").child(userID).setValue(attendance);
                            historyRef.child(userID).child(timeStamp).setValue(attendance);
                        }
                    }
                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });

                super.onAuthenticationSucceeded(result);
                bottomSheetDialog.dismiss();
                Toast.makeText(getBaseContext(), "Otentikasi Berhasil", Toast.LENGTH_SHORT).show();
//                Intent intent = new Intent(AttendanceWfh.this, CheckKehadiranWfh.class);
                startActivity(new Intent(AttendanceWfh.this, CheckKehadiranWfh.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
                finish();
            }

            @Override
            public void onAuthenticationFailed() {
                Toast.makeText(getBaseContext(), "Otentikasi Gagal", Toast.LENGTH_SHORT).show();
                super.onAuthenticationFailed();
            }
        };
    }

}
