package com.joe.print.mvp.print;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.gingersoft.gsa.cloud.base.adapter.print.BillAdapter;
import com.gingersoft.gsa.cloud.base.adapter.print.BillTypeAdapter;
import com.gingersoft.gsa.cloud.base.adapter.print.FoodAdapter;
import com.gingersoft.gsa.cloud.base.adapter.print.KitChenPrintFoodAdapter;
import com.gingersoft.gsa.cloud.base.application.GsaCloudApplication;
import com.gingersoft.gsa.cloud.base.common.bean.BillOrderMoney;
import com.gingersoft.gsa.cloud.base.common.bean.BillingBean;
import com.gingersoft.gsa.cloud.base.common.bean.OrderDetail;
import com.gingersoft.gsa.cloud.base.common.bean.PayMethod;
import com.gingersoft.gsa.cloud.base.common.bean.TableBean;
import com.gingersoft.gsa.cloud.base.common.bean.mealManage.MyOrderManage;
import com.gingersoft.gsa.cloud.base.common.bean.mealManage.OpenTableManage;
import com.gingersoft.gsa.cloud.base.utils.MoneyUtil;
import com.gingersoft.gsa.cloud.base.utils.PrintTransitUtils;
import com.gingersoft.gsa.cloud.base.utils.log.LogUtil;
import com.gingersoft.gsa.cloud.base.utils.other.TextUtil;
import com.gingersoft.gsa.cloud.base.utils.time.TimeUtils;
import com.gingersoft.gsa.cloud.base.utils.view.ImageUtils;
import com.gingersoft.gsa.cloud.base.utils.view.LayoutToBitmapUtils;
import com.gingersoft.gsa.cloud.base.widget.NoScrollRecyclerView;
import com.joe.print.R;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by Wyh on 2020/2/10.
 * 打印工具類
 */
public class PrintUtils {

    private static final String TAG = "PrintUtils";
    private static int paperWidth = 380;

    /**
     * @param mContext   上下文
     * @param type       打印類型  0：上菜紙
     *                   * 1：印單
     *                   * 2：結賬單
     *                   * 3：廚房單
     * @param paperWidth 紙張寬度
     * @return 返回需要打印的圖片
     */
    public static List<Bitmap> getPrintBitmap(Context mContext, int type, int paperWidth) {
        List<Bitmap> bitmaps = new ArrayList<>();
        PrintUtils.paperWidth = paperWidth;
        if (type == -1) {
            //測試紙
            bitmaps.add(getTestPrintBitmap(mContext));
        } else if (type == 0) {
            //上菜紙
            bitmaps.add(getPrintBitmap(mContext, MyOrderManage.getInstance().getNewFoodList()));
        } else if (type == 1) {
            //印單，可能會有還未送單的食品，同時也要將未送單的食品以廚房單的格式打印出來
            bitmaps.add(getPrintBitmap(mContext));
            bitmaps.addAll(getKitchenBitmap(mContext));
        } else if (type == 2) {
            //結賬單
            bitmaps.add(getPrintBillBitmap(mContext));
        } else if (type == 3) {
            //廚房單，需要切紙
            bitmaps.addAll(getKitchenBitmap(mContext));
        } else if (type == 4) {
            //清機報表
            bitmaps.add(getReportBitmap(mContext));
        }
        return bitmaps;
    }


