package com.joe.print.mvp.ui.activity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;

import androidx.appcompat.app.AppCompatActivity;

import com.epson.epos2.printer.Printer;
import com.epson.epos2.printer.PrinterStatusInfo;
import com.epson.epos2.printer.ReceiveListener;
import com.gingersoft.gsa.cloud.base.application.GsaCloudApplication;
import com.gingersoft.gsa.cloud.base.order.bean.OrderDetail;
import com.gingersoft.gsa.cloud.base.utils.okhttpUtils.OkHttp3Utils;
import com.gingersoft.gsa.cloud.base.utils.time.TimeUtils;
import com.gingersoft.gsa.cloud.base.utils.toast.ToastUtils;
import com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean;
import com.gingersoft.gsa.cloud.print.PrintExecutor;
import com.gingersoft.gsa.cloud.print.PrintSocketHolder;
import com.joe.print.R;
import com.joe.print.mvp.print.common.PrinterFinderCallback;
import com.joe.print.mvp.print.common.SendCallback;
import com.joe.print.mvp.print.common.SendResultCode;
import com.joe.print.mvp.print.usb.UsbPrinter;
import com.joe.print.mvp.print.usb.UsbPrinterFinder;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

public class PrintTestActivity extends AppCompatActivity implements PrintSocketHolder.OnStateChangedListener, PrintExecutor.OnPrintResultListener, ReceiveListener {

    private int lineLength = 42;//一行42個
    private static int foodNameSpace = 16;
    private static int foodNumSpace = 8;
    private static int foodAmountSpace = 10;

    /**
     * 獲取縮進，通過文字和最大長度
     *
     * @param text
     * @param MaxLength
     * @return
     */
    private static String getSpaceByTextLength(String text, int MaxLength) {
        int spaceLength = (int) Math.ceil(MaxLength - getChineseValueLength(text));
        StringBuilder space = new StringBuilder();
        for (int i = 0; i < spaceLength; i++) {
            space.append(" ");
        }
        space.append(text);
        return space.toString();
    }

    private static String getSpaceByTextLength2(String text, int MaxLength) {
        int spaceLength = (int) Math.ceil(MaxLength - getChineseValueLength(text));
        StringBuilder space = new StringBuilder();
        space.append(text);
        for (int i = 0; i < spaceLength; i++) {
            space.append(" ");
        }
        return space.toString();
    }

    private static double cnLength = 2;//中文字符占的寬度

    /**
     * 根據字符串獲取長度，中文長度為2，在那台針式打印機長度為1.5
     *
     * @param value
     * @return
     */
    private static double getChineseValueLength(String value) {
        double valueLength = 0;
        String chinese = "[\u4e00-\u9fa5]";
        for (int i = 0; i < value.length(); i++) {
            String temp = value.substring(i, i + 1);
            if (temp.matches(chinese)) {
                valueLength += cnLength;
            } else {
                valueLength += 1;
            }
        }
        return valueLength;
//        return getBytesLength(value);
    }

    /**
     * 获取数据长度
     *
     * @param msg
     * @return
     */
    @SuppressLint("NewApi")
    private static int getBytesLength(String msg) {
        return msg.getBytes(Charset.forName("GB2312")).length;
    }

    private static String abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";


