package ch.pizzalemon.android.fragment.createOrder;

import static com.braintreepayments.api.ThreeDSecureRequest.VERSION_2;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.braintreepayments.api.DropInClient;
import com.braintreepayments.api.DropInListener;
import com.braintreepayments.api.DropInRequest;
import com.braintreepayments.api.DropInResult;
import com.braintreepayments.api.PayPalRequest;
import com.braintreepayments.api.ThreeDSecureAdditionalInformation;
import com.braintreepayments.api.ThreeDSecurePostalAddress;
import com.braintreepayments.api.ThreeDSecureRequest;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import com.wdullaer.materialdatetimepicker.time.Timepoint;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import butterknife.BindString;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import ch.pizzalemon.android.R;
import ch.pizzalemon.android.activity.BaseActivity;
import ch.pizzalemon.android.activity.CreateOrderActivity;
import ch.pizzalemon.android.adapter.recycler.OrderPriceRecyclerAdapter;
import ch.pizzalemon.android.adapter.recycler.ProductOnOrderSummaryRecyclerAdapter;
import ch.pizzalemon.android.api.ApiConstants;
import ch.pizzalemon.android.api.ApiEndPoints;
import ch.pizzalemon.android.api.ApiErrorUtils;
import ch.pizzalemon.android.api.ApiService;
import ch.pizzalemon.android.api.ResponseObject;
import ch.pizzalemon.android.helper.DialogHelper;
import ch.pizzalemon.android.helper.PriceHelper;
import ch.pizzalemon.android.helper.SessionHelper;
import ch.pizzalemon.android.helper.SharedPrefsHelper;
import ch.pizzalemon.android.model.PaymentMethodModel;
import ch.pizzalemon.android.model.PaymentTokenModel;
import ch.pizzalemon.android.model.StoreShiftModel;
import ch.pizzalemon.android.model.UserModel;
import ch.pizzalemon.android.model.cart.CartInfoModel;
import ch.pizzalemon.android.model.cart.CartProductModel;
import ch.pizzalemon.android.model.cart.CartTotalModel;
import ch.pizzalemon.android.view.AppInfoView;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by cimenmus on 17/10/2017.
 */

public class CreateOrderSummaryFragment extends CreateOrderBaseFragment implements DropInListener {

    @BindView(R.id.orderPersonFullnamePizzalinkInfoLayout) AppInfoView orderPersonFullnamePizzalinkInfoLayout;
    @BindView(R.id.orderShippingMethodPizzalinkInfoLayout) AppInfoView orderShippingMethodPizzalinkInfoLayout;
    @BindView(R.id.orderShippingAddressPizzalinkInfoLayout) AppInfoView orderShippingAddressPizzalinkInfoLayout;
    @BindView(R.id.orderPaymentMethodPizzalinkInfoLayout) AppInfoView orderPaymentMethodPizzalinkInfoLayout;
    //@BindView(R.id.orderTotalPizzalinkInfoLayout) AppInfoView orderTotalPizzalinkInfoLayout;
    @BindView(R.id.orderPriceRecyclerView) RecyclerView orderPriceRecyclerView;
    @BindView(R.id.orderProductsRecyclerView) RecyclerView orderProductsRecyclerView;
    @BindView(R.id.orderNotePizzalinkInfoLayout) AppInfoView orderNotePizzalinkInfoLayout;

    @BindString(R.string.confirm_order) String confirmOrderText;
    @BindString(R.string.slice_pizza_for_store) String slicePizzaForStoreText;
    @BindString(R.string.slice_pizza) String yesText;
    @BindString(R.string.do_not_slice_pizza) String noText;
    @BindString(R.string.restaurant_out_of_order) String restaurantOutOfOrderText;
    @BindString(R.string.choose_pick_up_date_time) String choosePickUpDateTimeText;
    @BindString(R.string.something_went_wrong) String genericErrorText;
    @BindString(R.string.unknown_payment_method) String unknownPaymentMethodText;
    @BindString(R.string.payment_canceled) String paymentCanceledText;
    @BindString(R.string.andorid_pay_not_found) String androidPayNotFoundText;
    @BindString(R.string.choose) String choosetext;
    @BindString(R.string.alert) String alertText;
    @BindString(R.string.delivery_date) String deliveryDateText;
    @BindString(R.string.delivery_time) String deliveryTimeText;

    public static final java.lang.String FRAGMENT_NAME = "orderSummaryFragment";
    private final int REQUEST_CODE_BRAINTREE_PAYMENT = 3784;
    private CreateOrderActivity createOrderActivity;
    private String dateOfOrderString, timeOfOrder;
    private Calendar dateOfOrder;
    private ArrayList<CartTotalModel> cartTotalList = new ArrayList<>();
    private OrderPriceRecyclerAdapter orderPriceRecyclerAdapter;
    private ProductOnOrderSummaryRecyclerAdapter productOnOrderSummaryRecyclerAdapter;
    private StoreShiftModel storeShiftModel;
    private PaymentTokenModel braintreePaymentTokenModel;

    private DropInClient dropInClient = null;

    public CreateOrderSummaryFragment() {}