    private static List<Bitmap> getKitchenBitmap(Context mContext) {
        List<Bitmap> bitmaps = new ArrayList<>();
//        Map<String, List<Bitmap>> bitmapMaps = new HashMap<>();

        List<OrderDetail> orderDetails = MyOrderManage.getInstance().getNewFoodList();
        if (orderDetails != null) {
            //廚房單，可能會有多個IP打印
            //獲得ip打印列表，
            //再將食品數據根據打印位置分組。
            //打印一組之後，關閉連接，切換第二台打印機ip，如此循環
            //打印完成之後，返回所有打印結果。
            Map<String, List<OrderDetail>> foodMaps = new HashMap<>();
            String emptyPrintLocation = "null";//部分食品沒有打印位置時設置為此key，比如這是第一個食品，沒有打印位置時
            int lastEmptyPrintLocationIndex = 0;//上一次遍歷到第一個食品時都沒有打印位置時，開始的食品位置
            //將所有食品進行遍歷，分組
            for (int i = 0; i < orderDetails.size(); i++) {
                OrderDetail food = orderDetails.get(i);
                if (TextUtil.isEmptyOrNullOrUndefined(food.getPrintseting())) {
                    //如果沒有打印位置，向上尋找
                    if (i == 0) {
                        food.setPrintseting(emptyPrintLocation);
                        addToMap(foodMaps, food);
                    } else {
                        for (int j = i - 1; j >= lastEmptyPrintLocationIndex; j--) {
                            //一直遍歷，直到找到有打印位置的食品
                            // 如果所有食品都沒有打印位置的情況，為了避免多次遍歷
                            // 如果本次遍歷到第一個食品，都沒有打印位置，記錄下這一次開始遍歷的下標，下一次遍歷到這個位置就停止
                            if (!TextUtil.isEmptyOrNullOrUndefined(orderDetails.get(j).getPrintseting())) {
                                //一直遍歷，直到找到有打印位置的食品
                                //判斷是否帶*號
                                if (orderDetails.get(j).getPrintseting().contains("*")) {
                                    //帶*號，則需要取得通過下標加去掉*號的標識來取得map中的集合，將i食品裝進去，這樣就能打印在一張紙上
                                    //如果沒取得集合，則通過打印位置去map取得集合，將j食品從map中移除，將這個j食品的和i食品裝一起
                                    // 生成新的key。為當前下標+去掉*的打印位置，不帶*的key取得的食品集合才能打印在一張紙上。
                                    String newKey = j + orderDetails.get(j).getPrintseting().replaceAll("\\*", "");
                                    //通過newKey取得map中的集合
                                    List<OrderDetail> newKeyfoods = foodMaps.get(newKey);
                                    if (newKeyfoods != null) {
                                        newKeyfoods.add(food);
                                    } else {
                                        List<OrderDetail> printsetingFoods = foodMaps.get(orderDetails.get(j).getPrintseting());
                                        if (printsetingFoods != null) {//理論上不會為空
                                            printsetingFoods.remove(printsetingFoods.lastIndexOf(orderDetails.get(j)));
                                            //移除掉之後，put到newkey中
                                            List<OrderDetail> newFoods = new ArrayList<>();
                                            newFoods.add(orderDetails.get(j));
                                            newFoods.add(food);
                                            foodMaps.put(newKey, newFoods);
                                        }
                                    }
                                    break;
                                } else {
                                    //沒有*號，不需要做多餘的操作
                                    food.setPrintseting(orderDetails.get(j).getPrintseting());
                                    addToMap(foodMaps, food);
                                }
                            } else if (j == lastEmptyPrintLocationIndex) {
                                //從i到0的打印位置都沒有，記錄下i，下次只遍歷到i就停下來
                                lastEmptyPrintLocationIndex = i;
                                //如果找到最初的那個食品，也沒有打印位置，設置打印位置為"null"
                                food.setPrintseting(emptyPrintLocation);
                                addToMap(foodMaps, food);
                            }
                        }
                    }
                } else {
                    //有打印位置，
                    //已經保存過這個位置的，
                    addToMap(foodMaps, food);
                }
            }
            //通過打印位置生成多張用於打印的bitmap
            for (Map.Entry<String, List<OrderDetail>> entry : foodMaps.entrySet()) {
                String key = entry.getKey();
//                List<Bitmap> bitmaps1 = new ArrayList<>();
                if (key.contains("*")) {
                    //如果帶*號，這個集合就需要切紙，每個食品都需要單獨在一張廚房單上
                    for (OrderDetail orderDetail : entry.getValue()) {
                        List<OrderDetail> orders = new ArrayList<>();//這裡new集合是因為下面的方法需要的參數是list集合
                        orders.add(orderDetail);
                        bitmaps.add(PrintUtils.getKitChenPrintBitmap(mContext, orders));
//                        bitmaps1.add(PrintUtils.getKitChenPrintBitmap(mContext, orders));
                    }
                } else {
                    //不帶*號，所有同樣廚房位置的食品都在一張紙上
                    bitmaps.add(PrintUtils.getKitChenPrintBitmap(mContext, entry.getValue()));
//                    bitmaps1.add(PrintUtils.getKitChenPrintBitmap(mContext, entry.getValue()));
                }
//                bitmapMaps.put(key, bitmaps1);
            }
        }
        //通過遍歷map進行打印
        return bitmaps;
    }

