package com.gingersoft.supply_chain.mvp.presenter;

import android.app.Application;

import com.gingersoft.gsa.cloud.common.bean.BaseResult;
import com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager;
import com.gingersoft.gsa.cloud.common.utils.JsonUtils;
import com.gingersoft.gsa.cloud.common.utils.MoneyUtil;
import com.gingersoft.gsa.cloud.common.utils.gson.GsonUtils;
import com.gingersoft.gsa.cloud.common.utils.other.TextUtil;
import com.gingersoft.gsa.cloud.common.utils.view.BitmapUtil;
import com.gingersoft.supply_chain.mvp.bean.DeputyUnitBean;
import com.gingersoft.supply_chain.mvp.bean.PurchaseFoodBean;
import com.gingersoft.supply_chain.mvp.bean.PurchaseOrderDetailsBean;
import com.gingersoft.supply_chain.mvp.bean.OrderWareHouseBean;
import com.gingersoft.supply_chain.mvp.bean.WareHousingUnitBean;
import com.gingersoft.supply_chain.mvp.content.Constant;
import com.gingersoft.supply_chain.mvp.content.SupplyShoppingCart;
import com.jess.arms.integration.AppManager;
import com.jess.arms.di.scope.FragmentScope;
import com.jess.arms.mvp.BasePresenter;
import com.jess.arms.http.imageloader.ImageLoader;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

import javax.inject.Inject;

import com.gingersoft.supply_chain.mvp.contract.OrderDetailsContract;
import com.jess.arms.utils.RxLifecycleUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.gingersoft.supply_chain.mvp.content.Constant.GET_INFO_ERROR;
import static com.gingersoft.supply_chain.mvp.content.Constant.GET_INFO_LOADING;
import static com.gingersoft.supply_chain.mvp.content.Constant.NULL_INFO_ERROR;
import static com.gingersoft.supply_chain.mvp.content.Constant.SAVE_FAIL;
import static com.gingersoft.supply_chain.mvp.content.Constant.SAVE_LOADING;


/**
 * ================================================
 * Description:
 * <p>
 * Created by MVPArmsTemplate on 12/22/2020 16:57
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms/wiki">See me</a>
 * <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
 * ================================================
 */
@FragmentScope
public class OrderDetailsPresenter extends BasePresenter<OrderDetailsContract.Model, OrderDetailsContract.View> {
    @Inject
    RxErrorHandler mErrorHandler;
    @Inject
    Application mApplication;
    @Inject
    ImageLoader mImageLoader;
    @Inject
    AppManager mAppManager;

    private int orderId;
    /**
     * 所上傳的圖片路徑集合
     */
    private List<String> imgs;
    /**
     * 逗號分隔符
     */
    private final String COMMA_SEPARATED = ",";
    /**
     * 訂單狀態
     */
    public int orderState;

    @Inject
    public OrderDetailsPresenter(OrderDetailsContract.Model model, OrderDetailsContract.View rootView) {
        super(model, rootView);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mErrorHandler = null;
        this.mAppManager = null;
        this.mImageLoader = null;
        this.mApplication = null;
    }

