package com.seatel.mobilehall.util.manager;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.google.gson.Gson;
import com.seatel.mobilehall.data.network.SeatelJSONObjectRequest;
import com.seatel.mobilehall.data.network.SeatelSuperRequest;
import com.seatel.mobilehall.data.prefs.SeatelSharePreferences;
import com.seatel.mobilehall.ui.home.activity.MyCartActivity;
import com.seatel.mobilehall.ui.home.model.CartModel;
import com.seatel.mobilehall.ui.home.model.SeatelShopLocationModel;
import com.seatel.mobilehall.util.Constant;
import com.seatel.mobilehall.util.SeatelAlertDialog;
import com.seatel.mobilehall.util.request.UpdateCartRequest;

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

import java.util.ArrayList;

public class OrderingManager {

    private static OrderingManager orderingManager = null;
    private final ArrayList<CartModel> cartsModels = new ArrayList<>();
    private OrderCallback mOrderCallback;
    private int selectedSection = 1;
    private DeliverStatus deliverStatus = null;
    private SeatelShopLocationModel mSeatelShopLocationModel = null;
    private String paymentMethod = "";
    private String simIconUrl = "";
    private String simPriceIconUrl = "";
    private String deviceIconUrl = "";
    private String topUpIconUrl = "";
    private String addressSave = "";
    private String firstNameSave = "";
    private String lastNameSave = "";
    private String emailSave = "";
    private String phoneNumberSave = "";
    private String provinceSave = "";
    private String scratchCardIconUrl = "";
    private Boolean isUpdatedDeliveryAddress = false;
    private Boolean isUpdatedPickupAddress = false;
    private Boolean isUpdateProfile = false;
    private Boolean isSelectedDelivery = false;
    public String orderId;
    private Boolean isCheckShimmentInsurance = false;
    private Boolean isClaimFreeSim = false;
    private Boolean isBuyTopUpCard = false;
    private Boolean isSkipTopUp = false;
    private Boolean isWinPromotionFreeSim = false;
    private String promotionItemId = "";
    private Double shipmentInsuranceRate = 0.005;
    private Double simPriceDefault = 0.5;

    public String getFirstNameSave() {
        return firstNameSave;
    }

    public String getLastNameSave() {
        return lastNameSave;
    }

    public String getEmailSave() {
        return emailSave;
    }

    public String getPhoneNumberSave() {
        return phoneNumberSave;
    }

    public void setFirstNameSave(String firstNameSave) {
        this.firstNameSave = firstNameSave;
    }

    public void setLastNameSave(String lastNameSave) {
        this.lastNameSave = lastNameSave;
    }

    public void setEmailSave(String emailSave) {
        this.emailSave = emailSave;
    }

    public void setPhoneNumberSave(String phoneNumberSave) {
        this.phoneNumberSave = phoneNumberSave;
    }

    public Boolean getUpdatedPickupAddress() {
        return isUpdatedPickupAddress;
    }

    public void setUpdatedPickupAddress(Boolean updatedPickupAddress) {
        isUpdatedPickupAddress = updatedPickupAddress;
    }

    public void setPromotionItem(String itemId) {
        promotionItemId = itemId;
    }

    public String getPromotionItemId() {
        return promotionItemId;
    }

    public Boolean getWinPromotionFreeSim() {
        return isWinPromotionFreeSim;
    }

    public void setWinPromotionFreeSim(Boolean winPromotionFreeSim) {
        isWinPromotionFreeSim = winPromotionFreeSim;
    }

    public Boolean getSkipTopUp() {
        return isSkipTopUp;
    }

    public void setSkipTopUp(Boolean skipTopUp) {
        isSkipTopUp = skipTopUp;
    }

    public void setClaimFreeSim(boolean claimFreeSim) {
        this.isClaimFreeSim = claimFreeSim;
    }

    public boolean getClaimFreeSim() {
        return isClaimFreeSim;
    }