    public static CreateOrderSummaryFragment newInstance(PaymentTokenModel paymentTokenModel) {
        Bundle args = new Bundle();
        args.putSerializable("braintreePaymentTokenModel", paymentTokenModel);
        CreateOrderSummaryFragment fragment = new CreateOrderSummaryFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_create_order_summary, container, false);
        getDataFromArguments();
        ButterKnife.bind(this, view);
        initViews();
        getCartProductsWithCommission();
        return view;
    }

    private void getDataFromArguments(){
        braintreePaymentTokenModel = (PaymentTokenModel) getArguments().getSerializable("braintreePaymentTokenModel");
        if (braintreePaymentTokenModel != null && braintreePaymentTokenModel.getToken() != null){
            dropInClient = new DropInClient(CreateOrderSummaryFragment.this, braintreePaymentTokenModel.getToken());
        }
    }

    @Override
    public void onDropInSuccess(@NonNull DropInResult dropInResult) {
        if (dropInResult.getPaymentMethodType() != null && dropInResult.getPaymentMethodNonce() != null){
            createOrderActivity.setSelectedPaymentMethodForBraintree(dropInResult.getPaymentMethodType());
            createBraintreePayment(dropInResult);
        }
    }

    @Override
    public void onDropInFailure(@NonNull Exception error) {
        DialogHelper.showAlertDialog(BaseActivity.currentActivity, error.getMessage());
    }

    @OnClick({R.id.previousTextView, R.id.nextTextView})
    protected void onClick(View view){
        CreateOrderActivity createOrderActivity = (CreateOrderActivity) BaseActivity.currentActivity;
        switch (view.getId()){
            case R.id.previousTextView:
                createOrderActivity.onPreviousClicked(FRAGMENT_NAME);
                break;
            case R.id.nextTextView:
                checkOrderPrice();
                break;
        }
    }

    private void initViews(){

        nextTextView.setText(confirmOrderText);

        createOrderActivity = (CreateOrderActivity) BaseActivity.currentActivity;

        orderPersonFullnamePizzalinkInfoLayout.setText(SessionHelper.getUser().getFullname());
        orderShippingMethodPizzalinkInfoLayout.setText(createOrderActivity.getSelectedShippingMethod().getTitle());
        orderShippingAddressPizzalinkInfoLayout.setText(createOrderActivity.getSelectedShippingAddress().getAddress());
        orderPaymentMethodPizzalinkInfoLayout.setText(createOrderActivity.getSelectedPaymentMethod().getTitle());
        //orderTotalPizzalinkInfoLayout.setText(PriceHelper.roundFractions(createOrderActivity.getCartInfo().getCartTotalModel().getText()));
        if(createOrderActivity.getOrderNote().trim().isEmpty()){
            orderNotePizzalinkInfoLayout.setVisibility(View.GONE);
        }
        else {
            orderNotePizzalinkInfoLayout.setVisibility(View.VISIBLE);
            orderNotePizzalinkInfoLayout.setText(createOrderActivity.getOrderNote());
        }

        initOrderPriceRecyclerView();
        initOrderProductsRecyclerView();

    }

    private void initOrderPriceRecyclerView(){
        orderPriceRecyclerAdapter = new OrderPriceRecyclerAdapter(cartTotalList);
        orderPriceRecyclerView.setLayoutManager(new LinearLayoutManager(BaseActivity.currentActivity));
        orderPriceRecyclerView.setNestedScrollingEnabled(false);
        orderPriceRecyclerView.setAdapter(orderPriceRecyclerAdapter);
    }

    private void initOrderProductsRecyclerView(){
        productOnOrderSummaryRecyclerAdapter = new ProductOnOrderSummaryRecyclerAdapter(createOrderActivity.getCartInfo().getProducts());
        orderProductsRecyclerView.setLayoutManager(new LinearLayoutManager(BaseActivity.currentActivity));
        orderProductsRecyclerView.setNestedScrollingEnabled(false);
        orderProductsRecyclerView.setAdapter(productOnOrderSummaryRecyclerAdapter);
    }

    private void checkOrderPrice(){

        DialogHelper.showLoadingDialog();

        HashMap<String, Object> params = new HashMap<>();
        params.put("customer_id", SessionHelper.getUser().getId());
        params.put("shipping_method_title", createOrderActivity.getSelectedShippingMethod().getTitle());
        params.put("shipping_method_code", createOrderActivity.getSelectedShippingMethod().getCode());
        params.put("address_id", createOrderActivity.getSelectedShippingAddress().getId());
        params.put("payment_method_title", createOrderActivity.getSelectedPaymentMethod().getTitle());
        params.put("payment_method_code", createOrderActivity.getSelectedPaymentMethod().getCode());
        params.put("comment", createOrderNote());
        params.put("is_pizza_pass_campaign", createOrderActivity.getCartInfo().isPizzaPassCampaignUsed());
        params.put("application_id", ApiConstants.APP_TYPE_ID_ANDROID);
        SessionHelper.addCouponCodeToRequestParamsIfNeeded(params);
        if(dateOfOrderString != null && !dateOfOrderString.isEmpty() &&
                timeOfOrder != null && !timeOfOrder.isEmpty()){
            params.put("delivery_date", dateOfOrderString + " " + timeOfOrder);
        }

        Call<ResponseObject> call = ApiService.apiInterface.checkOrderPrice(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_CHECK_ORDER_PRICE + SessionHelper.getCustomerToken().getToken(), params);
        call.enqueue(new Callback<ResponseObject>() {
            @Override
            public void onResponse(Call<ResponseObject> call, Response<ResponseObject> response) {
                if(response.isSuccessful() && response.body().isSuccess()){
                    checkDeliveryTimeForPreferenceDialog();
                }
                else{
                    DialogHelper.hideLoadingDialog();
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseObject> call, Throwable t) {
                DialogHelper.hideLoadingDialog();
                DialogHelper.showFailedDialog();
            }
        });

    }

    private void checkDeliveryTime(){
        ApiService
                .apiInterface
                .checkDeliveryTime(
                        SessionHelper.getSelectedStore().getStoreName(),
                        createOrderActivity.getSelectedShippingMethod().getCode())
                .enqueue(new Callback<ResponseObject<Boolean>>() {
                    @Override
                    public void onResponse(Call<ResponseObject<Boolean>> call, Response<ResponseObject<Boolean>> response) {
                        if(response.isSuccessful() &&
                                response.body() != null){

                            if(response.body().isSuccess()){
                                redirectToPayment();
                            }
                            else {
                                getDeliveryTimeOfStore(restaurantOutOfOrderText);
                            }

                        }
                        else{
                            DialogHelper.hideLoadingDialog();
                            ApiErrorUtils.parseError(response);
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseObject<Boolean>> call, Throwable t) {
                        DialogHelper.hideLoadingDialog();
                        DialogHelper.showFailedDialog();
                    }
                });
    }

    private void checkDeliveryTimeForPreferenceDialog(){
        ApiService
                .apiInterface
                .checkDeliveryTime(
                        SessionHelper.getSelectedStore().getStoreName(),
                        createOrderActivity.getSelectedShippingMethod().getCode())
                .enqueue(new Callback<ResponseObject<Boolean>>() {
                    @Override
                    public void onResponse(Call<ResponseObject<Boolean>> call, Response<ResponseObject<Boolean>> response) {
                        DialogHelper.hideLoadingDialog();
                        if(response.isSuccessful() && response.body() != null){

                            if(response.body().isSuccess()){
                                showDeliveryTimePreferenceDialogWithTwoButtons();
                            }
                            else {
                                showDeliveryTimePreferenceDialogWithOneButton();
                            }

                        }
                        else{
                            ApiErrorUtils.parseError(response);
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseObject<Boolean>> call, Throwable t) {
                        DialogHelper.hideLoadingDialog();
                        DialogHelper.showFailedDialog();
                    }
                });
    }

    private void showDeliveryTimePreferenceDialogWithTwoButtons(){
        DialogHelper.showTwoButtonsDialog(
                getString(R.string.info),
                getString(R.string.delivery_time_preference_message),
                R.string.delivery_time_preference_as_soon_as_possible,
                new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        DialogHelper.showLoadingDialog();
                        checkDeliveryTime();
                    }
                },
                R.string.delivery_time_preference_choose_delivery_time,
                new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        DialogHelper.showLoadingDialog();
                        getDeliveryTimeOfStore(null);
                    }
                },
                false,
                true
        );

    }

    private void showDeliveryTimePreferenceDialogWithOneButton(){
        DialogHelper.showOneButtonDialogWithCallback(
                getString(R.string.info),
                getString(R.string.delivery_time_preference_message),
                getString(R.string.delivery_time_preference_choose_delivery_time),
                new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        DialogHelper.showLoadingDialog();
                        getDeliveryTimeOfStore(null);
                    }
                },
                false,
                true
        );
    }

    private void getDeliveryTimeOfStore(final String dialogMessage){
        ApiService
                .apiInterface
                .getDeliveryTimeOfStore(
                        SessionHelper.getSelectedStore().getStoreName(),
                        createOrderActivity.getSelectedShippingMethod().getCode())
                .enqueue(new Callback<ResponseObject<StoreShiftModel>>() {
                    @Override
                    public void onResponse(Call<ResponseObject<StoreShiftModel>> call, Response<ResponseObject<StoreShiftModel>> response) {
                        DialogHelper.hideLoadingDialog();
                        if(response.isSuccessful() &&
                                response.body() != null){

                            if(response.body().isSuccess()){
                                storeShiftModel = response.body().getData();
                                if(dialogMessage == null || dialogMessage.isEmpty()){
                                    showDatePickerDialog();
                                }
                                else {
                                    showRestaurantOutOfOrderDialog(dialogMessage + getWorkingHoursString());
                                }
                            }
                            else {
                                DialogHelper.showAlertDialog(BaseActivity.currentActivity, genericErrorText);
                            }

                        }
                        else{
                            DialogHelper.hideLoadingDialog();
                            ApiErrorUtils.parseError(response);
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseObject<StoreShiftModel>> call, Throwable t) {
                        DialogHelper.hideLoadingDialog();
                        DialogHelper.showFailedDialog();
                    }
                });
    }

    private void checkDeliveryTimeWithDateAndTime(){
        DialogHelper.showLoadingDialog();
        String deliveryDateAndTime = dateOfOrderString + " " + timeOfOrder;
        ApiService
                .apiInterface
                .checkDeliveryTimeWithDateAndTime(
                        SessionHelper.getSelectedStore().getStoreName(),
                        deliveryDateAndTime,
                        createOrderActivity.getSelectedShippingMethod().getCode())
                .enqueue(new Callback<ResponseObject<Boolean>>() {
                    @Override
                    public void onResponse(Call<ResponseObject<Boolean>> call, Response<ResponseObject<Boolean>> response) {
                        DialogHelper.hideLoadingDialog();
                        if(response.isSuccessful() &&
                                response.body() != null){

                            if(response.body().isSuccess()){
                                redirectToPayment();
                            }
                            else {
                                showRestaurantOutOfOrderDialog(restaurantOutOfOrderText + getWorkingHoursString());
                            }

                        }
                        else{
                            ApiErrorUtils.parseError(response);
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseObject<Boolean>> call, Throwable t) {
                        DialogHelper.hideLoadingDialog();
                        DialogHelper.showFailedDialog();
                    }
                });
    }

    private void showRestaurantOutOfOrderDialog(String message){

        DialogHelper.showTwoButtonsDialog(
                alertText,
                message,
                R.string.ok,
                new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        showDatePickerDialog();
                    }
                },
                R.string.cancel_all_caps,
                new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        dialog.dismiss();
                    }
                }
        );
    }

    private void showDatePickerDialog() {

        Calendar nowDate = Calendar.getInstance();
        final int nowYear = nowDate.get(Calendar.YEAR);
        final int nowMonth = nowDate.get(Calendar.MONTH);
        final int nowDay = nowDate.get(Calendar.DAY_OF_MONTH);

        if(nowDate.get(Calendar.HOUR_OF_DAY) == 23){
            nowDate.add(Calendar.DAY_OF_YEAR, 1);
        }

        DatePickerDialog datePickerDialog = DatePickerDialog.newInstance(
                new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {

                        String yearOfOrder = String.valueOf(year);
                        String monthOfOrder = String.valueOf(monthOfYear + 1);
                        String dayOfOrder = String.valueOf(dayOfMonth);

                        if(monthOfOrder.length() == 1){
                            monthOfOrder = "0" + monthOfOrder;
                        }

                        if(dayOfOrder.length() == 1){
                            dayOfOrder = "0" + dayOfOrder;
                        }

                        dateOfOrder = Calendar.getInstance();
                        dateOfOrder.set(year, monthOfYear, dayOfMonth);

                        dateOfOrderString = dayOfOrder + "-" + monthOfOrder + "-" + yearOfOrder;
                        showTimePickerDialog();
                    }
                },
                nowYear,
                nowMonth,
                nowDay
        );

        datePickerDialog.setSelectableDays(generateEnabledDays());

        datePickerDialog.vibrate(false);
        datePickerDialog.setMinDate(nowDate);
        //datePickerDialog.autoDismiss(true);
        datePickerDialog.show(BaseActivity.currentActivity.getSupportFragmentManager(), choosetext);
    }

    private void showTimePickerDialog(){

        Calendar nowDate = Calendar.getInstance();

        boolean isTheSameDate =
                dateOfOrder.get(Calendar.YEAR) == nowDate.get(Calendar.YEAR) &&
                dateOfOrder.get(Calendar.MONTH) == nowDate.get(Calendar.MONTH) &&
                dateOfOrder.get(Calendar.DAY_OF_MONTH) == nowDate.get(Calendar.DAY_OF_MONTH);

        if(isTheSameDate &&
                createOrderActivity.getSelectedShippingMethod().getCode().toLowerCase().equals(ApiConstants.SHIPPING_METHOD_CODE_FREE_SHIPPING)){
            nowDate.add( Calendar.MINUTE, 65);
        }
        else if(isTheSameDate &&
                createOrderActivity.getSelectedShippingMethod().getCode().toLowerCase().equals(ApiConstants.SHIPPING_METHOD_CODE_PICK_UP_FROM_STORE)){
            nowDate.add( Calendar.MINUTE, 25);
        }
        else if(isTheSameDate){
            nowDate.add( Calendar.MINUTE, 10);
        }

        int orderYear = dateOfOrder.get(Calendar.YEAR);
        int orderMonth = dateOfOrder.get(Calendar.MONTH);
        int orderDay = dateOfOrder.get(Calendar.DAY_OF_MONTH);

        int nowYear = nowDate.get(Calendar.YEAR);
        int nowMonth = nowDate.get(Calendar.MONTH);
        int nowDay = nowDate.get(Calendar.DAY_OF_MONTH);

        int nowHour = nowDate.get(Calendar.HOUR_OF_DAY);
        int nowMinute = nowDate.get(Calendar.MINUTE);
        int nowSecond = nowDate.get(Calendar.SECOND);

        int selectedDayIndex = dateOfOrder.get(Calendar.DAY_OF_WEEK);
        ArrayList<String> workingParts = new ArrayList<>();
        switch (selectedDayIndex){
            case 1:
                workingParts = storeShiftModel.getSundayShift();
                break;
            case 2:
                workingParts = storeShiftModel.getMondayShift();
                break;
            case 3:
                workingParts = storeShiftModel.getTuesdayShift();
                break;
            case 4:
                workingParts = storeShiftModel.getWednesdayShift();
                break;
            case 5:
                workingParts = storeShiftModel.getThursdayShift();
                break;
            case 6:
                workingParts = storeShiftModel.getFridayShift();
                break;
            case 7:
                workingParts = storeShiftModel.getSaturdayShift();
                break;
        }

        TimePickerDialog timePickerDialog =
                TimePickerDialog.newInstance(
                        new TimePickerDialog.OnTimeSetListener() {
                            @Override
                            public void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second) {

                                String hourOfOrder = String.valueOf(hourOfDay);
                                String minuteOfOrder = String.valueOf(minute);

                                if(hourOfOrder.length() == 1){
                                    hourOfOrder = "0" + hourOfOrder;
                                }

                                if(minuteOfOrder.length() == 1){
                                    minuteOfOrder = "0" + minuteOfOrder;
                                }

                                timeOfOrder = hourOfOrder + ":" + minuteOfOrder;
                                checkDeliveryTimeWithDateAndTime();
                                //redirectToPayment();
                            }
                        },
                        nowHour,
                        nowMinute,
                        true
                );

        StringBuilder restaurantWorkingHoursMessageBuilder = new StringBuilder(getString(R.string.delivery_times_of_restaurant));
        restaurantWorkingHoursMessageBuilder.append(" ");
        for(String workingPart: workingParts){
            restaurantWorkingHoursMessageBuilder.append(workingPart).append(", ");
        }
        String restaurantWorkingHoursMessage = restaurantWorkingHoursMessageBuilder.toString().substring(0, restaurantWorkingHoursMessageBuilder.toString().length() - 2);

        /*
        time point removed

        if(orderYear == nowYear && orderMonth == nowMonth && orderDay == nowDay){
            ArrayList<String> realPartsOfToday = new ArrayList<>();
            for(String part : workingParts){
                if(isPartAvailable(part)){
                    realPartsOfToday.add(part);
                }
            }
            if(!realPartsOfToday.isEmpty()){
                workingParts.clear();
                workingParts.addAll(realPartsOfToday);
            }
        }

        Timepoint[] enabledTimePoints = generateEnabledTimePoints(workingParts);
        timePickerDialog.setSelectableTimes(enabledTimePoints);
         */
        timePickerDialog.vibrate(false);
        timePickerDialog.setTitle(restaurantWorkingHoursMessage);

        if(isTheSameDate){
            /*
            time point removed
            boolean isMinimumTimeInTimePoints = false;
            for(Timepoint timepoint : enabledTimePoints){
                if(timepoint.getHour() == nowHour && timepoint.getMinute() == nowMinute){
                    isMinimumTimeInTimePoints = true;
                    break;
                }
            }

            if(isMinimumTimeInTimePoints){
                timePickerDialog.setMinTime(nowHour, nowMinute, nowSecond);
            }
            else if(enabledTimePoints.length > 0) {
                timePickerDialog.setMinTime(enabledTimePoints[0].getHour(), enabledTimePoints[0].getMinute(), nowSecond);
            }
            */
            timePickerDialog.setMinTime(nowHour, nowMinute, nowSecond);

        }

        timePickerDialog.show(BaseActivity.currentActivity.getSupportFragmentManager(), choosetext);
    }

    private void redirectToPayment(){

        switch (createOrderActivity.getSelectedPaymentMethod().getPaymentMethodType()){

            case UNKNOWN:
                DialogHelper.hideLoadingDialog();
                DialogHelper.showAlertDialog(BaseActivity.currentActivity, unknownPaymentMethodText);
                break;

            case CASH:
            case TRANSFER:
            case POST_FINANCE_CARD:
            case TWINT:
                createOrder(getCreateOrderParams(null));
                break;

            default:
                DialogHelper.hideLoadingDialog();
                startBraintreePayment();
        }
    }

    private void createOrder(HashMap<String, Object> params){
        DialogHelper.showLoadingDialog();
        Call<ResponseObject<Integer>> call = ApiService.apiInterface.createOrder(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_CREATE_ORDER + SessionHelper.getCustomerToken().getToken(), params);
        call.enqueue(new Callback<ResponseObject<Integer>>() {
            @Override
            public void onResponse(Call<ResponseObject<Integer>> call, Response<ResponseObject<Integer>> response) {
                DialogHelper.hideLoadingDialog();
                if(response.isSuccessful() && response.body().isSuccess()){

                    if(createOrderActivity.getSelectedPaymentMethod().getPaymentMethodType() == PaymentMethodModel.PaymentMethodType.POST_FINANCE_CARD ||
                            createOrderActivity.getSelectedPaymentMethod().getPaymentMethodType() == PaymentMethodModel.PaymentMethodType.TWINT){
                        showPaymentWebView(response.body().getData());
                    }
                    else {
                        createOrderActivity.onNextClicked(FRAGMENT_NAME);
                    }
                }
                else{
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseObject<Integer>> call, Throwable t) {
                DialogHelper.hideLoadingDialog();
                DialogHelper.showFailedDialog();
            }
        });
    }

    // for braintree payment
    private HashMap<String, Object> getCreateOrderParams(String paymentMethodNonce){
        HashMap<String, Object> params = new HashMap<>();
        params.put("customer_id", SessionHelper.getUser().getId());
        params.put("shipping_method_title", createOrderActivity.getSelectedShippingMethod().getTitle());
        params.put("shipping_method_code", createOrderActivity.getSelectedShippingMethod().getCode());
        params.put("address_id", createOrderActivity.getSelectedShippingAddress().getId());
        params.put("payment_method_title", createOrderActivity.getSelectedPaymentMethod().getTitle());
        params.put("payment_method_code", createOrderActivity.getSelectedPaymentMethod().getCode());
        params.put("comment", createOrderNote());
        params.put("is_pizza_pass_campaign", createOrderActivity.getCartInfo().isPizzaPassCampaignUsed());
        params.put("application_id", ApiConstants.APP_TYPE_ID_ANDROID);
        if(paymentMethodNonce != null){
            params.put("payment_method_nonce", paymentMethodNonce);
        }
        SessionHelper.addCouponCodeToRequestParamsIfNeeded(params);
        if(dateOfOrderString != null && !dateOfOrderString.isEmpty() &&
                timeOfOrder != null && !timeOfOrder.isEmpty()){
            params.put("delivery_date", dateOfOrderString + " " + timeOfOrder);
        }
        return params;
    }

    private String createOrderNote(){

        CreateOrderActivity createOrderActivity = (CreateOrderActivity) BaseActivity.currentActivity;
        StringBuilder stringBuilder = new StringBuilder();
        /*
        if(isCartContainsAnyPizza()){
            stringBuilder.append(slicePizzaForStoreText).append(" : ");
            if(createOrderActivity.getSlicePizza() == Boolean.TRUE){
                stringBuilder.append(yesText);
            }
            else {
                stringBuilder.append(noText);
            }
            stringBuilder.append("\n");
        }
        */

        stringBuilder
                .append(createOrderActivity.getOrderNote());
                //.append("\n");

        /*
        if(dateOfOrderString != null && !dateOfOrderString.isEmpty() &&
                timeOfOrder != null && !timeOfOrder.isEmpty()){

            stringBuilder
                    .append(deliveryDateText)
                    .append(" ")
                    .append(dateOfOrderString)
                    .append("\n")
                    .append(deliveryTimeText)
                    .append(" ")
                    .append(timeOfOrder);

        }
        */

        if(stringBuilder.toString().equals("\n") || stringBuilder.toString().equals("\n<br/>") || stringBuilder.toString().equals("<br/>")){
            return "";
        }
        String comment = stringBuilder.toString();
        if(comment.startsWith("\n")){
            comment = comment.replace("\n", "");
        }
        return comment;
    }

    private boolean isCartContainsAnyPizza(){
        boolean containsAnyPizza = false;
        outerloop:
        for(CartProductModel cartProductModel : createOrderActivity.getCartInfo().getProducts()){
            if(SharedPrefsHelper.readPizzaCategoryIdList().contains(Integer.valueOf(cartProductModel.getProductId()))){
                containsAnyPizza = true;
                break;
            }
            for(String categoryId : cartProductModel.getCategoryList()){
                if(SharedPrefsHelper.readPizzaCategoryIdList().contains(Integer.valueOf(categoryId))){
                    containsAnyPizza = true;
                    break outerloop;
                }
            }
        }
        return containsAnyPizza;
    }

    private void getCartProducts(){
        DialogHelper.showLoadingDialog();
        /*
        Call<ResponseObject<CartInfoModel>> call = ApiService.apiInterface.getCartProducts(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_GET_CART_PRODUCTS + SessionHelper.getCustomerToken().getToken());
                */
        HashMap<String, Object> params = new HashMap<>();
        SessionHelper.addCouponCodeToRequestParamsIfNeeded(params);

        Call<ResponseObject<CartInfoModel>> call = ApiService.apiInterface.getCartProducts(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_GET_CART_PRODUCTS + SessionHelper.getCustomerToken().getToken(),
                params);

        call.enqueue(new Callback<ResponseObject<CartInfoModel>>() {
            @Override
            public void onResponse(Call<ResponseObject<CartInfoModel>> call, Response<ResponseObject<CartInfoModel>> response) {
                DialogHelper.hideLoadingDialog();
                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess()){
                    response.body().getData().checkNull();
                    createOrderActivity.setCartInfoSafeForCampaigns(response.body().getData());
                }
                else
                    ApiErrorUtils.parseError(response);
            }

            @Override
            public void onFailure(Call<ResponseObject<CartInfoModel>> call, Throwable t) {
                DialogHelper.hideLoadingDialog();
                DialogHelper.showFailedDialog();
            }
        });
    }

    private void getCartProductsWithCommission(){
        DialogHelper.showLoadingDialog();
        /*
        Call<ResponseObject<CartInfoModel>> call = ApiService.apiInterface.getCartProductsForCommission(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_GET_CART_PRODUCTS + SessionHelper.getCustomerToken().getToken(),
                createOrderActivity.getSelectedPaymentMethod().getCode(),
                createOrderActivity.getSelectedShippingMethod().getCode());
                */

        HashMap<String, Object> params = new HashMap<>();
        params.put("payment_method", createOrderActivity.getSelectedPaymentMethod().getCode());
        params.put("payment_method_code", createOrderActivity.getSelectedPaymentMethod().getCode());
        params.put("shipping_method",createOrderActivity.getSelectedShippingMethod().getCode());
        params.put("shipping_method_code",createOrderActivity.getSelectedShippingMethod().getCode());
        SessionHelper.addCouponCodeToRequestParamsIfNeeded(params);

        Call<ResponseObject<CartInfoModel>> call = ApiService.apiInterface.getCartProducts(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_GET_CART_PRODUCTS + SessionHelper.getCustomerToken().getToken(),
                params);

        call.enqueue(new Callback<ResponseObject<CartInfoModel>>() {
            @Override
            public void onResponse(Call<ResponseObject<CartInfoModel>> call, Response<ResponseObject<CartInfoModel>> response) {
                DialogHelper.hideLoadingDialog();
                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess()){
                    CartInfoModel cartInfoModel = response.body().getData();
                    cartInfoModel.checkNull();
                    createOrderActivity.setCartInfoSafeForCampaigns(cartInfoModel);
                    //setOrderTotalText(response.body().getData());
                    cartTotalList.clear();
                    cartTotalList.addAll(cartInfoModel.getTotalsList());
                    fixCartTotalList();
                    orderPriceRecyclerAdapter.notifyDataSetChanged();
                }
                else {
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseObject<CartInfoModel>> call, Throwable t) {
                DialogHelper.hideLoadingDialog();
                DialogHelper.showFailedDialog();
            }
        });
    }

    private void startBraintreePayment(){

        // CVV kodu default olarak gozukmuyor.
        // Gozukmesi için braintree'ye login ol
        // Go to Settings --> Processing --> CVV --> Click on Edit --> Check option 'CVV not provided(l)', Enable option 'for any transaction'

        if(braintreePaymentTokenModel == null || braintreePaymentTokenModel.getToken().isEmpty() || dropInClient == null){
            DialogHelper.showAlertDialog(BaseActivity.currentActivity, getString(R.string.something_went_wrong));
            return;
        }
        String amountStringForBraintree = PriceHelper.removeCurrencyFromPrice(createOrderActivity.getCartInfo().getCartTotalModel().getText());
        //PayPalRequest paypalRequest = new PayPalRequest(amountStringForBraintree).currencyCode("CHF");//.intent(PayPalRequest.INTENT_AUTHORIZE);

        /**
         * Paypal has two flow type: Vault and Checkout.
         * Vault: Collects user card data.
         * Checkout: One time payment.
         *
         *  This method (paypalRequest() method) is optional.
         *  @param request The PayPal Request {@link PayPalRequest} for the transaction.
         *  If no amount is set, PayPal will default to the billing agreement (Vault) flow.
         *  If amount is set, PayPal will follow the one time payment (Checkout) flow.
         *
         * Drop-in verince Vault çalışıyormuş galiba, ondan dolay pappal request verdik
         * https://bitbucket.org/pusulawiss/pizza_leu/issues/73/feat-paypal-i-leyi-de-i-imi
         *
         * https://developers.braintreepayments.com/guides/paypal/checkout-with-paypal/android/v3
         * https://developers.braintreepayments.com/guides/paypal/vault/javascript/v2
         */

        UserModel user = SessionHelper.getUser();

        ThreeDSecurePostalAddress threeDSecureBillingAddress = new ThreeDSecurePostalAddress();
        threeDSecureBillingAddress.setGivenName(user.getFirstname());
        threeDSecureBillingAddress.setSurname(user.getLastname());
        threeDSecureBillingAddress.setPhoneNumber(user.getTelephone());
        if (SessionHelper.getUserMainAddress() != null && SessionHelper.getUserMainAddress().getAddress() != null){
            threeDSecureBillingAddress.setExtendedAddress(SessionHelper.getUserMainAddress().getAddress());
        }

        ThreeDSecurePostalAddress threeDSecureShippingAddress = new ThreeDSecurePostalAddress();
        threeDSecureShippingAddress.setGivenName(user.getFirstname());
        threeDSecureShippingAddress.setSurname(user.getLastname());
        threeDSecureShippingAddress.setPhoneNumber(user.getTelephone());
        threeDSecureShippingAddress.setExtendedAddress(createOrderActivity.getSelectedShippingAddress().getAddress());

        ThreeDSecureAdditionalInformation ThreeDSecureAdditionalInformation = new ThreeDSecureAdditionalInformation();
        ThreeDSecureAdditionalInformation.setShippingAddress(threeDSecureShippingAddress);

        ThreeDSecureRequest threeDSecureRequest = new ThreeDSecureRequest();
        threeDSecureRequest.setAmount(amountStringForBraintree);
        threeDSecureRequest.setEmail(user.getEmail());
        threeDSecureRequest.setBillingAddress(threeDSecureBillingAddress);
        threeDSecureRequest.setVersionRequested(VERSION_2);
        threeDSecureRequest.setAdditionalInformation(ThreeDSecureAdditionalInformation);

        //DropInRequest paymentRequest = new DropInRequest(true);
        DropInRequest dropInRequest = new DropInRequest();
        dropInRequest.setThreeDSecureRequest(threeDSecureRequest);
        dropInRequest.setGooglePayDisabled(true);
        dropInRequest.setPayPalDisabled(true);
        dropInRequest.setVenmoDisabled(true);
        //paymentRequest.setPayPalRequest(paypalRequest);

        dropInClient.setListener(this);
        dropInClient.launchDropIn(dropInRequest);



        /*
        switch (createOrderActivity.getSelectedPaymentMethod().getPaymentMethodType()){
            case CREDIT_DEBIT_CARD:
                paymentRequest.disableAndroidPay();
                paymentRequest.disablePayPal();
                break;
            case PAYPAL:
                paymentRequest.disableAndroidPay();
                break;
            case ANDROID_PAY:
                paymentRequest.disablePayPal();
                if(getAndroidPayCart() == null){
                    DialogHelper.showAlertDialog(BaseActivity.currentActivity, androidPayNotFoundText);
                    return;
                }
                else {
                    paymentRequest.androidPayCart(getAndroidPayCart());
                }
                break;
        }
        */
    }

    private void createBraintreePayment(final DropInResult dropInResult){
        DialogHelper.showLoadingDialog();
        Call<ResponseObject> call = ApiService.apiInterface.createBraintreePayment(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_CREATE_BRAINTREE_PAYMENT + SessionHelper.getCustomerToken().getToken(),
                getBraintreePaymentParams(dropInResult));
        call.enqueue(new Callback<ResponseObject>() {
            @Override
            public void onResponse(Call<ResponseObject> call, final Response<ResponseObject> response) {
                DialogHelper.hideLoadingDialog();
                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess() && dropInResult.getPaymentMethodNonce() != null){
                    createOrder(getCreateOrderParams(dropInResult.getPaymentMethodNonce().getString()));
                }
                else {
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseObject> call, Throwable t) {
                DialogHelper.hideLoadingDialog();
                DialogHelper.showFailedDialog();
            }
        });
    }

    private HashMap<String, Object> getBraintreePaymentParams(DropInResult dropInResult){
        HashMap<String, Object> params = new HashMap<>();
        params.put("payment_method_nonce", dropInResult.getPaymentMethodNonce().getString());
        params.put("amount", PriceHelper.removeCurrencyFromPrice(createOrderActivity.getCartInfo().getCartTotalModel().getText()));
        return params;
    }

    /*
    private void setOrderTotalText(CartInfoModel cartInfoModel){

        CartTotalModel subtotalModel = new CartTotalModel("","");
        CartTotalModel commissionModel = new CartTotalModel("","");
        CartTotalModel totalModel = new CartTotalModel("","");

        String totalText = "";

        for (CartTotalModel cartTotalModel : cartInfoModel.getTotalsList()){
            switch (cartTotalModel.getTitle().toLowerCase()){
                case ApiConstants.CART_SUBTOTAL :
                    subtotalModel = cartTotalModel;
                    break;
                case ApiConstants.CART_COMMISSION :
                    commissionModel = cartTotalModel;
                    break;
                case ApiConstants.CART_TOTAL :
                    totalModel = cartTotalModel;
                    break;
            }
        }

        if(commissionModel.getText().isEmpty()){
            totalText = PriceHelper.roundFractions(cartInfoModel.getCartTotalModel().getText());
        }
        else {
            totalText =
                    new StringBuilder()
                            .append(subtotalModel.getTitle())
                            .append("\n")
                            .append(subtotalModel.getText())
                            .append("\n\n")
                            .append(commissionModel.getTitle())
                            .append("\n")
                            .append(commissionModel.getText())
                            .append("\n\n")
                            .append(totalModel.getTitle())
                            .append("\n")
                            .append(totalModel.getText())
                            //.append(PriceHelper.roundFractions(totalModel.getText()))
                            .toString();
        }
        //orderTotalPizzalinkInfoLayout.setText(totalText);

    }
    */

    private Calendar[] generateEnabledDays(){

        ArrayList<Calendar> enabledDayList = new ArrayList<>();

        for(int i = 0; i < 8; i++){

            Calendar calendar = Calendar.getInstance();
            ArrayList<String> dayParts = new ArrayList<>();

            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

            switch ((dayOfWeek + i) % 7){
                case 0:
                    dayParts = storeShiftModel.getSundayShift();
                    break;
                case 1:
                    dayParts = storeShiftModel.getMondayShift();
                    break;
                case 2:
                    dayParts = storeShiftModel.getTuesdayShift();
                    break;
                case 3:
                    dayParts = storeShiftModel.getWednesdayShift();
                    break;
                case 4:
                    dayParts = storeShiftModel.getThursdayShift();
                    break;
                case 5:
                    dayParts = storeShiftModel.getFridayShift();
                    break;
                case 6:
                    dayParts = storeShiftModel.getSaturdayShift();
                    break;
            }

            if(!dayParts.isEmpty()){
                calendar.add(Calendar.DAY_OF_YEAR, i);
                enabledDayList.add(calendar);
            }
        }

        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        ArrayList<String> todayParts = new ArrayList<>();
        switch (dayOfWeek){
            case 1:
                todayParts = storeShiftModel.getSundayShift();
                break;
            case 2:
                todayParts = storeShiftModel.getMondayShift();
                break;
            case 3:
                todayParts = storeShiftModel.getTuesdayShift();
                break;
            case 4:
                todayParts = storeShiftModel.getWednesdayShift();
                break;
            case 5:
                todayParts = storeShiftModel.getThursdayShift();
                break;
            case 6:
                todayParts = storeShiftModel.getFridayShift();
                break;
            case 7:
                todayParts = storeShiftModel.getSaturdayShift();
                break;
        }
        if(isDayAvailable(todayParts)){
            enabledDayList.add(Calendar.getInstance());
        }
        return enabledDayList.toArray(new Calendar[enabledDayList.size()]);

    }

    private Timepoint[] generateEnabledTimePoints(ArrayList<String> workingParts){

        ArrayList<Timepoint> enabledTimePointList = new ArrayList<>();

        try {
            for(String part : workingParts){
                part = part.replace(" ", "");
                String[] array = part.split("-");
                String partStart = array[0];
                String partEnd = array[1];
                //partEnd = fixEndTime(partEnd); // to prevent creating orders which 15 minutes before restaurant close time. now it will controlled on backend

                int partStartHour = Integer.valueOf(partStart.substring(0,2));
                int partStartMinute = Integer.valueOf(partStart.substring(3, 5));
                int partEndHour = Integer.valueOf(partEnd.substring(0,2));
                int partEndMinute = Integer.valueOf(partEnd.substring(3, 5));

                int hour = partStartHour;
                int minute = partStartMinute;

                while (hour <= partEndHour){
                    enabledTimePointList.add(new Timepoint(hour, minute));
                    minute++;
                    if(minute == 60){
                        minute = 0;
                        hour += 1;
                    }

                    if(hour == partEndHour && minute > partEndMinute){
                        break;
                    }
                }
            }
        }catch (Exception e){
            return enabledTimePointList.toArray(new Timepoint[enabledTimePointList.size()]);

        }
        return enabledTimePointList.toArray(new Timepoint[enabledTimePointList.size()]);
    }

    private boolean isDayAvailable(ArrayList<String> parts){
        if(parts.size() < 2){
            return false;
        }
        for(String part : parts){
            if(isPartAvailable(part)){
                return true;
            }
        }
        return false;
    }

    private boolean isPartAvailable(String part){
        try {
            Date nowDate = Calendar.getInstance().getTime();
            DateFormat dateFormat = new SimpleDateFormat("HH:mm");
            String nowTimeString = dateFormat.format(nowDate);
            part = part.replace(" ", "");
            String[] array = part.split("-");
            String partStart = array[0];
            String partEnd = array[1];

            int partStartHour = Integer.valueOf(partStart.substring(0,2));
            int partStartMinute = Integer.valueOf(partStart.substring(3, 5));
            int partEndHour = Integer.valueOf(partEnd.substring(0,2));
            int partEndMinute = Integer.valueOf(partEnd.substring(3, 5));

            Calendar partStartCalendar = Calendar.getInstance();
            partStartCalendar.set(Calendar.HOUR_OF_DAY, partStartHour);
            partStartCalendar.set(Calendar.MINUTE, partStartMinute);
            partStartCalendar.set(Calendar.SECOND, 0);
            Date partStartDate = partStartCalendar.getTime();

            Calendar partEndCalendar = Calendar.getInstance();
            partEndCalendar.set(Calendar.HOUR_OF_DAY, partEndHour);
            partEndCalendar.set(Calendar.MINUTE, partEndMinute);
            partEndCalendar.set(Calendar.SECOND, 0);
            Date partEndDate = partEndCalendar.getTime();

            if(partStartDate.after(nowDate) && partEndDate.after(nowDate)){
                return true;
            }
            else {
                return false;
            }

            /*
            String[] array2 = nowTimeString.split(":");
            String nowHourString = array2[0];
            String nowMinuteString = array2[1];

            int nowHour = Integer.valueOf(nowHourString);
            int nowMinute = Integer.valueOf(nowMinuteString);

            return nowHour >= partStartHour && nowHour <= partEndHour &&
                    nowMinute >= partStartMinute && nowMinute <= partEndMinute;
            */
        }catch (Exception e){
            return false;
        }
    }

    private void fixCartTotalList(){
        ArrayList<CartTotalModel> tempTotalList = new ArrayList<>();
        for(CartTotalModel cartTotalModel : cartTotalList){
            String price = PriceHelper.removeCurrencyFromPrice(cartTotalModel.getText());
            if(!price.equals("0") && !price.equals("0.0") && !price.equals("0.00") &&
                    !price.equals("-0") && !price.equals("-0.0") && !price.equals("-0.00")){
                tempTotalList.add(cartTotalModel);
            }
        }
        cartTotalList.clear();
        cartTotalList.addAll(tempTotalList);
        tempTotalList.clear();
    }

    private void showPaymentWebView(int orderId){
        createOrderActivity.setPaymentWebViewVisibility(true);
        final WebView paymentWebView = createOrderActivity.getPaymentWebView();
        paymentWebView.loadUrl("about:blank");
        paymentWebView.clearHistory();
        paymentWebView.setVisibility(View.VISIBLE);
        paymentWebView.getSettings().setJavaScriptEnabled(true);
        paymentWebView.setWebViewClient(new WebViewClient(){

            @RequiresApi(Build.VERSION_CODES.N)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                /*
                // Canceled because response json from PostFinance fr apple Webview is not valid
                // payment success or fail. response json will handle at "handlePaymentResponse" method of "PaymentJavaScriptInterface" class below
                if(request.getUrl().toString().contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_SUCCESS) ||
                        request.getUrl().toString().contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_FAIL)){
                    createOrderActivity.setPaymentWebViewVisibility(false);
                }
                */

                // payment success
                if(request.getUrl().toString().contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_SUCCESS) ||
                        request.getUrl().toString().equals(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTP) ||
                        request.getUrl().toString().equals(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTPS)){
                    createOrderActivity.setPaymentWebViewVisibility(false);
                    createOrderActivity.onNextClicked(FRAGMENT_NAME);
                    return false;
                }
                // payment fail
                else if(request.getUrl().toString().contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_FAIL) ||
                        request.getUrl().toString().contains(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTP) ||
                        request.getUrl().toString().contains(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTPS)){
                    createOrderActivity.setPaymentWebViewVisibility(false);
                    DialogHelper.showAlertDialog(BaseActivity.currentActivity, getString(R.string.error_message));
                    return false;
                }
                else {
                    return false;
                }
            }

            @SuppressWarnings("deprecation")
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                /*
                // Canceled because response json from PostFinance fr apple Webview is not valid
                // payment success or fail. response json will handle at "handlePaymentResponse" method of "PaymentJavaScriptInterface" class below
                if(url.contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_SUCCESS) ||
                        url.contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_FAIL)){
                    createOrderActivity.setPaymentWebViewVisibility(false);
                }
                */

                // payment success
                if(url.contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_SUCCESS) ||
                        url.equals(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTP) ||
                        url.equals(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTPS)){
                    createOrderActivity.setPaymentWebViewVisibility(false);
                    createOrderActivity.onNextClicked(FRAGMENT_NAME);
                    return true;
                }
                // payment fail
                else if(url.contains(ApiConstants.PAYMENT_WEBVIEW_REDIRECT_URL_POSTFINANCE_TWINT_FAIL) ||
                        url.contains(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTP) ||
                        url.contains(ApiConstants.PAYMENT_WEBVIEW_MAIN_PAGE_HTTPS)){
                    createOrderActivity.setPaymentWebViewVisibility(false);
                    DialogHelper.showAlertDialog(BaseActivity.currentActivity, getString(R.string.error_message));
                    return true;
                }
                else {
                    return false;
                }
            }

            /*
            // Canceled because response json from PostFinance fr apple Webview is not valid
            @Override
            public void onPageFinished(WebView view, String url) {
                view.loadUrl("javascript:PaymentResponseHandler.handlePaymentResponse" +
                        "(document.getElementsByTagName('pre')[0].innerHTML);");
            }
             */

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                DialogHelper.showAlertDialog(BaseActivity.currentActivity, getString(R.string.error_message));
            }
        });

        paymentWebView.loadUrl(ApiConstants.PAYMENT_WEBVIEW_URL_POSTFINANCE_TWINT + orderId);
        // Canceled because response json from PostFinance fr apple Webview is not valid
        //paymentWebView.addJavascriptInterface(new PaymentJavaScriptInterface(getActivity()), "PaymentResponseHandler");
    }

    private String fixEndTime(String endTime){
        try {
            String[] time = endTime.split(":");
            int hour = Integer.parseInt(time[0]);
            int minute = Integer.parseInt(time[1]);
            if(minute < 15){
                minute += 60;
                if(hour == 0){
                    hour += 24;
                }
                hour -= 1;
            }
            minute -= 15;
            String hourString = String.valueOf(hour);
            if(hourString.length() == 1){
                hourString = "0" + hourString;
            }
            String minuteString = String.valueOf(minute);
            if(minuteString.length() == 1){
                minuteString = "0" + minuteString;
            }
            return hourString + ":" + minuteString;
        }catch (Exception e){
            e.printStackTrace();
            return endTime;
        }
    }

    private String getWorkingHoursString(){

        HashMap<String, ArrayList<String>> shiftMap = new HashMap<>();
        concatTheSameWorkingDays(shiftMap, "Mo", storeShiftModel.getMondayShift());
        concatTheSameWorkingDays(shiftMap, "Di", storeShiftModel.getTuesdayShift());
        concatTheSameWorkingDays(shiftMap, "Mi", storeShiftModel.getWednesdayShift());
        concatTheSameWorkingDays(shiftMap, "Do", storeShiftModel.getThursdayShift());
        concatTheSameWorkingDays(shiftMap, "Fr", storeShiftModel.getFridayShift());
        concatTheSameWorkingDays(shiftMap, "Sa", storeShiftModel.getSaturdayShift());
        concatTheSameWorkingDays(shiftMap, "So", storeShiftModel.getSundayShift());

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("\n");
        for(String key: shiftMap.keySet()){
            ArrayList<String> hoursArray = shiftMap.get(key);
            if(hoursArray == null){
                hoursArray = new ArrayList<>();
            }
            StringBuilder hoursBuilder = new StringBuilder();
            for(String part: hoursArray){
                hoursBuilder.append(part).append(", ");
            }
            String hoursString = hoursBuilder.toString();
            int index = hoursString.lastIndexOf(", ");
            if(index != -1){
                hoursString = hoursString.substring(0, index);
            }
            stringBuilder
                    .append(key)
                    .append(": ")
                    .append(hoursString)
                    .append("\n");
        }
        return stringBuilder.toString();
    }

    private void concatTheSameWorkingDays(HashMap<String, ArrayList<String>> map,
                                          String day,
                                          ArrayList<String> workingHours){
        if(workingHours.isEmpty()){
            return;
        }
        if(map.containsValue(workingHours)){
            String currentKey = getKeyOfAValueOnMap(map, workingHours);
            String updatedKey = currentKey + "," + day;
            map.remove(currentKey);
            map.put(updatedKey, workingHours);
        }
        else {
            map.put(day, workingHours);
        }
    }

    private <K, V> K getKeyOfAValueOnMap(Map<K, V> map, V value) {
        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
                return entry.getKey();
            }
        }
        return null;
    }



    /*
    // Canceled because response json from PostFinance fr apple Webview is not valid
    class PaymentJavaScriptInterface {

        private Context ctx;

        PaymentJavaScriptInterface(Context ctx) {
            this.ctx = ctx;
        }

        @JavascriptInterface
        public void handlePaymentResponse(String jsonString) {
            try{
                if(jsonString.contains("success") && jsonString.contains("message") && jsonString.contains("error_code") && jsonString.contains("data")){
                    Gson gson = new Gson();
                    PostfinancePaymentResponseModel postfinancePaymentResponseModel = gson.fromJson(jsonString, PostfinancePaymentResponseModel.class);

                    if(postfinancePaymentResponseModel.isSuccess()){
                        createOrderActivity.onNextClicked(FRAGMENT_NAME);
                    }
                    else {
                        DialogHelper.showAlertDialog(BaseActivity.currentActivity, postfinancePaymentResponseModel.getMessage());
                    }
                }
            }
            catch (Exception e){
                DialogHelper.showAlertDialog(BaseActivity.currentActivity, getString(R.string.error_message));
            }
        }
    }
    */
}
