content: package com.pomodoro.application.bottomSheetFragment;
  
  import android.annotation.SuppressLint;
  import android.app.AlarmManager;
  import android.app.DatePickerDialog;
  import android.app.Dialog;
  import android.app.PendingIntent;
  import android.app.TimePickerDialog;
  import android.content.Intent;
  import android.os.AsyncTask;
  import android.os.Build;
  import android.view.MotionEvent;
  import android.view.View;
  import android.widget.Button;
  import android.widget.EditText;
  import android.widget.Toast;
  
  import androidx.annotation.NonNull;
  import androidx.annotation.RequiresApi;
  
  import com.pomodoro.application.R;
  import com.pomodoro.application.activity.MainActivity;
  import com.pomodoro.application.broadcastReceiver.AlarmBroadcastReceiver;
  import com.pomodoro.application.broadcastReceiver.database.DatabaseClient;
  
  import com.pomodoro.application.model.Task;
  import com.google.android.material.bottomsheet.BottomSheetBehavior;
  import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
  
  import java.util.Calendar;
  import java.util.Date;
  import java.util.GregorianCalendar;
  
  import butterknife.BindView;
  import butterknife.ButterKnife;
  import butterknife.Unbinder;
  
  import static android.content.Context.ALARM_SERVICE;
  
  public class CreateTaskBottomSheetFragment extends BottomSheetDialogFragment {
      Date currentTime = Calendar.getInstance().getTime();
      int minHour = currentTime.getHours();
      int minMin = currentTime.getMinutes();
      Unbinder unbinder;
      @BindView(R.id.addTaskTitle)
      EditText addTaskTitle;
      @BindView(R.id.taskDate)
      EditText taskDate;
      @BindView(R.id.taskTime)
      EditText taskTime;
      @BindView(R.id.addTask)
      Button addTask;
      int taskId;
      boolean isEdit;
      Task task;
      int mYear, mMonth, mDay;
      int mHour, mMinute;
      setRefreshListener setRefreshListener;
      AlarmManager alarmManager;
      TimePickerDialog timePickerDialog;
      DatePickerDialog datePickerDialog;
      MainActivity activity;
      public static int count = 0;
  
      private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
  
          @Override
          public void onStateChanged(@NonNull View bottomSheet, int newState) {
              if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                  dismiss();
              }
          }
  
          @Override
          public void onSlide(@NonNull View bottomSheet, float slideOffset) {
          }
      };
  
      public void setTaskId(int taskId, boolean isEdit, setRefreshListener setRefreshListener, MainActivity activity) {
          this.taskId = taskId;
          this.isEdit = isEdit;
          this.activity = activity;
          this.setRefreshListener = setRefreshListener;
      }
  
      @RequiresApi(api = Build.VERSION_CODES.O)
      @SuppressLint({"RestrictedApi", "ClickableViewAccessibility", "SuspiciousIndentation"})
      @Override
      public void setupDialog(Dialog dialog, int style) {
          super.setupDialog(dialog, style);
          View contentView = View.inflate(getContext(), R.layout.fragment_create_task, null);
          unbinder = ButterKnife.bind(this, contentView);
          dialog.setContentView(contentView);
          alarmManager = (AlarmManager) getActivity().getSystemService(ALARM_SERVICE);
          addTask.setOnClickListener(view -> {
              if(validateFields())
              createTask();
          });
          if (isEdit) {
              showTaskFromId();
          }
  
          taskDate.setOnTouchListener((view, motionEvent) -> {
              if(motionEvent.getAction() == MotionEvent.ACTION_UP) {
                  final Calendar c = Calendar.getInstance();
                  mYear = c.get(Calendar.YEAR);
                  mMonth = c.get(Calendar.MONTH);
                  mDay = c.get(Calendar.DAY_OF_MONTH);
                  datePickerDialog = new DatePickerDialog(getActivity(),
                          (view1, year, monthOfYear, dayOfMonth) -> {
                              taskDate.setText(dayOfMonth + "-" + (monthOfYear + 1) + "-" + year);
                              datePickerDialog.dismiss();
                          }, mYear, mMonth, mDay);
                  datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
                  datePickerDialog.show();
              }
              return true;
          });
  
          taskTime.setOnTouchListener((view, motionEvent) -> {
              if(motionEvent.getAction() == MotionEvent.ACTION_UP) {
                  // Get Current Time
                  final Calendar c = Calendar.getInstance();
                  mHour = c.get(Calendar.HOUR_OF_DAY);
                  mMinute = c.get(Calendar.MINUTE);
  
                  // Launch Time Picker Dialog
                  timePickerDialog = new TimePickerDialog(getActivity(),
                          (view12, hourOfDay, minute) -> {
                              taskTime.setText(hourOfDay + ":" + minute);
                              timePickerDialog.dismiss();
                          }, mHour, mMinute, false);
                  timePickerDialog.show();
              }
              return true;
          });
      }
  
      public boolean validateFields() {
          String inpTime[] = taskTime.getText().toString().split(":");
          int inpHour = Integer.parseInt(inpTime[0]);
          int inpMin = Integer.parseInt(inpTime[1]);
  
          if(addTaskTitle.getText().toString().equalsIgnoreCase("")) {
              Toast.makeText(activity, "Please enter a valid title", Toast.LENGTH_SHORT).show();
              return false;
          }
          else if(taskDate.getText().toString().equalsIgnoreCase("")) {
              Toast.makeText(activity, "Please enter date", Toast.LENGTH_SHORT).show();
              return false;
          }
          else if(taskTime.getText().toString().equalsIgnoreCase("")) {
              Toast.makeText(activity, "Please enter time", Toast.LENGTH_SHORT).show();
              return false;
          }
          else if(inpHour < minHour){
              if(inpMin < minMin) {
                  Toast.makeText(activity, "Time must be beyond current time", Toast.LENGTH_SHORT).show();
                  return false;
              }
              else{
                  Toast.makeText(activity, "Time must be beyond current time", Toast.LENGTH_SHORT).show();
                  return false;
              }
          }
          else if(inpHour == minHour && inpMin < minMin){
              Toast.makeText(activity, "Time must be beyond current time", Toast.LENGTH_SHORT).show();
              return false;
          }
          else {
              return true;
          }
      }
  
      @Override
      public void onDestroyView() {
          super.onDestroyView();
      }
  
      private void createTask() {
          class saveTaskInBackend extends AsyncTask<Void, Void, Void> {
              @SuppressLint("WrongThread")
              @Override
              protected Void doInBackground(Void... voids) {
                  Task createTask = new Task();
                  createTask.setTaskTitle(addTaskTitle.getText().toString());
                  createTask.setDate(taskDate.getText().toString());
                  createTask.setLastAlarm(taskTime.getText().toString());
  
                  if (!isEdit)
                      DatabaseClient.getInstance(getActivity()).getAppDatabase()
                              .dataBaseAction()
                              .insertDataIntoTaskList(createTask);
                  else
                      DatabaseClient.getInstance(getActivity()).getAppDatabase()
                              .dataBaseAction()
                              .updateAnExistingRow(taskId, addTaskTitle.getText().toString(),
                                      taskDate.getText().toString(),
                                      taskTime.getText().toString());
  
  
                  return null;
              }
  
              @Override
              protected void onPostExecute(Void aVoid) {
                  super.onPostExecute(aVoid);
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                      createAnAlarm();
                  }
                  setRefreshListener.refresh();
                  Toast.makeText(getActivity(), "Task successfully added!", Toast.LENGTH_SHORT).show();
                  dismiss();
  
              }
          }
          saveTaskInBackend st = new saveTaskInBackend();
          st.execute();
      }
  
      @RequiresApi(api = Build.VERSION_CODES.M)
      public void createAnAlarm() {
          try {
              String[] items1 = taskDate.getText().toString().split("-");
              String dd = items1[0];
  
              String[] itemTime = taskTime.getText().toString().split(":");
              String hour = itemTime[0];
              String min = itemTime[1];
  
              Calendar cur_cal = new GregorianCalendar();
              cur_cal.setTimeInMillis(System.currentTimeMillis());
  
              Calendar cal = new GregorianCalendar();
              cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour));
              cal.set(Calendar.MINUTE, Integer.parseInt(min));
              cal.set(Calendar.SECOND, 0);
              cal.set(Calendar.MILLISECOND, 0);
              cal.set(Calendar.DATE, Integer.parseInt(dd)-1);
  
              Intent alarmIntent = new Intent(activity, AlarmBroadcastReceiver.class);
              alarmIntent.putExtra("TITLE", addTaskTitle.getText().toString());
              alarmIntent.putExtra("DATE", taskDate.getText().toString());
              alarmIntent.putExtra("TIME", taskTime.getText().toString());
              PendingIntent pendingIntent = PendingIntent.getBroadcast(activity,count, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                  alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                      alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
                  } else {
                      alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
                  }
                  count ++;
  
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      private void showTaskFromId() {
          class showTaskFromId extends AsyncTask<Void, Void, Void> {
              @SuppressLint("WrongThread")
              @Override
              protected Void doInBackground(Void... voids) {
                  task = DatabaseClient.getInstance(getActivity()).getAppDatabase()
                          .dataBaseAction().selectDataFromAnId(taskId);
                  return null;
              }
  
              @Override
              protected void onPostExecute(Void aVoid) {
                  super.onPostExecute(aVoid);
                  setDataInUI();
              }
          }
          showTaskFromId st = new showTaskFromId();
          st.execute();
      }
  
      private void setDataInUI() {
          addTaskTitle.setText(task.getTaskTitle());
          taskDate.setText(task.getDate());
          taskTime.setText(task.getLastAlarm());
  
      }
  
      public interface setRefreshListener {
          void refresh();
      }
  }
  