    private static void addToMap(Map<String, List<OrderDetail>> foodMaps, OrderDetail food) {
        if (foodMaps.get(food.getPrintseting()) != null) {
            Objects.requireNonNull(foodMaps.get(food.getPrintseting())).add(food);
        } else {
            List<OrderDetail> newFoods = new ArrayList<>();
            newFoods.add(food);
            foodMaps.put(food.getPrintseting(), newFoods);
        }
    }

    private static Bitmap getPrintBitmap(Context context) {
        return getPrintBitmap(context, MyOrderManage.getInstance().getOrderFoodList());
    }

    /**
     * 獲取"印單"圖片
     *
     * @param context
     * @return
     */
    private static Bitmap getPrintBitmap(Context context, List<OrderDetail> foodList) {
        if (foodList == null || foodList.size() <= 0) {
            return null;
        }
        View view = LinearLayout.inflate(context, R.layout.print_layout_print, null);
        TextView brandName = view.findViewById(R.id.tv_brand_name);
        TextView restaurantName = view.findViewById(R.id.tv_restaurant_name);
        TextView tableNum = view.findViewById(R.id.tv_dining_table_number);
        TextView people = view.findViewById(R.id.tv_people);
        TextView orderNum = view.findViewById(R.id.tv_order_num);
        TextView orderData = view.findViewById(R.id.tv_date);
        RecyclerView rvFood = view.findViewById(R.id.rv_food);
        RecyclerView rvBillAmount = view.findViewById(R.id.rv_bill_amount);
        TextView mTvTotalAmount = view.findViewById(R.id.tv_total_amount);
        TextView checkOutTime = view.findViewById(R.id.tv_checkout_time);
        TextView line_food_info = view.findViewById(R.id.line_food_info);
//        List<OrderDetail> foodList = MyOrderManage.getInstance().getOrderFoodList();
        TableBean.DataBean tableBean = OpenTableManage.getDefault().getTableBean();

        tableNum.setText(tableBean.getTableName());
        people.setText(OpenTableManage.getDefault().getPeopleNumber() + "");

        orderData.setText(TimeUtils.getCurrentTimeInString(TimeUtils.DEFAULT_DATE_FORMAT));

        checkOutTime.setText(TimeUtils.getCurrentTimeInString(TimeUtils.DEFAULT_DATE_FORMAT));

        FoodAdapter foodAdapter = new FoodAdapter(foodList);
        rvFood.setLayoutManager(new LinearLayoutManager(context));
        rvFood.setAdapter(foodAdapter);

        List<BillingBean> billingBeans = new ArrayList<>();
        if (MyOrderManage.getInstance().getOrderMoneyList().size() > 0) {
            for (BillOrderMoney item : MyOrderManage.getInstance().getOrderMoneyList()) {
                billingBeans.add(new BillingBean(item.getTitle(), item.getMoney()));
            }
        }
        LogUtil.d(TAG,"getPrintBitmap OrderMoneyList size: "+  MyOrderManage.getInstance().getOrderMoneyList().size());
//        billingBeans.add(new BillingBean("合計", 58.88));
        billingBeans.add(new BillingBean("10%服務費", 5.08));
//        billingBeans.add(new BillingBean("賬單小數", -0.06));
        if (billingBeans.size() <= 0) {
            line_food_info.setVisibility(View.GONE);
        } else {
            BillAdapter billAdapter = new BillAdapter(billingBeans);
            rvBillAmount.setLayoutManager(new LinearLayoutManager(context));
            rvBillAmount.setAdapter(billAdapter);
        }
        if (OpenTableManage.getDefault().getTableBean() != null) {
            tableNum.setText(OpenTableManage.getDefault().getTableBean().getTableName());
            people.setText(OpenTableManage.getDefault().getPeopleNumber() + "");
        }

        if (MyOrderManage.getInstance().getOrderId() != -1) {
            orderNum.setText(MyOrderManage.getInstance().getOrderId() + "");
        }

        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderDetail OrderDetail : foodList) {
            totalAmount = MoneyUtil.sum(totalAmount, MoneyUtil.priceCalculation(OrderDetail.getPrice(), OrderDetail.getNumber()));
        }
        //總金額
        mTvTotalAmount.setText(totalAmount + "");