    /**
     * 如果超過紙張寬度的英文，換行時，要截取得當
     */
    public static List<String> getFormatList(String content) {
        String chinese = "[\u4e00-\u9fa5]";
        List<String> stringList = new ArrayList<>();
        int length = 0;
        int startIndex = 0;
        for (int i = 0; i < content.length(); i++) {
            String temp = content.substring(i, i + 1);
            //判斷中英文，累積長度
            if (temp.matches(chinese)) {
                length += 2;
            } else {
                length += 1;
            }
            if (length > foodNameSpace) {
                i -= 1;
            }
            //長度達到設定的值
            if (length >= foodNameSpace) {
                String headerStr = content.substring(startIndex, i + 1);
                String lastStr = headerStr.substring(headerStr.length() - 1);
                if (abc.contains(lastStr)) {
                    if (headerStr.length() + 1 <= content.length()) {
                        String nextFirstStr = content.substring(headerStr.length(), headerStr.length() + 1);
                        if (abc.contains(nextFirstStr)) {
                            //如果截取後最後一個字符是英文，則需要判斷下一個字符是不是英文
                            //是，那麼這是一整個單詞，需要截取整段換到下一行去
                            for (int j = headerStr.length() - 1; j >= 0; j--) {
                                String str = headerStr.charAt(j) + "";
                                if (!abc.contains(str)) {
                                    //找到不是英文的
                                    String newHeaderStr = headerStr.substring(0, j + 1);
                                    stringList.add(newHeaderStr);
                                    startIndex = i - (headerStr.length() - newHeaderStr.length()) + 1;
                                    length = 0;
                                    i = startIndex;
                                    break;
                                }
                                if (j == 0) {
                                    //循環完了都沒找到，就不管了
                                    stringList.add(headerStr);
                                    startIndex = i + 1;
                                    length = 0;
                                    break;
                                }
                            }
                        } else {
                            stringList.add(headerStr);
                            startIndex = i + 1;
                            length = 0;
                        }
                    } else {
                        stringList.add(headerStr);
                        startIndex = i + 1;
                        length = 0;
                    }
                } else {
                    stringList.add(headerStr);
                    startIndex = i + 1;
                    length = 0;
                }
            } else if (length > 0 && i == content.length() - 1) {
                stringList.add(content.substring(startIndex));
            }
        }
        return stringList;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_print_test);
        EditText ed_ip = findViewById(R.id.ed_ip);
        UsbPrinterFinder printerFinder = new UsbPrinterFinder(this, printerFinderCallback);
        printerFinder.startFinder();

        List<OrderDetail> foodList = new ArrayList<>();
        foodList.add(new OrderDetail("Thịt bò não trong nước sốt nâu", 5, 0));
        foodList.add(new OrderDetail("        紅燒牛肉          拉麵", 10, 1));
        foodList.add(new OrderDetail("เนื้อตุ๋น", 200, 2));
        foodList.add(new OrderDetail("牛肉の角煮アスティフェン", 1000, 30));

        findViewById(R.id.btn_test).setOnClickListener(view -> {
            //打印測試
            String stringBuilder = "<html><body>" +
                    getPLable(GsaCloudApplication.getBrandName()) +
                    getPLable(GsaCloudApplication.getRestaurantName()) +
                    getPLable(getLineChar(lineLength,"_")) +
                    getPLable("餐檯：                 " + "111") +
                    getPLable("人數：23") +
                    getPLable("123456789123456789123456789123456789123456789") +
                    getPLable("日期：" + TimeUtils.getCurrentTimeInString(TimeUtils.DEFAULT_DATE_FORMAT)) +
                    getPLable(getLineChar(lineLength,"_")) +
                    getPLable(getFoodListStr(foodList)) +
                    "</body></html>";
            OkHttp3Utils.get("http://localhost:8080/pos?transactionType=PRINT&isExternal=false&apiVersion=21&printData=" + stringBuilder).subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(String s) {
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
        });
    }

