package cg.cits.koumbangai;


import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.NumberPicker;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.TimePicker;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;

public class SetRideDetailsActivity extends AppCompatActivity implements Serializable, View.OnClickListener{

    //SetRideActivitystä siirretty data
    private List<HashMap<String,Double>> selectedPoints;
    private String startAddress, endAddress, duration, distance, startCity, endCity;

    private Calendar mC;
    private int mYear, mMonth, mDay, mHour, mMinute;
    private int pickedYear, pickedMonth, pickedDate, pickedHour, pickedMinute;
    private String strDate, strTime;
    private long leaveTime;

    private float price = 0.03f;
    int pickUpDistance = 10;
    int passengers = 1;
    int minRangeInt = 20;

    Double doubleDistance;
    int intDistance;

    private CheckBox checkBox_time, checkBox_luggage, checkBox_pets;
    private Boolean pets;

    private HashMap<String,Double> bounds;


    TextView priceTxt, examplePriceTxt, fetchRange, rangeValueTextView;
    EditText txtDate, txtTime, lahtoaikaSanallinen, matkatavaraSanallinen;
    private String departureTimeTxt, luggageTxt;
    NumberPicker numberPicker;
    SeekBar seekBar3, seekBar2, seekBar;
    Button confirmBtn;
    ImageButton timeBtn, luggageBtn, picUpBtn, rangeBtn, priceBtn;