    public Boolean getBuyTopUpCard() {
        return isBuyTopUpCard;
    }

    public void setBuyTopUpCard(Boolean buyTopUpCard) {
        isBuyTopUpCard = buyTopUpCard;
    }

    public void clear() {
        orderingManager = null;
    }

    public void setIsCheckShimmentInsurance(boolean check) {
        this.isCheckShimmentInsurance = check;
    }

    public Double getSimPriceDefault() {
        return simPriceDefault;
    }

    public void setSimPriceDefault(Double simPriceDefault) {
        this.simPriceDefault = simPriceDefault;
    }

    public void setIsSelectedDelivery(boolean check) {
        this.isSelectedDelivery = check;
    }

    public boolean getIsSelectedDelivery() {
        return isSelectedDelivery;
    }

    public boolean getIsCheckShimmentInsurance() {
        return isCheckShimmentInsurance;
    }

    public void setShipmentInsuranceRate(Double shipmentInsuranceRate) {
        this.shipmentInsuranceRate = shipmentInsuranceRate;
    }

    public Double getShipmentInsuranceRate() {
        return shipmentInsuranceRate;
    }

    public String getSelectedIds() {
        StringBuilder ids = new StringBuilder();
        for (int i = 0; i < getSelectedCartsModels().size(); i++) {
            ids.append(getSelectedCartsModels().get(i).getId());
            if (i < getSelectedCartsModels().size() - 1) {
                ids.append(",");
            }
        }
        return ids.toString();
    }

