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.BillingBean;
import com.gingersoft.gsa.cloud.base.common.bean.OrderDetail;
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.time.TimeUtils;
import com.gingersoft.gsa.cloud.base.utils.view.ImageUtils;
import com.gingersoft.gsa.cloud.base.utils.view.LayoutToBitmapUtils;
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.stream.Collectors;

/**
 * Created by Wyh on 2020/2/10.
 * 打印工具類
 */
public class 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<>();
        List<OrderDetail> orderDetails = MyOrderManage.getInstance().getNewFoodList();
        if (orderDetails != null) {
            // 將沒有打印位置的歸類到一起
            // 如果沒有打印位置，向上尋找，如果都沒有，就不打印
            for (int i = 0; i < orderDetails.size(); i++) {
                //需要判斷大於0的原因是，如果為0，是第一個食品，則不需要向上尋找，直接不打印
                if (orderDetails.get(i).getPrintseting().equals("") && i > 0) {
                    //沒有打印位置的食品，向上尋找
                    for (int j = i - 1; j >= 0; j--) {
                        if (!orderDetails.get(j).getPrintseting().equals("")) {
                            //找到打印位置不為空的食品
                            if (orderDetails.get(j).getPrintseting().contains("*")) {
                                //如果找到的打印位置包含*號，則將這些食品單獨分為一組
                                //因為帶*號的食品會單獨打印一張紙，需求是將這些沒有打印位置的打印到向上能找到的食品的打印位置上，不管有沒有*號，都打印到一張紙上
                                //所以如果帶*號，就要特殊處理
                                String newPrintSetting = orderDetails.get(j).getPrintseting();
                                orderDetails.get(i).setPrintseting(newPrintSetting);
                            } else {
                                orderDetails.get(i).setPrintseting(orderDetails.get(j).getPrintseting());
                            }
                        }
                    }
                }
            }
            //將所有送單的食品通過打印位置分組，不同的打印位置在不同的打印紙上。
            Map<String, List<OrderDetail>> map = new HashMap<>();
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                map = orderDetails.stream().collect(Collectors.groupingBy(OrderDetail::getPrintseting));
            } else {
                for (OrderDetail orderDetail : orderDetails) {
                    if (map.containsKey(orderDetail.getPrintseting())) {
                        map.get(orderDetail.getPrintseting()).add(orderDetail);
                    } else {
                        List<OrderDetail> orderDetailList = new ArrayList<>();
                        orderDetailList.add(orderDetail);
                        map.put(orderDetail.getPrintseting(), orderDetailList);
                    }
                }
            }
            //通過打印位置生成多張用於打印的bitmap
            for (Map.Entry<String, List<OrderDetail>> entry : map.entrySet()) {
                String key = entry.getKey();
                if (key.contains("*")) {
                    //如果帶*號，這個集合就需要切紙，每個食品都需要單獨在一張廚房單上
                    for (OrderDetail orderDetail : entry.getValue()) {
                        List<OrderDetail> orders = new ArrayList<>();//這裡new集合是應為下面的方法需要的參數是list集合
                        orders.add(orderDetail);
                        bitmaps.add(PrintUtils.getKitChenPrintBitmap(mContext, orders));
                    }
                }
//                    else if (key.equals("")) {
//                        //如果沒有打印位置，向上尋找，如果都沒有，就不打印
//
//                    }
                else {
                    //不帶*號，所有同樣廚房位置的食品都在一張紙上
                    bitmaps.add(PrintUtils.getKitChenPrintBitmap(mContext, entry.getValue()));
                }
            }
        }
        return bitmaps;
    }


    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<>();
//        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<>();
//        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 + "");

        rvPayType.setLayoutManager(new LinearLayoutManager(context));
        rvPayType.setAdapter(new BillTypeAdapter(MyOrderManage.getInstance().getBillMoney()));
        //加载条形码
//        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);
            //廚房位置
            tvKitChenLocation.setText(foodList.get(0).getPrintseting().replace("*", ""));
        }
        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);
    }

}