    private Calendar calendar;
    private long systemTime = System.currentTimeMillis();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_set_ride_details);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        mC = new GregorianCalendar();

        initCalendarTimes();
        //Reitin tietojen vastaanotto setRideActivitystä
        if(savedInstanceState == null) {
            Bundle extras = getIntent().getExtras();
            if(extras == null) {
            } else {
                startAddress = extras.getString("ALKUOSOITE");
                endAddress = extras.getString("LOPPUOSOITE");
                startCity = extras.getString("STARTCITY");
                endCity = extras.getString("ENDCITY");
                distance = extras.getString("DISTANCE");
                duration = extras.getString("DURATION");
                selectedPoints = (List<HashMap<String, Double>>) extras.getSerializable("POINTS");
                bounds = (HashMap<String,Double>) extras.getSerializable("BOUNDS");
            }
        }else {
            startAddress = (String) savedInstanceState.getSerializable ("ALKUOSOITE");
            endAddress = (String) savedInstanceState.getSerializable ("LOPPUOSOITE");
            startCity = (String) savedInstanceState.getSerializable("STARTCITY");
            endCity = (String) savedInstanceState.getSerializable("ENDCITY");
            distance = (String) savedInstanceState.getSerializable ("DISTANCE");
            duration = (String) savedInstanceState.getSerializable ("DURATION");
            selectedPoints = (List<HashMap<String,Double>>) savedInstanceState.getSerializable("POINTS");
            bounds = (HashMap<String, Double>) savedInstanceState.getSerializable("BOUNDS");
        }

        //Muuttaa string distancen eri muuttujatyypeiksi
        if(distance != null && !distance.isEmpty()){
            doubleDistance = Double.valueOf(distance);
            intDistance = Integer.valueOf(doubleDistance.intValue());
        }

        //CheckBoxit
        checkBox_time = (CheckBox) findViewById(R.id.setRideDetails_checkBox_aika);
        checkBox_luggage = (CheckBox) findViewById(R.id.setRideDetails_checkBox_matkatavarat);
        checkBox_pets = (CheckBox) findViewById(R.id.setRideDetails_checkBox_lemmikit);
        checkBox_time.setOnClickListener(this);
        checkBox_luggage.setOnClickListener(this);
        checkBox_pets.setOnClickListener(this);

        //Buttonit
        confirmBtn = (Button) findViewById(R.id.setRideDetails_button_vahvista);
        confirmBtn.setOnClickListener(this);
        confirmBtn.setEnabled(false);

        //ImageButtonit
        timeBtn = (ImageButton) findViewById(R.id.setRideDetails_imageBtn_lahtoaika);
        luggageBtn = (ImageButton) findViewById(R.id.setRideDetails_imageBtn_tavaratila);
        picUpBtn = (ImageButton) findViewById(R.id.setRideDetails_imageBtn_nouto);
        rangeBtn = (ImageButton) findViewById(R.id.setRideDetails_imageBtn_matka);
        priceBtn = (ImageButton) findViewById(R.id.setRideDetails_imageBtn_hinta);
        timeBtn.setOnClickListener(this);
        luggageBtn.setOnClickListener(this);
        picUpBtn.setOnClickListener(this);
        rangeBtn.setOnClickListener(this);
        priceBtn.setOnClickListener(this);

        //Editorit
        txtDate = (EditText) findViewById(R.id.setRideDetails_editText_date);
        txtTime = (EditText) findViewById(R.id.setRideDetails_editText_time);
        lahtoaikaSanallinen = (EditText)findViewById(R.id.setRideDetails_editText_sanallinenAika);
        matkatavaraSanallinen = (EditText)findViewById(R.id.setRideDetails_editText_sanallinenTavaratila);
        txtDate.setOnClickListener(this);
        txtTime.setOnClickListener(this);

        //TextWatcherit varmistaa että lähtöpäivä ja -aika on määritetty
        txtDate.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if(!txtTime.getText().toString().equals(""))
                {
                    confirmBtn.setEnabled(true);
                }else{
                    confirmBtn.setEnabled(false);
                }
            }
        });
        txtTime.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if(!txtDate.getText().toString().equals(""))
                {
                    confirmBtn.setEnabled(true);
                }else{
                    confirmBtn.setEnabled(false);
                }
            }
        });

        //TextViewit
        priceTxt = (TextView) findViewById(R.id.setRideDetails_textView_hinta);
        examplePriceTxt = (TextView) findViewById(R.id.setRideDetails_textView_examplePrice);
        fetchRange = (TextView) findViewById(R.id.setRideDetails_textView_noutoEtaisyys);
        rangeValueTextView = (TextView) findViewById(R.id.setRideDetails_textView_minmatka);

        examplePriceTxt.setText(getString(R.string.setridedetails_distance_example) + " " +  distance + " km \n"
                + getString(R.string.setridedetails_price_example) + String.format("%.2f", doubleDistance * 0.03) + " fcfa");
        rangeValueTextView.setText(getString(R.string.setridedetails_ride_length_text) + " " +  minRangeInt + "km");
        fetchRange.setText(getString(R.string.setridedetails_max_pickup_dist_text) + " " +  pickUpDistance + "km");
        priceTxt.setText(String.format(getString(R.string.setridedetails_price_example) + " " +  "%.3f", price) + getString(R.string.setridedetails_km_example));

        //Number Picker matkustajien määritys
        numberPicker = findViewById(R.id.setRideDetails_numberPicker_passengers);
        numberPicker.setMinValue(1);
        numberPicker.setMaxValue(10);
        numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                passengers = newVal;
            }
        });


        //Seekbarien onBarChangeListenerit
        seekBar = (SeekBar) findViewById(R.id.setRideDetails_seekbar_nouto);
        seekBar2 = (SeekBar) findViewById(R.id.setRideDetails_seekbar_matka);
        seekBar3 = (SeekBar) findViewById(R.id.setRideDetails_seekbar_hinta);

        //Nouto etäisyys (pickUpDistance)
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                float tempDist = ((50 / 100.00f) * progress);
                pickUpDistance = (int) tempDist;
                //Log.d("####matka3####", range + ", " + intMatka + ", " + progress + ", " + (intMatka / 100.00f) * progress);
                fetchRange.setText(getString(R.string.setridedetails_max_pickup_dist_text) + " " + pickUpDistance + "km");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        //Kuljettava matka
        seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                minRangeInt = (int) ((intDistance / 100.00f) * progress);
                DecimalFormat df = new DecimalFormat("#.##");
                rangeValueTextView.setText(getString(R.string.setridedetails_ride_length_text) + " " +  minRangeInt + " km");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        //Hinta:
        seekBar3.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                price = ((float) progress / 1000);
                priceTxt.setText(getString(R.string.setridedetails_price_hint) + " " + String.format("%.3f", price) + getString(R.string.setridedetails_km_example));
                //hintaTxt.setTextColor(Color.WHITE);
                examplePriceTxt.setText(getString(R.string.setridedetails_distance_example) + " " +  distance + " km \n" + getString(R.string.setridedetails_price_example) + " " +  String.format("%.2f", doubleDistance * price) + " fcfa");

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

    }

    private void initCalendarTimes()
    {
        calendar = Calendar.getInstance();
        mYear = calendar.get(Calendar.YEAR);
        mMonth = calendar.get(Calendar.MONTH);
        mDay = calendar.get(Calendar.DAY_OF_MONTH);

        strDate = String.valueOf(CalendarHelper.getDayString(systemTime) + "-" + CalendarHelper.getMonthString(systemTime) +
                "-" + CalendarHelper.getYearString(systemTime));

        strTime = String.valueOf(CalendarHelper.getHourString(systemTime) + ":" + CalendarHelper.getMinuteString(systemTime));


    }

    @Override
    public void onClick(View v) {

        /*
        if (v == txtDate) {
            final Calendar c = Calendar.getInstance();
            mYear = c.get(Calendar.YEAR);
            mMonth = c.get(Calendar.MONTH);
            mDay = c.get(Calendar.DAY_OF_MONTH);

            DatePickerDialog datePickerDialog = new DatePickerDialog(this,
                    new DatePickerDialog.OnDateSetListener() {
                        @Override
                        public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                            strDate = (dayOfMonth + "-" + (month+1) + "-" + year);
                            txtDate.setText(strDate);
                            pickedYear = year;
                            pickedMonth = month;
                            pickedDate = dayOfMonth;
                            Log.d("TAG", "onDateSet: " + pickedMonth);
                        }
                    }, mYear, mMonth, mDay);

            datePickerDialog.show();
        }else if (v == txtTime) {
            final Calendar c = Calendar.getInstance();
            mHour = c.get(Calendar.HOUR_OF_DAY);
            mMinute = c.get(Calendar.MINUTE);

            TimePickerDialog timePickerDialog = new TimePickerDialog(this,
                    new TimePickerDialog.OnTimeSetListener() {
                        @Override
                        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                            String format = "%1$02d";
                            String estHour = String.format(format, hourOfDay);
                            String estMin = String.format(format, minute);
                            strTime = (estHour + ":" + estMin);
                            txtTime.setText(strTime);
                            pickedHour = hourOfDay;
                            pickedMinute = minute;
                        }
                    }, mHour, mMinute, true);

            timePickerDialog.show();
        }*/

        //when you press DateEditText, it will open datePickerDialog where you can select date in dd-MM-yyyy
        if(v == txtDate){
            DatePickerDialog datePickerDialog = new DatePickerDialog(SetRideDetailsActivity.this, new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                    calendar.set(year, month, dayOfMonth);
                    strDate = new SimpleDateFormat("dd-MM-yyyy").format(calendar.getTime());
                    txtDate.setText(strDate);
                    pickedYear = calendar.get(Calendar.YEAR);
                    pickedMonth = calendar.get(Calendar.MONTH);
                    pickedDate = calendar.get(Calendar.DAY_OF_MONTH);
                }
            }, mYear, mMonth, mDay);
            datePickerDialog.show();
        }

        //when you click TimeText, it will popup timePickerDialog, where you set hours and minutes
        else if (v == txtTime){
            TimePickerDialog timePickerDialog = new TimePickerDialog(SetRideDetailsActivity.this, AlertDialog.THEME_HOLO_LIGHT, new TimePickerDialog.OnTimeSetListener() {
                @Override
                public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                    mHour = hourOfDay;
                    mMinute = minute;

                    String format = "%1$02d";
                    String estHour = String.format(format, hourOfDay);
                    String estMinute = String.format(format, minute);
                    strTime = estHour + ":" + estMinute;
                    txtTime.setText(strTime);
                }
            }, mHour, mMinute, true);
            timePickerDialog.show();
        }

        else if (v == timeBtn)
        {
            AlertDialog.Builder time = new AlertDialog.Builder(SetRideDetailsActivity.this);
            time.setTitle("Mon heure de départ peut changer:");
            time.setMessage("Vous ne connaissez pas votre heure de départ, pas de problème ! Vous pouvez marquer une estimation approximative de votre heure de départ dans le champ Heure de départ et écrire un message dans le champ de note, qui sera visible par les passagers lors de la recherche de trajets");
            time.setCancelable(true);

            time.setNeutralButton(
                    "OK",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    }
            );
            AlertDialog alert11 = time.create();
            alert11.show();
        }
        else if (v == luggageBtn)
        {
            AlertDialog.Builder luggage = new AlertDialog.Builder(SetRideDetailsActivity.this);
            luggage.setTitle("Espace bagages limité:");
            luggage.setMessage("Si votre espace de bagages est limité, vous pouvez écrire un message dans le champ pour les personnes réservant des trajets, par exemple : le trajet ne peut accueillir que des bagages pouvant être transportés sur vos genoux");
            luggage.setCancelable(true);

            luggage.setNeutralButton(
                    "OK",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    }
            );
            AlertDialog alert11 = luggage.create();
            alert11.show();
        }
        else if (v == picUpBtn)
        {
            AlertDialog.Builder time = new AlertDialog.Builder(SetRideDetailsActivity.this);
            time.setTitle("Distance de ramassage:");
            time.setMessage("Choisissez de combien vous pouvez vous écarter de l'itinéraire lors de la prise en charge d'un passager.");
            time.setCancelable(true);

            time.setNeutralButton(
                    "OK",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    }
            );
            AlertDialog alert11 = time.create();
            alert11.show();
        }
        else if (v == rangeBtn)
        {
            AlertDialog.Builder range = new AlertDialog.Builder(SetRideDetailsActivity.this);
            range.setTitle("Un voyage pour voyager:");
            range.setMessage("Vous pouvez définir une limite de kilomètres que le passager doit voyager avec vous au moins.");
            range.setCancelable(true);

            range.setNeutralButton(
                    "OK",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    }
            );
            AlertDialog alert11 = range.create();
            alert11.show();
        }
        else if (v == priceBtn)
        {
            AlertDialog.Builder price = new AlertDialog.Builder(SetRideDetailsActivity.this);
            price.setTitle("Prix en kilomètre");
            price.setMessage("Précisez le prix au kilomètre que vous souhaitez. Le prix total du trajet est déterminé par la durée du trajet du passager et le prix au kilomètre. Dans la case d'exemple, vous pouvez voir combien coûterait le trajet d'un passager pour toute la durée du trajet que vous avez indiqué. REMARQUE! Veuillez préciser le prix uniquement pour la distribution de carburant.");
            price.setCancelable(true);

            price.setNeutralButton(
                    "OK",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    }
            );
            AlertDialog alert11 = price.create();
            alert11.show();
        }

        if(checkBox_time.isChecked()) {
            lahtoaikaSanallinen.setVisibility(View.VISIBLE);
        } else {
            lahtoaikaSanallinen.setVisibility(View.GONE);
            lahtoaikaSanallinen.setText("");
            departureTimeTxt = "";
        }
        if(checkBox_luggage.isChecked()) {
            matkatavaraSanallinen.setVisibility(View.VISIBLE);
        } else {
            matkatavaraSanallinen.setVisibility(View.GONE);
            matkatavaraSanallinen.setText("");
            luggageTxt = "";
        }
        if(checkBox_pets.isChecked()) {
            pets = true;
        } else {
            pets = false;
        }
        if(v.getId() == R.id.setRideDetails_button_vahvista)
        {

            mC.set(pickedYear, pickedMonth, pickedDate, pickedHour, pickedMinute);
            leaveTime = mC.getTimeInMillis();

            departureTimeTxt = lahtoaikaSanallinen.getText().toString();
            luggageTxt = matkatavaraSanallinen.getText().toString();

            String departure = "";
            String luggage = "";
            String sPets = "";
            if(departureTimeTxt.length() == 0){ departureTimeTxt = null; }else {
                departure = "Message d'heure de départ: " + departureTimeTxt;
            }
            if(luggageTxt.length() == 0) { luggageTxt = null; }else {
                luggage = "Message bagages: " + luggageTxt;
            }
            if(pets == true){
                sPets = "Admissible";
            }else{
                sPets = "Interdit";
            }

            if(FirebaseHelper.loggedIn)
            {
                AlertDialog.Builder confirm = new AlertDialog.Builder(SetRideDetailsActivity.this);
                confirm.setTitle("Vérifiez les détails et confirmez");
                confirm.setMessage("Jour de départ: " + strDate + "\nHeure de départ: " + strTime + "\nPlaces libres: " + passengers + "\nDistance de ramassage: " + pickUpDistance + " km" +
                        "\nUn voyage pour voyager: " + minRangeInt + " km" + "\nPrix en kilomètre: " + price + "\nAnimaux domestiques: " + sPets + "\n" + departure + "\n" + luggage + "\n\nLes informations sont-elles correctes ? " );
                confirm.setCancelable(true);

                confirm.setPositiveButton(
                        "Oui",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                CREATE_RIDE_DEMO();
                            }
                        }
                );
                confirm.setNegativeButton(
                        "Ei",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.cancel();
                            }
                        }
                );
                AlertDialog alert11 = confirm.create();
                alert11.show();
            }
            else
            {
                FirebaseHelper.GoToLogin(getApplicationContext());
            }
        }
    }

    // TODO: DELETE THIS after proper implementation
    // now only creates rides with proper points and user but otherwise random values
    public void CREATE_RIDE_DEMO()
    {
        Ride r = new Ride(FirebaseHelper.getUid(), duration, leaveTime,
                startAddress, endAddress, passengers, price, doubleDistance,
                selectedPoints, bounds, new ArrayList<String>(),
                new ArrayList<String>(), 5, startCity, endCity, departureTimeTxt, luggageTxt, pets);
        FirebaseFirestore.getInstance().collection("rides").add(r).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
            @Override
            public void onComplete(@NonNull Task<DocumentReference> task) {
                if(task.isSuccessful())
                {
                    // Ride creation succesfull
                    showCustomDialogSuccessful();
                }
                else {
                    // Ride create failed
                    showCustomDialogFailed();
                }
            }
        });

    }

    private void showCustomDialogSuccessful() {
        ViewGroup viewGroup =  findViewById(android.R.id.content);
        View dialogView = LayoutInflater.from(this).inflate(R.layout.my_alertdialog, viewGroup, false);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setView(dialogView);
        AlertDialog alertDialog = builder.create();
        Button okBtn = (Button) dialogView.findViewById(R.id.my_alertdialog_buttonOk);
        okBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(),
                        MainActivity.class);
                startActivity(intent);
            }
        });
        alertDialog.show();
    }

    private void showCustomDialogFailed() {
        ViewGroup viewGroup2 =  findViewById(android.R.id.content);
        View dialogView2 = LayoutInflater.from(this).inflate(R.layout.my_alertdialog2, viewGroup2, false);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setView(dialogView2);
        AlertDialog alertDialog2 = builder.create();
        Button okBtn2 = (Button) dialogView2.findViewById(R.id.my_alertdialog2_buttonOk);
        okBtn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(),
                        MainActivity.class);
                startActivity(intent);
            }
        });
        alertDialog2.show();
    }

}