    /**
     * 跟劇訂單ID獲取訂單詳情
     *
     * @param orderId 訂單ID
     */
    public void getOrderDetailsById(int orderId) {
        mModel.getOrderDetails(orderId)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(GET_INFO_LOADING))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {
                    @Override
                    public void onNext(BaseResult baseResult) {
                        if (baseResult.isSuccess()) {
                            PurchaseOrderDetailsBean orderDetailsBean = GsonUtils.GsonToBean(GsonUtils.GsonString(baseResult.getData()), PurchaseOrderDetailsBean.class);
                            if (orderDetailsBean != null) {
                                OrderDetailsPresenter.this.orderId = orderId;
                                try {
                                    transformationWareHouse(orderDetailsBean);
                                    orderState = orderDetailsBean.getStatus();
                                    //加載圖片
                                    loadImages(orderDetailsBean.getFiles());
                                    mRootView.loadOrderDetails(orderDetailsBean);
                                } catch (NullPointerException e) {
                                    mRootView.showMessage(e.getMessage());
                                    mRootView.killMyself();
                                }
                            } else {
                                mRootView.showMessage(GET_INFO_ERROR);
                            }
                        } else if (TextUtil.isNotEmptyOrNullOrUndefined(baseResult.getErrMsg())) {
                            mRootView.showMessage(baseResult.getErrMsg());
                            mRootView.killMyself();
                        } else {
                            mRootView.showMessage(GET_INFO_ERROR);
                            mRootView.killMyself();
                        }
                    }

                    /**
                     * 處理單位問題
                     * 未收過貨的單：顯示第一個副單位，用戶可切換副單位和主單位。副單位是 foodUnits集合
                     * 收過貨的單：不可操作單位，顯示入庫單位 purchaseWarehousingUnits
                     * showUnit 用於顯示的單位，進行收貨操作時傳遞給後台
                     */
                    private void transformationWareHouse(PurchaseOrderDetailsBean orderDetailsBean) throws NullPointerException {
                        List<PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean> purchaseOrderDetailsInfoVos = orderDetailsBean.getPurchaseOrderDetailsInfoVOS();
                        if (purchaseOrderDetailsInfoVos != null) {
                            //遍歷訂單商品
                            for (PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean purchaseOrderDetailsInfoVO : purchaseOrderDetailsInfoVos) {
                                purchaseOrderDetailsInfoVO.setOrderNo(orderDetailsBean.getOrderNo());
                                //單位
                                List<DeputyUnitBean> deputyUnitBeans = purchaseOrderDetailsInfoVO.getFoodUnits();
                                //計算出當前食材總金額
                                double warehousingAmount = MoneyUtil.priceCalculation(purchaseOrderDetailsInfoVO.getFoodPrice(), purchaseOrderDetailsInfoVO.getFoodQuantity());
                                //待收貨的
                                if (purchaseOrderDetailsInfoVO.getStatus() == PurchaseOrderDetailsBean.WAIT_RECEIVED) {
                                    //副單位為空，設置顯示主單位
                                    if (deputyUnitBeans == null) {
                                        deputyUnitBeans = new ArrayList<>();
                                    }
                                    if (TextUtil.isEmptyOrNullOrUndefined(purchaseOrderDetailsInfoVO.getBasicUnitName())) {
                                        throw new NullPointerException("未獲取到食品主單位，請檢查後重試");
                                    }
                                    //添加主單位到副單位列表，用戶可手動切換
                                    DeputyUnitBean deputyUnitBean = new DeputyUnitBean(purchaseOrderDetailsInfoVO.getBasicUnitName(), purchaseOrderDetailsInfoVO.getFoodQuantity());
                                    deputyUnitBeans.add(0, deputyUnitBean);
                                    //设置显示的单位，如果大於1，則顯示第一個，因為第一個是副單位，默認顯示副單位
                                    if (deputyUnitBeans.size() > 1) {
                                        purchaseOrderDetailsInfoVO.setShowUnit(deputyUnitBeans.get(1));
                                    } else {
                                        //只有一個單位，顯示主單位
                                        purchaseOrderDetailsInfoVO.setShowUnit(deputyUnitBeans.get(0));
                                    }
                                    //設置默認顯示數量和價格
                                    purchaseOrderDetailsInfoVO.getShowUnit().setDeputyValue(purchaseOrderDetailsInfoVO.getFoodQuantity());
                                    purchaseOrderDetailsInfoVO.getShowUnit().setUnitPrice(purchaseOrderDetailsInfoVO.getFoodPrice());
                                    //設置單位集合
                                    purchaseOrderDetailsInfoVO.setFoodUnits(deputyUnitBeans);
                                } else {
                                    //如果不是待收貨的商品：部分收貨和已完成，都不可再更改收貨單位，只顯示一個固定的單位
                                    //拿到入庫的那個單位
                                    WareHousingUnitBean wareHousingUnitBean = purchaseOrderDetailsInfoVO.getPurchaseWarehousingUnit();
                                    if (wareHousingUnitBean != null) {
                                        //只有一個入庫單位
                                        DeputyUnitBean warehouseUnit = DeputyUnitBean.getDeputyUnitByWareHousingUnit(wareHousingUnitBean);
                                        if (purchaseOrderDetailsInfoVO.getStatus() == PurchaseOrderDetailsBean.COMPLETE_RECEIVED) {
                                            //已經全部收貨，顯示已入庫數量
                                            warehouseUnit.setDeputyValue(purchaseOrderDetailsInfoVO.getWarehousingQuantity());
                                        } else {
                                            //已經入庫一次的食材，數量顯示為食材總數-已入庫數量
                                            warehouseUnit.setDeputyValue(Math.max(MoneyUtil.sub(purchaseOrderDetailsInfoVO.getFoodQuantity(), purchaseOrderDetailsInfoVO.getWarehousingQuantity()), 0));
                                        }
                                        purchaseOrderDetailsInfoVO.setShowUnit(warehouseUnit);
                                        purchaseOrderDetailsInfoVO.setFoodUnits(Collections.singletonList(warehouseUnit));
                                    }
                                }
                                purchaseOrderDetailsInfoVO.setWarehousingAmount(warehousingAmount);
                                purchaseOrderDetailsInfoVO.setTotalAmount(MoneyUtil.priceCalculation(purchaseOrderDetailsInfoVO.getFoodPrice(), purchaseOrderDetailsInfoVO.getFoodQuantity()));
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        super.onError(t);
                        mRootView.showMessage(GET_INFO_ERROR);
                        mRootView.killMyself();
                    }
                });
    }