        //加载条形码
//        ImageView ivBarCode = view.findViewById(R.id.iv_bar_code);
//        ivBarCode.setImageBitmap(BitmapUtil.generateBitmap("12312112131", 2, 450, 150));
        return viewToBitmap(context, view);
    }

    /**
     * 獲取"結賬單"圖片
     *
     * @param context
     * @return
     */
    private static Bitmap getPrintBillBitmap(Context context) {
        List<OrderDetail> foodList = MyOrderManage.getInstance().getOrderFoodList();
        TableBean.DataBean tableBean = OpenTableManage.getDefault().getTableBean();
        if (foodList == null || foodList.size() <= 0 || tableBean == null) {
            return null;
        }
        View view = LinearLayout.inflate(context, R.layout.print_layout_print_bill, null);
        TextView brandName = view.findViewById(R.id.tv_brand_name);
        TextView restaurantName = view.findViewById(R.id.tv_restaurant_name);
        TextView topOrderNum = view.findViewById(R.id.tv_print_bill_order_num);//頂部的訂單號
        TextView tableNum = view.findViewById(R.id.tv_dining_table_number);
        TextView people = view.findViewById(R.id.tv_people);
        TextView orderNum = view.findViewById(R.id.tv_order_num);
        TextView orderData = view.findViewById(R.id.tv_date);
        RecyclerView rvFood = view.findViewById(R.id.rv_food);
        RecyclerView rvBillAmount = view.findViewById(R.id.rv_bill_amount);
        TextView mTvTotalAmount = view.findViewById(R.id.tv_total_amount);
        TextView checkOutTime = view.findViewById(R.id.tv_checkout_time);
        TextView line_food_info = view.findViewById(R.id.line_food_info);
        RecyclerView rvPayType = view.findViewById(R.id.rv_print_pay_type);//顯示支付方式


        tableNum.setText(tableBean.getTableName());
        people.setText(OpenTableManage.getDefault().getPeopleNumber() + "");

        orderData.setText(TimeUtils.parseTimeRepeat(tableBean.getCreateTime(), TimeUtils.DEFAULT_DATE_FORMAT));
        checkOutTime.setText(TimeUtils.getCurrentTimeInString(TimeUtils.DEFAULT_DATE_FORMAT));

        FoodAdapter foodAdapter = new FoodAdapter(foodList);
        rvFood.setLayoutManager(new LinearLayoutManager(context));
        rvFood.setAdapter(foodAdapter);

        List<BillingBean> billingBeans = new ArrayList<>();
        if (MyOrderManage.getInstance().getOrderMoneyList().size() > 0) {
            for (BillOrderMoney item : MyOrderManage.getInstance().getOrderMoneyList()) {
                billingBeans.add(new BillingBean(item.getTitle(), item.getMoney()));
            }
        }
//        billingBeans.add(new BillingBean("合計", 58.88));
//        billingBeans.add(new BillingBean("10%服務費", 5.08));
//        billingBeans.add(new BillingBean("賬單小數", -0.06));
        if (billingBeans.size() <= 0) {
            line_food_info.setVisibility(View.GONE);
        } else {
            BillAdapter billAdapter = new BillAdapter(billingBeans);
            rvBillAmount.setLayoutManager(new LinearLayoutManager(context));
            rvBillAmount.setAdapter(billAdapter);
        }
        if (OpenTableManage.getDefault().getTableBean() != null) {
            tableNum.setText(OpenTableManage.getDefault().getTableBean().getTableName());
            people.setText(OpenTableManage.getDefault().getPeopleNumber() + "");
        }

        if (MyOrderManage.getInstance().getOrderId() != -1) {
            orderNum.setText(MyOrderManage.getInstance().getOrderId() + "");
        }

        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderDetail OrderDetail : MyOrderManage.getInstance().getOrderFoodList()) {
            totalAmount = MoneyUtil.sum(totalAmount, OrderDetail.getPrice());
        }
        //總金額
        mTvTotalAmount.setText(totalAmount + "");

        List<PayMethod> payBillMoneys = MyOrderManage.getInstance().getBillMoney();
        rvPayType.setLayoutManager(new LinearLayoutManager(context));
        rvPayType.setAdapter(new BillTypeAdapter(payBillMoneys));
        //加载条形码