    public void updateCartItem(final Context context, final CartModel cartModel, final int qty) {
        if (context instanceof MyCartActivity)
            ((MyCartActivity) context).getErrorView().setVisibility(View.VISIBLE);
        new UpdateCartRequest(context)
                .cartItemModel(cartModel)
                .phoneNumber(getPhoneNumber(context))
                .qty(qty)
                .setOnErrorListener(new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        if (context instanceof MyCartActivity)
                            ((MyCartActivity) context).getErrorView().setVisibility(View.GONE);
                    }
                }).execute(new Response.Listener() {
            @Override
            public void onResponse(Object response) {
                if (context instanceof MyCartActivity)
                    ((MyCartActivity) context).getErrorView().setVisibility(View.GONE);
                JSONObject dataUpdate = (JSONObject) response;
                if (dataUpdate != null) {
                    if (dataUpdate.has("data")) {
                        JSONObject data = dataUpdate.optJSONObject("data");
                        if (data.has("totalPrice")) {
                            getCart(cartModel.getId()).setTotalPrice(data.optDouble("totalPrice", getCart(cartModel.getId()).getUnitPrice() * qty));
                        }
                        if (data.has("unitPrice")) {
                            getCart(cartModel.getId()).setUnitPrice(data.optDouble("unitPrice", getCart(cartModel.getId()).getUnitPrice()));
                        }
                    }
                } else {
                    getCart(cartModel.getId()).setTotalPrice(getCart(cartModel.getId()).getUnitPrice() * qty);
                }
                getCart(cartModel.getId()).setQuantity(qty);
                //Reload Sim price discount
                if (cartModel.isSelected() && TextUtils.equals(cartModel.getType().toLowerCase(), Constant.DEVICE.toLowerCase())) {
                    updateSimPriceDiscount();
                }
                if (mOrderCallback != null)
                    mOrderCallback.onCartModifyQty();
            }
        });
    }

    private CartModel getCart(String id) {
        for (CartModel c : cartsModels) {
            if (c.getId().equalsIgnoreCase(id))
                return c;
        }
        return new CartModel();
    }

    public enum DeliverStatus {
        PICKUP("pick-up"),
        DELIVERY("delivery");

        private final String name;

        DeliverStatus(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    public static synchronized OrderingManager getInstance() {
        if (orderingManager == null)
            orderingManager = new OrderingManager();
        return orderingManager;
    }

    public void setOrderCallback(OrderCallback mOrderCallback) {
        this.mOrderCallback = mOrderCallback;
    }

    public OrderCallback getOrderCallback() {
        return mOrderCallback;
    }

    public double getTotalSelectedPrice() {
        double total = 0;
        for (CartModel cartModel : cartsModels) {
            if (cartModel.isSelected()) {
                if (cartModel.isSimDiscount())
                    total += cartModel.getTotalPriceAfterDiscountSim();
                else total += cartModel.getTotalPrice();
            }
        }
        return total;
    }

    public double getTotalSelectedPriceWithInsurance() {
        double total = 0;
        for (CartModel cartModel : cartsModels) {
            if (cartModel.isSelected())
                if (cartModel.isSimDiscount())
                    total += cartModel.getTotalPriceAfterDiscountSim();
                else total += cartModel.getTotalPrice();
        }
        if (isCheckShimmentInsurance)
            return total + getTotalSelectedPriceDevice();
        else return total;
    }

    public double getTotalSelectedPriceDevice() {
        double total = 0;
        for (CartModel cartModel : cartsModels)
            if (cartModel.isSelected() && TextUtils.equals(cartModel.getType().toLowerCase(), Constant.DEVICE.toLowerCase()))
                total += cartModel.getTotalPrice();
        return total * shipmentInsuranceRate;
    }

    public void updateSimPriceDiscount() {
        int totalDevice = 0;
        int countSimDiscount = 0;
        for (CartModel cartModel : cartsModels) {
            if (cartModel.isSelected() && TextUtils.equals(cartModel.getType().toLowerCase(), Constant.DEVICE.toLowerCase())) {
                totalDevice += cartModel.getQuantity();
            }
            if (TextUtils.equals(cartModel.getType().toLowerCase(), Constant.SIM_CARD.toLowerCase())) {
                getCart(cartModel.getId()).setSimDiscount(false);
            }
        }
        for (CartModel cartModel : cartsModels) {
            if (totalDevice > countSimDiscount && cartModel.isSelected() && TextUtils.equals(cartModel.getType().toLowerCase(), Constant.SIM_CARD.toLowerCase())) {
                getCart(cartModel.getId()).setSimDiscount(true);
                double total = (getCart(cartModel.getId()).getTotalPrice() - getCart(cartModel.getId()).getCardPrice()) + getCart(cartModel.getId()).getDiscountedCardPrice();
                getCart(cartModel.getId()).setTotalPriceAfterDiscountSim(total);
                countSimDiscount++;
            }
        }
    }


    public String getAddressSave() {
        return addressSave;
    }

    public String getProvinceSave() {
        return provinceSave;
    }

    public void setAddressSave(String addressSave) {
        this.addressSave = addressSave;
    }

    public void setProvinceSave(String provinceSave) {
        this.provinceSave = provinceSave;
    }

    public String getPhoneNumber(Context context) {
        return SeatelSharePreferences.Companion.getInstance(context).getPhoneLogin();
    }

    public String getUsername(Context context) {
        return SeatelSharePreferences.Companion.getInstance(context).getUsername();
    }

    public String getUserPhone(Context context) {
        return SeatelSharePreferences.Companion.getInstance(context).getUserPhone();
    }

    public ArrayList<CartModel> getCartsModels() {
        return cartsModels;
    }

    public ArrayList<CartModel> getSelectedCartsModels() {
        ArrayList<CartModel> tmp = new ArrayList<>();
        for (CartModel cart : cartsModels) {
            if (cart.isSelected())
                tmp.add(cart);
        }
        return tmp;
    }

    public void setUpdatedDeliveryAddress(Boolean updatedDeliveryAddress) {
        isUpdatedDeliveryAddress = updatedDeliveryAddress;
    }

    public Boolean getUpdatedDeliveryAddress() {
        return isUpdatedDeliveryAddress;
    }

    public void setUpdateProfile(Boolean updateProfile){
        isUpdateProfile = updateProfile;
    }

    public Boolean getUpdateProfile(){
        return isUpdateProfile;
    }



    public String getToolbarTitle() {
        switch (selectedSection) {
            case 1:
                return "Order Summary";
            case 2:
                return "Pickup or Delivery";
            case 3:
                return "Confirm Order";
            default:
                return "Make Payment";
        }
    }

    public int getSelectedSection() {
        return selectedSection;
    }

    public void setSelectedSection(int selectedSection) {
        this.selectedSection = selectedSection;
    }

    public void setDeliverStatus(DeliverStatus deliverStatus) {
        this.deliverStatus = deliverStatus;
    }

    public DeliverStatus getDeliverStatus() {
        return deliverStatus;
    }

    public void setLocationModel(SeatelShopLocationModel seatelShopLocationModel) {
        mSeatelShopLocationModel = new SeatelShopLocationModel();
        mSeatelShopLocationModel = seatelShopLocationModel;
        mOrderCallback.onDeliveryData(mSeatelShopLocationModel);
    }

    public double getTopupAmountClaimFreeSim() {
        for (CartModel c : getSelectedCartsModels()) {
            return c.getTopUpAmount();
        }
        return 0.0;
    }

    public SeatelShopLocationModel getLocationModel() {
        return mSeatelShopLocationModel;
    }

    public String getUrlAddForABA() {
        return "&phoneNumber=" + getPhoneNumberSave() + "&firstName=" + getFirstNameSave()
                + "&lastName=" + getLastNameSave() + "&email=" + getEmailSave();
    }

    public void executeOrderVerify(final Context context, Response.Listener<JSONObject> listener) {
        new SeatelJSONObjectRequest(context) {

            @Override
            public String getFunctionName() {
                return Constant.ORDER_VERIFY;
            }

            @Override
            public int getMethod() {
                return Request.Method.POST;
            }

            @Override
            public String onGetBodyRequest() {
                return getOrderVerifyBody(context);
            }
        }.setOnErrorListener(new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                SeatelAlertDialog.Companion.with(context, SeatelSuperRequest.getErrorMessageFrom(error)).show();
            }
        }).execute(listener);
    }

    public void executeOrderPayment(final Context context, String payment, Response.Listener<JSONObject> listener) {
        paymentMethod = payment;
        new SeatelJSONObjectRequest(context) {

            @Override
            public String getFunctionName() {
                return Constant.ORDER;
            }

            @Override
            public int getMethod() {
                return Request.Method.POST;
            }

            @Override
            public String onGetBodyRequest() {
                return getOrderBody(context);
            }
        }.setOnErrorListener(error -> SeatelAlertDialog.Companion.with(context, SeatelSuperRequest.getErrorMessageFrom(error)).show()).execute(listener);
    }

    private String getOrderVerifyBody(Context context) {
        JSONObject object = new JSONObject();
        try {
            JSONArray objectItems = new JSONArray();
            for (CartModel c : getSelectedCartsModels()) {
                JSONObject objectItem = new JSONObject();
                objectItem.put("type", c.getType());
                objectItem.put("_id", c.getId());
                objectItem.put("quantity", c.getQuantity());
                objectItem.put("deviceUrl", c.getDeviceUrl());
                objectItem.put("colorId", c.getColorId());
                objectItem.put("storage", c.getStorage());
                objectItems.put(objectItem);
            }
            object.put("items", objectItems);
            object.put("phoneNumber", getPhoneNumber(context));
            Log.d("object=", object.toString());
            return object.toString();
        } catch (Exception e) {
            return "";
        }
    }

    private String getOrderBody(Context context) {
        JSONObject object = new JSONObject();
        try {
            JSONObject objectDeliver = new JSONObject();
            objectDeliver.put("name", getUsername(context));
            objectDeliver.put("contactNumber", getUserPhone(context));
            objectDeliver.put("address", mSeatelShopLocationModel.getAddress());
            objectDeliver.put("city", mSeatelShopLocationModel.getCity());
            objectDeliver.put("latitude", mSeatelShopLocationModel.getLatitude());
            objectDeliver.put("longitude", mSeatelShopLocationModel.getLongitude());


            JSONArray objectItems = new JSONArray();
            for (CartModel c : getSelectedCartsModels()) {
                JSONObject objectItem = new JSONObject();
                objectItem.put("type", c.getType());
                objectItem.put("_id", c.getId());
                objectItem.put("quantity", c.getQuantity());
                objectItem.put("deviceUrl", c.getDeviceUrl());
                objectItem.put("colorId", c.getColorId());
                objectItem.put("storage", c.getStorage());
                objectItem.put("topUpAmount", c.getTopUpAmount());
                objectItem.put("scratchCardAmount", c.getScratchCardAmount());

//                JSONObject objectPlanSubscription = new JSONObject();
//                objectPlanSubscription.put("planName", c.getPlanName());
//                objectPlanSubscription.put("addOns", c.getPlanSubscription().getAddOns());
                if (TextUtils.equals(c.getType(), Constant.SIM_CARD)) {
                    objectItem.put("simCardNumber", c.getSimCardNumber());
                    objectItem.put("planSubscription", new JSONObject(new Gson().toJson(c.getPlanSubscription())));
                }
                objectItems.put(objectItem);
            }
            if (!TextUtils.isEmpty(paymentMethod))
                object.put("paymentMethod", paymentMethod);
            object.put("orderServiceType", deliverStatus.name);
            object.put("shopId", getLocationModel().getId());
            object.put("items", objectItems);
            object.put("deliveryLocation", objectDeliver);
            object.put("phoneNumber", getUserPhone(context));
            object.put("shipmentInsurance", getIsCheckShimmentInsurance());
            object.put("dynamicCardPrice", true);
            if (isClaimFreeSim)
                object.put("hasPromotion", true);
            if (isWinPromotionFreeSim)
                object.put("promotionItem", promotionItemId);
            return object.toString();
        } catch (Exception e) {
            return "";
        }
    }

    public String getPaymentMethod() {
        return paymentMethod;
    }

    public void setPaymentMethod(String method) {
        paymentMethod = method;
    }


    public String getOrderId() {
        return orderId;
    }

    public boolean isBuySim() {
        for (CartModel c : cartsModels) {
            if (c.isSelected() && c.getType().equalsIgnoreCase("sim-card"))
                return true;
        }
        return false;
    }

    public String getSimPriceIconUrl() {
        return simPriceIconUrl;
    }

    public void setSimPriceIconUrl(String simPriceIconUrl) {
        this.simPriceIconUrl = simPriceIconUrl;
    }

    public String getSimIconUrl() {
        return simIconUrl;
    }

    public void setSimIconUrl(String simIconUrl) {
        this.simIconUrl = simIconUrl;
    }

    public String getDeviceIconUrl() {
        return deviceIconUrl;
    }

    public void setDeviceIconUrl(String deviceIconUrl) {
        this.deviceIconUrl = deviceIconUrl;
    }

    public String getTopUpIconUrl() {
        return topUpIconUrl;
    }

    public void setTopUpIconUrl(String topUpIconUrl) {
        this.topUpIconUrl = topUpIconUrl;
    }

    public String getScratchCardIconUrl() {
        return scratchCardIconUrl;
    }

    public void setScratchCardIconUrl(String scratchCardIconUrl) {
        this.scratchCardIconUrl = scratchCardIconUrl;
    }

    public interface OrderCallback {
        void onCartModify();

        void onCartModifyQty();

        void onDeliveryData(SeatelShopLocationModel seatelShopLocationModel);
    }
}
