package com.younki.maidmatching.ui.owner;

import static android.app.Activity.RESULT_OK;

import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import android.os.Handler;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

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.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.younki.maidmatching.R;
import com.younki.maidmatching.services.Adapter.UserData;
import com.younki.maidmatching.services.ApiClient;
import com.younki.maidmatching.services.HTTP.GlobalResponse;
import com.younki.maidmatching.services.SharedPreference.Preferences;
import com.younki.maidmatching.ui.AddJobDetailDialog;
import com.younki.maidmatching.ui.DetailUserFragment;
import com.younki.maidmatching.utils.OnUserClickListener;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link OwnerCreateJobFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class OwnerCreateJobFragment extends Fragment implements OnMapReadyCallback {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    private File jobImg = null;
    private View rootView;

    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
    private MapView mapView;
    private GoogleMap googleMap;
    private FusedLocationProviderClient fusedLocationClient;

    final String[] currentLocation = {"Lokasi terkini belum didapatkan"};

    private boolean[] selectedDays;
    private String[] daysOfWeek;

    private Spinner accommodationSpinner;

    public OwnerCreateJobFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment OwnerCreateJobFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static OwnerCreateJobFragment newInstance(String param1, String param2) {
        OwnerCreateJobFragment fragment = new OwnerCreateJobFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        rootView = inflater.inflate(R.layout.fragment_owner_create_job, container, false);

        Button input_image = rootView.findViewById(R.id.input_image);
        input_image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                chooseImage(view);
            }
        });

        accommodationSpinner = rootView.findViewById(R.id.spinner_accommodation);
        ArrayAdapter<CharSequence> genderAdapter = ArrayAdapter.createFromResource(rootView.getContext(),
                R.array.accommodation_arrays, android.R.layout.simple_spinner_item);
        genderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        accommodationSpinner.setAdapter(genderAdapter);

        daysOfWeek = getResources().getStringArray(R.array.days_of_week);
        selectedDays = new boolean[daysOfWeek.length];

        Button btnSelectDays = rootView.findViewById(R.id.btnSelectDays);
        btnSelectDays.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showMultiChoiceDialog();
            }
        });

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(getContext());

        mapView = rootView.findViewById(R.id.job_location_map);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(this);

        // Get Current Location
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                getLastLocation();
                new Handler().postDelayed(this, 5000);
            }
        }, 0);

        Button btn_create_project = rootView.findViewById(R.id.btn_create_project);
        btn_create_project.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                createJob();
            }
        });

        return rootView;
    }

    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        this.googleMap = googleMap;
    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                getLastLocation();
            } else {
                Toast.makeText(getContext(), "Location permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void getLastLocation() {
        if (getActivity() != null && ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            fusedLocationClient.getLastLocation()
                    .addOnSuccessListener((Activity) getContext(), new OnSuccessListener<Location>() {
                        @Override
                        public void onSuccess(Location location) {
                            if (location != null) {
                                googleMap.clear();
                                LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
                                googleMap.addMarker(new MarkerOptions().position(userLocation).title("You are here"));
                                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));

                                TextView txt_location = rootView.findViewById(R.id.txt_location);

                                String latlngval = String.valueOf(userLocation);

                                latlngval = latlngval.replace("lat/lng: ", "");

                                String[] values = latlngval.split(",");
                                double lat = Double.parseDouble(values[0].replace("(", ""));
                                double lng = Double.parseDouble(values[1].replace(")", ""));

                                JSONObject coordinates = new JSONObject();
                                try {
                                    coordinates.put("lat", lat);
                                    coordinates.put("lng", lng);
                                } catch (JSONException e) {
                                    throw new RuntimeException(e);
                                }

                                txt_location.setText(coordinates.toString());
                            } else {
                                Toast.makeText(getContext(), "Location not available", Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
        } else {
            if (getActivity() != null) {
                ActivityCompat.requestPermissions((Activity) getContext(),
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        LOCATION_PERMISSION_REQUEST_CODE);
            }
        }
    }

    public void chooseImage(View view) {
        Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(galleryIntent, 1);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            Uri selectedImageUri = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), selectedImageUri);

                showImageDialog(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void showImageDialog(Bitmap bitmap) {
        Dialog dialog = new Dialog(getContext());
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.preview_image_dialog);

        ImageView dialogImage = dialog.findViewById(R.id.dialog_image);
        dialogImage.setImageBitmap(bitmap);

        dialog.show();

        jobImg = bitmapToFile(bitmap);
    }

    public File bitmapToFile(Bitmap bitmap) {
        try {
            File file = new File(getContext().getCacheDir(), "temp_image.jpg");
            file.createNewFile();

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
            byte[] bitmapData = byteArrayOutputStream.toByteArray();

            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(bitmapData);
            fileOutputStream.flush();
            fileOutputStream.close();

            return file;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private void showMultiChoiceDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(rootView.getContext());
        builder.setTitle("Pilih Hari")
                .setMultiChoiceItems(daysOfWeek, selectedDays, new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                        selectedDays[which] = isChecked;
                    }
                })
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        showSelectedDays();
                    }
                })
                .setNegativeButton("Batal", null)
                .create()
                .show();
    }

    private void showSelectedDays() {
        StringBuilder selectedDaysStr = new StringBuilder();
        for (int i = 0; i < selectedDays.length; i++) {
            if (selectedDays[i]) {
                if (selectedDaysStr.length() > 0) {
                    selectedDaysStr.append(", ");
                }
                selectedDaysStr.append(daysOfWeek[i]);
            }
        }
        Toast.makeText(rootView.getContext(), "Hari Terpilih: " + selectedDaysStr.toString(), Toast.LENGTH_SHORT).show();
    }

    private void createJob() {
        ProgressDialog progressDialog = new ProgressDialog(getContext());
        progressDialog.setMessage("Loading..."); // Set message untuk dialog
        progressDialog.setCancelable(false); // Set apakah dialog bisa di-cancel atau tidak

        progressDialog.show(); // Menampilkan dialog

        Call<GlobalResponse> globalResponseCall = null;

        TextView txt_location = rootView.findViewById(R.id.txt_location);
        EditText input_name = rootView.findViewById(R.id.input_name);
        EditText input_description = rootView.findViewById(R.id.input_description);

        EditText input_working_hours = rootView.findViewById(R.id.input_working_hours);
        EditText input_salary = rootView.findViewById(R.id.input_salary);
        EditText input_address = rootView.findViewById(R.id.input_address);
        EditText input_recomended_age = rootView.findViewById(R.id.input_recomended_age);

        StringBuilder selectedDaysStr = new StringBuilder();
        for (int i = 0; i < selectedDays.length; i++) {
            if (selectedDays[i]) {
                if (selectedDaysStr.length() > 0) {
                    selectedDaysStr.append(", ");
                }
                selectedDaysStr.append(daysOfWeek[i]);
            }
        }

        if (jobImg == null) {
            Toast.makeText(getContext(), "Harap Upload Image Terlebih Dahulu.", Toast.LENGTH_SHORT).show();
            return;
        }

        File file = new File(jobImg.getPath());
        RequestBody fotoRequestBody = RequestBody.create(file, MediaType.parse("image/jpeg"));
        MultipartBody.Part imagePart = MultipartBody.Part.createFormData("image", file.getName(), fotoRequestBody);

        globalResponseCall = ApiClient.getJobService(getContext()).createJob(
                Preferences.getUserId(getContext()),
                RequestBody.create(MediaType.parse("text/plain"), input_name.getText().toString()),
                RequestBody.create(MediaType.parse("text/plain"), input_description.getText().toString()),
                RequestBody.create(MediaType.parse("text/plain"), accommodationSpinner.getSelectedItem().toString()),
                RequestBody.create(MediaType.parse("text/plain"), selectedDaysStr.toString()),
                RequestBody.create(MediaType.parse("text/plain"), input_working_hours.getText().toString()),
                imagePart,
                parseInt(input_salary.getText().toString()),
                RequestBody.create(MediaType.parse("text/plain"), input_address.getText().toString()),
                RequestBody.create(MediaType.parse("text/plain"), txt_location.getText().toString()),
                parseInt(input_recomended_age.getText().toString())
        );

        globalResponseCall.enqueue(new Callback<GlobalResponse>() {
            @Override
            public void onResponse(Call<GlobalResponse> call, Response<GlobalResponse> response) {
                progressDialog.dismiss();
                if (response.isSuccessful()) {
                    GlobalResponse globalResponse = response.body();

                    if (!globalResponse.isError()) {
                        Toast.makeText(getContext(), globalResponse.getMessage(), Toast.LENGTH_SHORT).show();

                        // Tampilkan dialog sukses
                        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                        builder.setTitle("Create Job");
                        builder.setMessage("Berhasil Menambahkan Job.");
                        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // Tindakan setelah tombol OK ditekan, jika diperlukan
                                AddJobDetailDialog completeProfileDialog = new AddJobDetailDialog(getContext(), globalResponse.getId());
                                completeProfileDialog.setCancelable(false);
                                completeProfileDialog.getWindow().setBackgroundDrawable(new ColorDrawable(getContext().getResources().getColor(android.R.color.transparent)));
                                completeProfileDialog.show();

                                navigateToJobFragment();
                            }
                        });
                        builder.show();
                    } else {
                        Toast.makeText(getContext(), globalResponse.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(getContext(), "Gagal Menambahkan Job.", Toast.LENGTH_SHORT).show();
                }
            }
            @Override
            public void onFailure(Call<GlobalResponse> call, Throwable t) {
                progressDialog.dismiss();
                Toast.makeText(getContext(), "Throwable "+t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    public int parseInt(String string){
        try {
            return Integer.valueOf(string);
        } catch (Exception e) {
            return 0;
        }
    }

    private void navigateToJobFragment() {
        BottomNavigationView bottomNavigationView = getActivity().findViewById(R.id.bottomNavigationView);
        bottomNavigationView.setSelectedItemId(R.id.home);

        OwnerHomeFragment ownerJobFragment = new OwnerHomeFragment();
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.frame_layout, ownerJobFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }
}