//        ImageView ivBarCode = view.findViewById(R.id.iv_bar_code);
//        ivBarCode.setImageBitmap(BitmapUtil.generateBitmap("12312112131", 2, 450, 150));
        return viewToBitmap(context, view);
    }


    /**
     * 獲取"廚房單"圖片
     *
     * @param context
     * @return
     */
    private static Bitmap getKitChenPrintBitmap(Context context, List<OrderDetail> foodList) {
        if (foodList == null || foodList.size() <= 0) {
            return null;
        }
        View view = LinearLayout.inflate(context, R.layout.print_kitchen, null);
        TextView tvTableNumber = view.findViewById(R.id.tv_kitchen_print_table_number);
        TextView tvOrderNumber = view.findViewById(R.id.tv_order_num);
        TextView tvOpeningTime = view.findViewById(R.id.tv_opening_time);
        TextView tvOrderTime = view.findViewById(R.id.tv_order_time);
        TextView tvKitChenLocation = view.findViewById(R.id.tv_kitchen_location);
        TextView tvPeople = view.findViewById(R.id.tv_people);
        TextView tvOperator = view.findViewById(R.id.tv_operator);
        RecyclerView rvFood = view.findViewById(R.id.rv_kitchen_food);
        TextView tvTableNumber2 = view.findViewById(R.id.tv_kitchen_print_table_number2);
        if (foodList.size() > 0 && foodList.get(0) != null) {
            KitChenPrintFoodAdapter foodAdapter = new KitChenPrintFoodAdapter(foodList);
            rvFood.setLayoutManager(new LinearLayoutManager(context));
            rvFood.setAdapter(foodAdapter);
            //廚房位置
            if (!TextUtil.isEmptyOrNullOrUndefined(foodList.get(0).getPrintseting())) {
                tvKitChenLocation.setText(foodList.get(0).getPrintseting());//.replace("*", "")
                tvKitChenLocation.setVisibility(View.VISIBLE);
            } else {
                tvKitChenLocation.setVisibility(View.GONE);
            }
        }
        if (OpenTableManage.getDefault().getTableBean() != null) {
//            台號
            tvTableNumber.setText(OpenTableManage.getDefault().getTableBean().getTableName() + "");
            tvTableNumber2.setText(OpenTableManage.getDefault().getTableBean().getTableName() + "");
            //人數
            tvPeople.setText(OpenTableManage.getDefault().getPeopleNumber() + "");
            //訂單號
            tvOrderNumber.setText("" + MyOrderManage.getInstance().getOrderId());
            //開台時間
            tvOpeningTime.setText(TimeUtils.parseTimeRepeat(OpenTableManage.getDefault().getTableBean().getCreateTime(), TimeUtils.DEFAULT_DATE_FORMAT));
        }
        //落單時間，為當前時間
        tvOrderTime.setText(TimeUtils.getCurrentTimeInString(TimeUtils.DEFAULT_DATE_FORMAT));
        //操作人員
        tvOperator.setText(GsaCloudApplication.userName);

        return viewToBitmap(context, view);
    }

    /**
     * 獲取測試打印bitmap
     *
     * @param context
     * @return
     */
    private static Bitmap getTestPrintBitmap(Context context) {
        View view = LinearLayout.inflate(context, R.layout.print_test, null);
        return viewToBitmap(context, view);
    }

    /**
     * 獲取清機報表Bitmap
     *
     * @param mContext
     * @return
     */
    private static Bitmap getReportBitmap(Context mContext) {
        View view = PrintTransitUtils.getInstance().getPrintView();
        if (view != null) {
            return viewToBitmap(mContext, view);
        }
        return null;
    }


    public static Bitmap viewToBitmap(Context context, View view) {
        LayoutToBitmapUtils.layoutView(context, view);//先测量view
        //580為程序支持的打印紙最大寬度
        return ImageUtils.zoomDrawable(LayoutToBitmapUtils.loadBitmapFromView(view), paperWidth);//将view轉bitmap
    }

    /**
     * 當前設備是不是打印設備
     *
     * @return
     */
    public static boolean isPrintDevice() {
        return GsaCloudApplication.mV2.contains(Build.MODEL) || GsaCloudApplication.mN5.contains(Build.MODEL);
    }

}
