package bf.io.openshop.ux.dialogs;
import android.app.Dialog;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import bf.io.openshop.CONST;
import bf.io.openshop.MyApplication;
import bf.io.openshop.R;
import bf.io.openshop.SettingsMy;
import bf.io.openshop.api.EndPoints;
import bf.io.openshop.api.GsonRequest;
import bf.io.openshop.api.JsonRequest;
import bf.io.openshop.entities.User;
import bf.io.openshop.entities.cart.CartProductItem;
import bf.io.openshop.entities.product.Product;
import bf.io.openshop.entities.product.ProductColor;
import bf.io.openshop.entities.product.ProductQuantity;
import bf.io.openshop.entities.product.ProductVariant;
import bf.io.openshop.interfaces.RequestListener;
import bf.io.openshop.utils.JsonUtils;
import bf.io.openshop.utils.MsgUtils;
import bf.io.openshop.ux.adapters.CartColorTextSpinnerAdapter;
import bf.io.openshop.ux.adapters.CartSizeSpinnerAdapter;
import bf.io.openshop.ux.adapters.QuantitySpinnerAdapter;
import timber.log.Timber;
/**
* Dialog handles update items in the shopping cart.
*/
public class UpdateCartItemDialogFragment extends DialogFragment {
/**
* Defined max product quantity.
*/
private static final int QUANTITY_MAX = 15;
private CartProductItem cartProductItem;
private RequestListener requestListener;
private View dialogProgress;
private View dialogContent;
private Spinner itemColorsSpinner;
private Spinner itemSizesSpinner;
private Spinner quantitySpinner;
/**
* Creates dialog which handles update items in the shopping cart
*
* @param cartProductItem item in the cart, which should be updated.
* @param requestListener listener receiving update request results.
* @return new instance of dialog.
*/
public static UpdateCartItemDialogFragment newInstance(CartProductItem cartProductItem, RequestListener requestListener) {
if (cartProductItem == null) {
Timber.e(new RuntimeException(), "Created UpdateCartItemDialogFragment with null parameters.");
return null;
}
UpdateCartItemDialogFragment updateCartItemDialogFragment = new UpdateCartItemDialogFragment();
updateCartItemDialogFragment.cartProductItem = cartProductItem;
updateCartItemDialogFragment.requestListener = requestListener;
return updateCartItemDialogFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.getWindow().setWindowAnimations(R.style.dialogFragmentAnimation);
return dialog;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Timber.d("%s - OnCreateView", this.getClass().getSimpleName());
View view = inflater.inflate(R.layout.dialog_update_cart_item, container, false);
dialogProgress = view.findViewById(R.id.dialog_update_cart_item_progress);
dialogContent = view.findViewById(R.id.dialog_update_cart_item_content);
itemColorsSpinner = (Spinner) view.findViewById(R.id.dialog_update_cart_item_color_spin);
itemSizesSpinner = (Spinner) view.findViewById(R.id.dialog_update_cart_item_size_spin);
TextView itemName = (TextView) view.findViewById(R.id.dialog_update_cart_item_title);
itemName.setText(cartProductItem.getVariant().getName());
View btnSave = view.findViewById(R.id.dialog_update_cart_item_save_btn);
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (quantitySpinner != null && itemSizesSpinner != null) {
ProductVariant productVariant = (ProductVariant) itemSizesSpinner.getSelectedItem();
ProductQuantity productQuantity = (ProductQuantity) quantitySpinner.getSelectedItem();
Timber.d("Selected: %s. Quantity: %s", productVariant, productQuantity);
if (productVariant != null && productVariant.getSize() != null && productQuantity != null) {
updateProductInCart(cartProductItem.getId(), productVariant.getId(), productQuantity.getQuantity());
} else {
Timber.e(new RuntimeException(), "Cannot obtain info about edited cart item.");
MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_MESSAGE, getString(R.string.Internal_error_reload_cart_please), MsgUtils.ToastLength.SHORT);
dismiss();
}
} else {
Timber.e(new NullPointerException(), "Null spinners in editing item in cart");
MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_MESSAGE, getString(R.string.Internal_error_reload_cart_please), MsgUtils.ToastLength.SHORT);
dismiss();
}
}
});
View btnCancel = view.findViewById(R.id.dialog_update_cart_item_cancel_btn);
btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
// Set item quantity
QuantitySpinnerAdapter adapterQuantity = new QuantitySpinnerAdapter(getActivity(), getQuantities());
quantitySpinner = (Spinner) view.findViewById(R.id.dialog_update_cart_item_quantity_spin);
quantitySpinner.setAdapter(adapterQuantity);
getProductDetail(cartProductItem);
return view;
}
// Prepare quantity spinner layout
private List<ProductQuantity> getQuantities() {
List<ProductQuantity> quantities = new ArrayList<>();
for (int i = 1; i <= QUANTITY_MAX; i++) {
ProductQuantity q = new ProductQuantity(i, i + "x");
quantities.add(q);
}
return quantities;
}
private void getProductDetail(CartProductItem cartProductItem) {
String url = String.format(EndPoints.PRODUCTS_SINGLE, SettingsMy.getActualNonNullShop(getActivity()).getId(), cartProductItem.getVariant().getProductId());
setProgressActive(true);
GsonRequest<Product> getProductRequest = new GsonRequest<>(Request.Method.GET, url, null, Product.class,
new Response.Listener<Product>() {
@Override
public void onResponse(@NonNull Product response) {
setProgressActive(false);
setSpinners(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
setProgressActive(false);
MsgUtils.logAndShowErrorMessage(getActivity(), error);
}
});
getProductRequest.setRetryPolicy(MyApplication.getDefaultRetryPolice());
getProductRequest.setShouldCache(false);
MyApplication.getInstance().addToRequestQueue(getProductRequest, CONST.UPDATE_CART_ITEM_REQUESTS_TAG);
}
private void setSpinners(final Product product) {
if (product != null && product.getVariants() != null && product.getVariants().size() > 0) {
List<ProductColor> productColors = new ArrayList<>();
for (ProductVariant pv : product.getVariants()) {
ProductColor pac = pv.getColor();
if (!productColors.contains(pac)) {
productColors.add(pac);
}
}
if (productColors.size() > 1) {
itemColorsSpinner.setVisibility(View.VISIBLE);
CartColorTextSpinnerAdapter adapterColor = new CartColorTextSpinnerAdapter(getActivity(), productColors);
itemColorsSpinner.setAdapter(adapterColor);
ProductColor actualItemColor = cartProductItem.getVariant().getColor();
if (actualItemColor != null) {
int index = productColors.indexOf(actualItemColor);
Timber.d("SetSpinners selectedColor: %s", actualItemColor.toString());
if (index == -1) {
itemColorsSpinner.setSelection(0);
Timber.e(new NullPointerException(), "Actual item color didn't match server received item colors");
} else {
itemColorsSpinner.setSelection(index);
}
}
itemColorsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
ProductColor productColor = (ProductColor) parent.getItemAtPosition(position);
if (productColor != null) {
Timber.d("ColorPicker selected color: %s", productColor.toString());
updateSizeSpinner(product, productColor);
} else {
Timber.e("Retrieved null color from spinner.");
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
Timber.d("Nothing selected in product colors spinner.");
}
});
} else {
itemColorsSpinner.setVisibility(View.GONE);
updateSizeSpinner(product, product.getVariants().get(0).getColor());
}
int selectedPosition = cartProductItem.getQuantity() - 1;
if (selectedPosition < 0) selectedPosition = 0;
if (selectedPosition > (quantitySpinner.getCount() - 1))
Timber.e(new RuntimeException(), "More item quantity that can be. Quantity: %d, max: %d", (selectedPosition + 1), quantitySpinner.getCount());
else
quantitySpinner.setSelection(selectedPosition);
} else {
Timber.e("Setting spinners for null product variants.");
MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_INTERNAL_ERROR, null, MsgUtils.ToastLength.SHORT);
}
}
/**
* Update size values in size adapter.
*
* @param product updated product.
* @param productColor actually selected color.
*/
private void updateSizeSpinner(Product product, ProductColor productColor) {
if (product != null) {
ArrayList<ProductVariant> variantSizeArrayList = new ArrayList<>();
for (ProductVariant pv : product.getVariants()) {
if (pv.getColor().equals(productColor)) {
variantSizeArrayList.add(pv);
}
}
// Show sizes
CartSizeSpinnerAdapter adapterSize = new CartSizeSpinnerAdapter(getActivity(), variantSizeArrayList);
itemSizesSpinner.setAdapter(adapterSize);
// Select actual size
if (!variantSizeArrayList.isEmpty()) {
int sizeSelection = 0;
for (int i = 0; i < variantSizeArrayList.size(); i++) {
// Timber.d("Compare list: " + variantSizeArrayList.get(i).getId() + " == " + cartProductItem.getVariant().getId() + " as actual");
if (variantSizeArrayList.get(i).getId() == cartProductItem.getVariant().getId()) {
sizeSelection = i;
}
}
itemSizesSpinner.setSelection(sizeSelection);
}
} else {
Timber.e("UpdateImagesAndSizeSpinner with null product.");
}
}
private void updateProductInCart(long productCartId, long newVariantId, int newQuantity) {
User user = SettingsMy.getActiveUser();
if (user != null) {
JSONObject jo = new JSONObject();
try {
jo.put(JsonUtils.TAG_QUANTITY, newQuantity);
jo.put(JsonUtils.TAG_PRODUCT_VARIANT_ID, newVariantId);
} catch (JSONException e) {
Timber.e(e, "Create update object exception");
MsgUtils.showToast(getActivity(), MsgUtils.TOAST_TYPE_INTERNAL_ERROR, null, MsgUtils.ToastLength.SHORT);
return;
}
Timber.d("update product: %s", jo.toString());
String url = String.format(EndPoints.CART_ITEM, SettingsMy.getActualNonNullShop(getActivity()).getId(), productCartId);
setProgressActive(true);
JsonRequest req = new JsonRequest(Request.Method.PUT, url, jo, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Timber.d("Update item in cart: %s", response.toString());
if (requestListener != null) requestListener.requestSuccess(0);
setProgressActive(false);
dismiss();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
setProgressActive(false);
if (requestListener != null) requestListener.requestFailed(error);
dismiss();
}
}, getFragmentManager(), user.getAccessToken());
req.setRetryPolicy(MyApplication.getDefaultRetryPolice());
req.setShouldCache(false);
MyApplication.getInstance().addToRequestQueue(req, CONST.UPDATE_CART_ITEM_REQUESTS_TAG);
} else {
LoginExpiredDialogFragment loginExpiredDialogFragment = new LoginExpiredDialogFragment();
loginExpiredDialogFragment.show(getFragmentManager(), "loginExpiredDialogFragment");
}
}
private void setProgressActive(boolean active) {
if (active) {
dialogProgress.setVisibility(View.VISIBLE);
dialogContent.setVisibility(View.INVISIBLE);
} else {
dialogProgress.setVisibility(View.GONE);
dialogContent.setVisibility(View.VISIBLE);
}
}
@Override
public void onStop() {
MyApplication.getInstance().getRequestQueue().cancelAll(CONST.UPDATE_CART_ITEM_REQUESTS_TAG);
super.onStop();
}
}