    public String getLineChar(int size, String str){
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < size; i++) {
            stringBuilder.append(str);
        }
        return stringBuilder.toString();
    }

    public static void main(String[] args) {
        List<OrderDetail> foodList = new ArrayList<>();
        foodList.add(new OrderDetail("牛肉", 0.5, 3));
        foodList.add(new OrderDetail("紅燒牛肉", 5, 0));
        foodList.add(new OrderDetail("        紅燒牛肉          拉麵", 10, 1));
        foodList.add(new OrderDetail("康師傅紅燒牛肉麵", 200, 2));
        foodList.add(new OrderDetail("紅燒牛肉炒康師傅", 1000, 30));
        System.out.print(getFoodListStr(foodList));
    }

    public static String getFoodListStr(List<OrderDetail> foodList) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<strong>");
        for (OrderDetail detail : foodList) {
//            stringBuilder.append(getLineFood(detail.getProductName(), detail.getNumber(), detail.getPrice()));
            stringBuilder.append("<div align=\"left\">")
                    .append(detail.getProductName())
                    .append("</div>");

            stringBuilder.append("<div align=\"right\">")
                    .append("X")
                    .append(detail.getNumber())
                    .append("         $")
                    .append(detail.getPrice())
                    .append("</div>");
        }
        stringBuilder.append("</strong>");
        return stringBuilder.toString();
    }

    public static String getLineFood(String foodName, int foodNum, double foodAmount) {
        List<String> stringList = getFormatList(foodName);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < stringList.size(); i++) {
            if (i == 0) {
                stringBuilder.append("<p>")
                        .append(getSpaceByTextLength2(stringList.get(i), foodNameSpace))
                        .append(getSpaceByTextLength("X" + foodNum, foodNumSpace))
                        .append(getSpaceByTextLength("$" + foodAmount, foodAmountSpace))
                        .append("</p>");
//                stringBuilder.append(getSpaceByTextLength2(stringList.get(i), foodNameSpace));
//                String foodNumStr = "X" + foodNum;
//                stringBuilder.append(getSpaceByTextLength(foodNumStr, foodNumSpace));
//                stringBuilder.append(getSpaceByTextLength("$" + foodAmount, foodAmountSpace));
            } else {
                stringBuilder.append("<p>")
                        .append(stringList.get(i))
                        .append("</p>");
            }
//            if (i != stringList.size() - 1) {
//            stringBuilder.append("<br/>");
            stringBuilder.append("\n");
//            }
        }
        return stringBuilder.toString();
    }

    private String getDiv(String content) {
        return "<div>" + content + "</div>";
    }

    private String getLineLable() {
        return "<br/>";
    }

    private String getPLable(String content) {
        return "<p>" + content + "</p>";
    }

    @Override
    public void onResult(int errorCode, PrinterDeviceBean printerDeviceBean) {
        if (errorCode == 0) {
            ToastUtils.show(PrintTestActivity.this, "打印失败");
        }
    }

    @Override
    public void onStateChanged(int state, PrinterDeviceBean printerDeviceBean) {

    }


    private String TAG = "eee";

    private PrinterFinderCallback<UsbPrinter> printerFinderCallback = new PrinterFinderCallback<UsbPrinter>() {

        @Override
        public void onStart() {
            Log.d(TAG, "startFind print");
        }

        @Override
        public void onFound(UsbPrinter usbPrinter) {
            //listAdapter.addData(usbPrinter);
            ToastUtils.show(PrintTestActivity.this, "onFound deviceName = " + usbPrinter.getPrinterName());
            Log.d(TAG, "onFound deviceName = " + usbPrinter.getPrinterName());
        }

        @Override
        public void onFinished(List<UsbPrinter> printers) {
            ToastUtils.show(PrintTestActivity.this, "printCount = " + printers.size());
            Log.d(TAG, "printCount = " + printers.size());
//            listAdapter.replaceDatas(usbPrinters);
        }
    };

    private SendCallback sendCallback = (code, printId) -> {
        String msg = "";
        if (code == SendResultCode.SEND_SUCCESS) {
            Log.d(TAG, "打印成功");
        } else if (code == SendResultCode.SEND_FAILED) {
            Log.d(TAG, "打印失敗");
        }
    };

    @Override
    public void onPtrReceive(Printer printer, int i, PrinterStatusInfo printerStatusInfo, String s) {
        if (i == 0) {
            ToastUtils.show(PrintTestActivity.this, "打印成功");
        } else {
            ToastUtils.show(PrintTestActivity.this, "打印失败");
        }
    }
}