    /**
     * 加載圖片
     *
     * @param images
     */
    public void loadImages(String images) {
        if (TextUtil.isNotEmptyOrNullOrUndefined(images)) {
            String[] split = images.split(COMMA_SEPARATED);
            if (imgs == null) {
                imgs = new ArrayList<>();
            }
            for (String s : split) {
                if (TextUtil.isNotEmptyOrNullOrUndefined(s)) {
                    mRootView.uploadPicSuccess(s);
                    imgs.add(s);
                }
            }
        }
    }

    /**
     * 入庫
     *
     * @param state                            入庫狀態
     * @param remark                           備註
     * @param totalAmount                      總金額
     * @param purchaseOrderDetailsInfoVosBeans 選中的食品
     */
    public void addWarehouse(int state, String remark, double totalAmount, List<PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean> purchaseOrderDetailsInfoVosBeans) {
        List<OrderWareHouseBean.PurchaseWarehousingOrderDetail> purchaseWarehousingOrderDetails = transformWareHoses(purchaseOrderDetailsInfoVosBeans);
        OrderWareHouseBean wareHouseBean = getWareHouseBean(state, remark, totalAmount, purchaseWarehousingOrderDetails);
        if (wareHouseBean == null) {
            return;
        }
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), GsonUtils.GsonString(wareHouseBean));
        mModel.addWarehouse(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(SAVE_LOADING))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {
                    @Override
                    public void onNext(BaseResult baseResult) {
                        if (baseResult.isSuccess()) {
                            mRootView.showMessage("收貨成功");
                            mRootView.killMyself();
                        } else if (TextUtil.isNotEmptyOrNullOrUndefined(baseResult.getErrMsg())) {
                            mRootView.showMessage(baseResult.getErrMsg());
                        } else {
                            mRootView.showMessage(SAVE_FAIL);
                        }
                    }
                });
    }

    /**
     * 再來一單
     */
    public void buyAgainByFoodIds(List<PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean> data) {
        if (data == null || data.size() <= 0) {
            return;
        }
        Map<String, Object> map = new HashMap<>(3);
        Constant.addRestaurantId(map);
        Constant.addBrandId(map);
        StringBuilder stringBuilder = new StringBuilder();
        for (PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean item : data) {
            stringBuilder.append(item.getPurchaseFoodId()).append(",");
        }
        map.put("ids", stringBuilder.substring(0, stringBuilder.length() - 1));
        mModel.buyAgainByFoodIds(map)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(GET_INFO_LOADING))
                .subscribeOn(AndroidSchedulers.mainThread())
                .doAfterNext(disposable -> mRootView.hideLoading())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {
                    @Override
                    public void onNext(BaseResult baseResult) {
                        if (baseResult.isSuccess()) {
                            List<PurchaseFoodBean> purchaseFoodBeans = GsonUtils.GsonToList(baseResult.getData(), PurchaseFoodBean.class);
                            for (PurchaseFoodBean purchaseFoodBean : purchaseFoodBeans) {
                                for (PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean item : data) {
                                    if (purchaseFoodBean.getId() == item.getPurchaseFoodId()) {
                                        purchaseFoodBean.setFoodQuantity(item.getFoodQuantity());
                                        break;
                                    }
                                }
                            }
                            SupplyShoppingCart.getInstance().clear();
                            SupplyShoppingCart.getInstance().getCartFoods().addAll(purchaseFoodBeans);
                            mRootView.buyAgain();
                        } else {
                            mRootView.showMessage(GET_INFO_ERROR);
                        }
                    }
                });
    }


    /**
     * 生成入庫對象
     */
    private OrderWareHouseBean getWareHouseBean(int state, String remark, double totalAmount, List<OrderWareHouseBean.PurchaseWarehousingOrderDetail> purchaseWarehousingOrderDetails) {
        if (purchaseWarehousingOrderDetails == null) {
            return null;
        }
        OrderWareHouseBean orderWareHouseBean = new OrderWareHouseBean();
        orderWareHouseBean.setStatus(state);
        orderWareHouseBean.setOrderId(orderId);

        OrderWareHouseBean.PurchaseWarehousingOrder purchaseWarehousingOrder = new OrderWareHouseBean.PurchaseWarehousingOrder();
        if (imgs != null) {
            StringBuilder files = new StringBuilder();
            for (String img : imgs) {
                files.append(img).append(COMMA_SEPARATED);
            }
            String substring = files.substring(0, files.length());
            purchaseWarehousingOrder.setFiles(substring);
        }
        purchaseWarehousingOrder.setRestaurantId(RestaurantInfoManager.newInstance().getRestaurantId());
        purchaseWarehousingOrder.setBrandId(RestaurantInfoManager.newInstance().getBrandId());
        purchaseWarehousingOrder.setRemarks(remark);
        purchaseWarehousingOrder.setTotalPrice(totalAmount);
        orderWareHouseBean.setPurchaseWarehousingOrder(purchaseWarehousingOrder);
        orderWareHouseBean.setPurchaseWarehousingOrderDetailsTOS(purchaseWarehousingOrderDetails);
        return orderWareHouseBean;
    }

    /**
     * 將訂單轉換為入庫單
     */
    private List<OrderWareHouseBean.PurchaseWarehousingOrderDetail> transformWareHoses(List<PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean> purchaseOrderDetailsInfoVosBeans) {
        if (purchaseOrderDetailsInfoVosBeans == null || purchaseOrderDetailsInfoVosBeans.size() <= 0) {
            mRootView.showMessage(NULL_INFO_ERROR);
            return null;
        }
        List<OrderWareHouseBean.PurchaseWarehousingOrderDetail> purchaseWarehousingOrderDetails = new ArrayList<>();
        for (PurchaseOrderDetailsBean.PurchaseOrderDetailsInfoVosBean purchaseOrderDetailsInfoVosBean : purchaseOrderDetailsInfoVosBeans) {
            if (purchaseOrderDetailsInfoVosBean.getStatus() != PurchaseOrderDetailsBean.COMPLETE_RECEIVED && purchaseOrderDetailsInfoVosBean.isChecked()) {
                OrderWareHouseBean.PurchaseWarehousingOrderDetail purchaseWarehousingOrderDetail = new OrderWareHouseBean.PurchaseWarehousingOrderDetail();
                purchaseWarehousingOrderDetail.setOrderDetailsId(purchaseOrderDetailsInfoVosBean.getId());
                purchaseWarehousingOrderDetail.setPurchaseFoodId(purchaseOrderDetailsInfoVosBean.getPurchaseFoodId());
                purchaseWarehousingOrderDetail.setFoodQuantity(purchaseOrderDetailsInfoVosBean.getFoodQuantity());
                purchaseWarehousingOrderDetail.setFoodPrice(purchaseOrderDetailsInfoVosBean.getFoodPrice());
                purchaseWarehousingOrderDetail.setTotalPrice(MoneyUtil.priceCalculation(purchaseOrderDetailsInfoVosBean.getFoodPrice(), purchaseOrderDetailsInfoVosBean.getFoodQuantity()));
//                List<DeputyUnitBean> deputyUnitBeans = purchaseOrderDetailsInfoVosBean.getFoodUnits();
                //將副單位轉為入庫用的副單位
//                if (deputyUnitBeans != null && deputyUnitBeans.size() > 1) {
//                    //主單位名稱
//                    purchaseWarehousingOrderDetail.setBasicUnitName(deputyUnitBeans.get(1).getDeputyUnit());
//                    //主單位數量
//                    purchaseWarehousingOrderDetail.setBasicUnitValue(deputyUnitBeans.get(1).getDeputyValue());
//                    //統計副單位
//                    List<WareHousingUnitBean> wareHousingUnitBeans = new ArrayList<>();
//                    for (int i = 0; i < deputyUnitBeans.size(); i++) {
                DeputyUnitBean deputyUnitBean = purchaseOrderDetailsInfoVosBean.getShowUnit();
                WareHousingUnitBean wareHousingUnitBean = DeputyUnitBean.getWareHousingUnitByDeputyUnit(deputyUnitBean);
                if (purchaseOrderDetailsInfoVosBean.getStatus() != PurchaseOrderDetailsBean.WAIT_RECEIVED && deputyUnitBean.getId() != null) {
                    //不是待收貨狀態才設置id，因為如果已經收過貨才有id
                    wareHousingUnitBean.setId(deputyUnitBean.getId());
                }
                wareHousingUnitBean.setBrandId(RestaurantInfoManager.newInstance().getBrandId());
                wareHousingUnitBean.setRestaurantId(RestaurantInfoManager.newInstance().getRestaurantId());
                purchaseWarehousingOrderDetail.setPurchaseWarehousingUnit(wareHousingUnitBean);
                purchaseWarehousingOrderDetails.add(purchaseWarehousingOrderDetail);
            }
        }
        if (purchaseWarehousingOrderDetails.size() <= 0) {
            mRootView.showMessage("請選擇需要操作的食品");
            return null;
        }
        return purchaseWarehousingOrderDetails;
    }

    /**
     * 刪除訂單
     */
    public void deleteOrder() {
        mModel.deleteOrder(orderId)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(Constant.DELETE_LOADING))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {
                    @Override
                    public void onNext(@NonNull BaseResult info) {
                        if (info.isSuccess()) {
                            mRootView.showMessage(Constant.DELETE_SUCCESS);
                            mRootView.killMyself();
                        }
                    }
                });
    }

    /**
     * 上傳圖片
     *
     * @param filePath 圖片路徑
     */
    public void uploadPic(String filePath) {
        File file = new File(BitmapUtil.compressImage(filePath));
        List<MultipartBody.Part> multipartBodies = new ArrayList<>();
        multipartBodies.add(MultipartBody.Part.createFormData("files", file.getName(), RequestBody.create(MediaType.parse("image/png"), file)));
        Map<String, Object> map = new HashMap<>(1);
        map.put("type", Constant.UPLOAD_PIC_TYPE_ORDER);
        mModel.upLoadPic(multipartBodies, map)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(Constant.IMG_UPLOAD_LOADING))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {
                    @Override
                    public void onNext(BaseResult baseResult) {
                        if (baseResult.isSuccess() && baseResult.getData() != null) {
                            List<String> imgUrl = JsonUtils.parseArray(baseResult.getData(), String.class);
                            if (imgUrl != null && imgUrl.size() > 0) {
                                String picUrl = imgUrl.get(0);
                                if (imgs == null) {
                                    imgs = new ArrayList<>();
                                }
                                imgs.add(picUrl);
                                mRootView.uploadPicSuccess(picUrl);
                            }
                        }
                        boolean delete = file.delete();
                    }
                });
    }

    public void deletePic(int position) {
        if (imgs != null && position < imgs.size()) {
            imgs.remove(position);
        }
    }

    public String getPic(int position) {
        if (imgs != null && position < imgs.size()) {
            return imgs.get(position);
        }
        return null;
    }

    public int getPicSize() {
        return imgs == null ? 0 : imgs.size();
    }
}
