package com.fos.modules.printOrder.util;

import com.fos.core.conf.GConstants;
import com.fos.modules.printOrder.entity.OrderEntity;
import com.fos.modules.printOrder.entity.PrintOrderEntity;
import com.fos.modules.printOrder.entity.SubFoodEntity;
import com.fos.modules.userOrder.service.UserOrderService;
import org.apache.commons.lang3.text.WordUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.print.PrintService;
import java.awt.*;
import java.awt.print.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

//实现Printable接口 用于创建打印内容  
public class PrintTicket implements Printable {

    private final static Logger log = LoggerFactory.getLogger(UserOrderService.class);

    private Font font;

    private static PrintOrderEntity printEntity;
    private static boolean titleMain = false;
    private static boolean titleDrink = false;
    private static boolean titleNoodle = false;
    private static boolean isIncludeMain = false;
    private static boolean isSetIncludeMain = false;
    private static boolean isIncludeDrink = false;
    private static boolean isSetIncludeDrink = false;
    private static boolean isIncludeNoodle = false;
    private static boolean isSetIncludeNoodle = false;
    private static boolean setTmp1 = false;
    private static boolean tmp1 = false;
    private static boolean setTmp2 = false;
    private static boolean tmp2 = false;

    private double x;
    private double y;

    public static String PrintTicket(PrintOrderEntity printOrderEntity) {

        printEntity = printOrderEntity;

        // 通俗理解就是书、文档(订单)
        Book book = new Book();

        // 打印格式
        PageFormat pf = new PageFormat();
        pf.setOrientation(PageFormat.PORTRAIT);

        // 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
        Paper p = new Paper();
        // p.setSize(158, 30000);
        // p.setImageableArea(0, 0, 158,
        // 30000);// A4(595 X // 842)设置打印区域，其实0，0应该是72，72，因为A4纸的默认X,Y边距是72  
        p.setSize(200, 30000);
        p.setImageableArea(0, 0, 200, 30000);
        pf.setPaper(p);

        // 把 PageFormat 和 Printable 添加到书中，组成一个页面
        book.append(new PrintTicket(), pf);

        // 打印全部
        // String strRet = printAll(book, GConstants.PRINTER_NAME_FOOD);
        String strRet = "";

        // 订单判断订单里是否有餐食
        List<OrderEntity> entityList = printEntity.getOrderList();
        for (OrderEntity orderEntity : entityList) {
            if ("0".equals(orderEntity.getFoodType()) && (orderEntity.getFoodNameList() == null || orderEntity.getFoodNameList().size() == 0)) {
                isIncludeMain = true;
            } else {
                List<SubFoodEntity> subFoodList = orderEntity.getFoodNameList();
                for (SubFoodEntity subFoodEntity : subFoodList) {
                    if ("0".equals(subFoodEntity.getFoodType())) {
                        isSetIncludeMain = true;
                    }
                }
            }
        }

        // 订单里有餐食
        if (isIncludeMain || isSetIncludeMain) {
            tmp1 = isIncludeDrink;
            setTmp1 = isSetIncludeDrink;
            tmp2 = isIncludeNoodle;
            setTmp2 = isSetIncludeNoodle;
            isIncludeDrink = false;
            isSetIncludeDrink = false;
            isIncludeNoodle = false;
            isSetIncludeNoodle = false;
            // 餐吧打印餐食 * 2
            titleMain = true;
            printAll(book, GConstants.PRINTER_NAME_FOOD);
            strRet = printAll(book, GConstants.PRINTER_NAME_FOOD);
            titleMain = false;
            isIncludeDrink = tmp1;
            isSetIncludeDrink = setTmp2;
            isIncludeNoodle = tmp2;
            isSetIncludeNoodle = setTmp2;
        }

        // 订单判断订单里是否有饮料
        for (OrderEntity orderEntity : entityList) {
            if ("1".equals(orderEntity.getFoodType()) && (orderEntity.getFoodNameList() == null || orderEntity.getFoodNameList().size() == 0)) {
                isIncludeDrink = true;
            } else {
                List<SubFoodEntity> subFoodList = orderEntity.getFoodNameList();
                for (SubFoodEntity subFoodEntity : subFoodList) {
                    if ("1".equals(subFoodEntity.getFoodType())) {
                        isSetIncludeDrink = true;
                    }
                }
            }
        }

        // 订单里有饮料
        if (isIncludeDrink || isSetIncludeDrink) {
            tmp1 = isIncludeMain;
            setTmp1 = isSetIncludeMain;
            tmp2 = isIncludeNoodle;
            setTmp2 = isSetIncludeNoodle;
            isIncludeMain = false;
            isSetIncludeMain = false;
            isIncludeNoodle = false;
            isSetIncludeNoodle = false;
            // 餐吧打印饮料
            titleDrink = true;
            printAll(book, GConstants.PRINTER_NAME_FOOD);
            // 水吧打印饮料
            strRet = printAll(book, GConstants.PRINTER_NAME_DRINK);
            titleDrink = false;
            isIncludeMain = tmp1;
            isSetIncludeMain = setTmp1;
            isIncludeNoodle = tmp2;
            isSetIncludeNoodle = setTmp2;
        }

        // 订单判断订单里是否有面食
        for (OrderEntity orderEntity : entityList) {
            if ("3".equals(orderEntity.getFoodType()) && (orderEntity.getFoodNameList() == null || orderEntity.getFoodNameList().size() == 0)) {
                isIncludeNoodle = true;
            } else {
                List<SubFoodEntity> subFoodList = orderEntity.getFoodNameList();
                for (SubFoodEntity subFoodEntity : subFoodList) {
                    if ("3".equals(subFoodEntity.getFoodType())) {
                        isSetIncludeNoodle = true;
                    }
                }
            }
        }

        // 订单里有面食
        if (isIncludeNoodle || isSetIncludeNoodle) {
            tmp1 = isIncludeMain;
            setTmp1 = isSetIncludeMain;
            tmp2 = isIncludeDrink;
            setTmp2 = isSetIncludeDrink;
            isIncludeMain = false;
            isSetIncludeMain = false;
            isIncludeDrink = false;
            isSetIncludeDrink = false;
            // 餐吧打印面食
            titleNoodle = true;
            printAll(book, GConstants.PRINTER_NAME_FOOD);
            // 面吧打印面食
            strRet = printAll(book, GConstants.PRINTER_NAME_NOODLE);
            titleNoodle = false;
            isIncludeMain = tmp1;
            isSetIncludeMain = setTmp1;
            isIncludeDrink = tmp2;
            isSetIncludeDrink = setTmp2;
        }

        isIncludeMain = false;
        isSetIncludeMain = false;
        isIncludeDrink = false;
        isSetIncludeDrink = false;
        isIncludeNoodle = false;
        isSetIncludeNoodle = false;
        printEntity = null;
        return strRet;
    }

    private static String printAll(Book book, String printerName) {
        // 获取打印服务对象
        PrinterJob job = PrinterJob.getPrinterJob();

        // log.debug("调用打印机服务" + PrintTicket.class);
        PrintService[] serviceArr = job.lookupPrintServices();

        try {
            String printServerName = "";
            for (int i = 0; i < serviceArr.length; i++) {
                System.out.println(serviceArr[i].getName());
                if (printerName.equals(serviceArr[i].getName())) {
                    job.setPrintService(serviceArr[i]);
                    printServerName = serviceArr[i].getName();
                    break;
                }
            }
            // log.debug("判断打印机名" + PrintTicket.class);
            if (printServerName != "") {
                // log.debug("打印 go " + PrintTicket.class);
                job.setPageable(book);
                job.print();
                return GConstants.STATUS_CODE_2000;
            }
            // log.debug("打印机没有找到。" + PrintTicket.class);
            return GConstants.STATUS_CODE_2001;

        } catch (PrinterException e) {
            log.error("打印小票异常：\n" + e.getMessage() + PrintTicket.class);
            return GConstants.STATUS_CODE_4002;
        }
    }

    /**
     * @param graphics   指明打印的图形环境
     * @param pageFormat 指明打印页格式
     *                   （页面大小以点为计量单位，1点为1英才的1/72，1英寸为25.4毫米。A4纸大致为595× 842点）
     * @param pageIndex  指明页号
     **/
    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
            throws PrinterException {
        // 转换成Graphics2D 拿到画笔
        Graphics2D g2 = (Graphics2D) graphics;
        // 设置打印颜色为黑色
        g2.setColor(Color.black);

        // 打印起点坐标
        x = pageFormat.getImageableX() + 5;
        y = pageFormat.getImageableY() + 20;

        // 设置打印字体（字体名称、样式和点大小）（字体名称可以是物理或者逻辑名称）
        font = new Font("宋体", Font.BOLD, 16);
        g2.setFont(font);// 设置字体
        float height = font.getSize2D();// 字体高度

        // 标题
        g2.drawString("香港航空", (float) x + 60, (float) y);
        y += height;
        // 标题
        g2.drawString("Premium VIP Lounge", (float) x + 10, (float) y);
        // 订单里有餐食
        if (titleMain) {
            y += height;
            // 标题:餐吧
            g2.drawString("餐吧", (float) x + 70, (float) y);
        }
        // 订单里有饮料
        if (titleDrink) {
            y += height;
            // 标题:水吧
            g2.drawString("水吧", (float) x + 70, (float) y);
        }
        // 订单里有面食
        if (titleNoodle) {
            y += height;
            // 标题:面吧
            g2.drawString("面吧", (float) x + 70, (float) y);
        }
        font = new Font("宋体", Font.PLAIN, 11);
        g2.setFont(font);// 设置字体
        height = font.getSize2D();// 字体高度
        y += height * 2;
        // 地点
        g2.drawString("地點:" + printEntity.getOfficeName(), (float) x, (float) y);

        y += height;

        Date date = new Date();
        SimpleDateFormat sFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
        // 员工
        g2.drawString("員工:" + printEntity.getSysName(), (float) x, (float) y);
        // 时间
        g2.drawString(sFormat.format(date), (float) x + 90, (float) y);

        y += height;
        g2.drawString("-------------------------------------", (float) x,
                (float) y);

        font = new Font("宋体", Font.BOLD, 13);
        g2.setFont(font);// 设置字体
        height = font.getSize2D();// 字体高度
        y += height;
        // 显示台号
        g2.drawString(
                "台號:"
                        + printEntity.getOrderList().get(0).getTableArea()
                        + "-"
                        + String.format(
                        "%02d",
                        Integer.parseInt(printEntity.getOrderList()
                                .get(0).getSeatNum())), (float) x - 3,
                (float) y);

        List<OrderEntity> orderList = printEntity.getOrderList();

        font = new Font("宋体", Font.BOLD, 13);
        g2.setFont(font);// 设置字体
        height = font.getSize2D();// 字体高度
        y += height;

        // 显示客户名称
        g2.drawString(orderList.get(0).getNickName(), (float) x, (float) y);

        for (int i = 0; i < orderList.size(); i++) {

            font = new Font("宋体", Font.PLAIN, 10);
            g2.setFont(font);// 设置字体
            height = font.getSize2D();// 字体高度
            // 打印菜单
            // 如果是套餐
            if ("1".equals(orderList.get(i).getSetType())) {
                if (isSetIncludeMain) {
                    boolean printThisSet = false;
                    for (SubFoodEntity subFoodEntity : orderList.get(i)
                            .getFoodNameList()) {
                        if ("0".equals(subFoodEntity.getFoodType())) {
                            printThisSet = true;
                        }
                    }
                    if (printThisSet) {
                        y += height;
                        // 打印菜单名
                        setFoodNameFormat(orderList.get(i), g2, height);

                        g2.drawString(" * " + orderList.get(i).getFoodNum(),
                                (float) x + 160, (float) y);

                        // 获取口味
                        String foodPre = getFoodPre(orderList.get(i));
                        if (foodPre != "") {
                            setFoodPreFormat(foodPre, g2, height);
                        }

                        // 循环子菜单
                        for (SubFoodEntity subFoodEntity : orderList.get(i)
                                .getFoodNameList()) {
                            if ("0".equals(subFoodEntity.getFoodType())) {
                                setSubFoodNameFormat(subFoodEntity.getFoodName(), g2, height);
                            }
                        }
                    }
                } else if (isSetIncludeDrink) {
                    boolean printThisSet = false;
                    for (SubFoodEntity subFoodEntity : orderList.get(i)
                            .getFoodNameList()) {
                        if ("1".equals(subFoodEntity.getFoodType())) {
                            printThisSet = true;
                        }
                    }
                    if (printThisSet) {
                        y += height;
                        // 打印菜单名
                        setFoodNameFormat(orderList.get(i), g2, height);

                        g2.drawString(" * " + orderList.get(i).getFoodNum(),
                                (float) x + 160, (float) y);

                        // 获取口味
                        String foodPre = getFoodPre(orderList.get(i));
                        if (foodPre != "") {
                            setFoodPreFormat(foodPre, g2, height);
                        }

                        // 循环子菜单
                        for (SubFoodEntity subFoodEntity : orderList.get(i)
                                .getFoodNameList()) {
                            if ("1".equals(subFoodEntity.getFoodType())) {
                                setSubFoodNameFormat(subFoodEntity.getFoodName(), g2, height);
                            }
                        }
                    }
                } else if (isSetIncludeNoodle) {
                    boolean printThisSet = false;
                    for (SubFoodEntity subFoodEntity : orderList.get(i)
                            .getFoodNameList()) {
                        if ("3".equals(subFoodEntity.getFoodType())) {
                            printThisSet = true;
                        }
                    }
                    if (printThisSet) {
                        y += height;
                        // 打印菜单名
                        setFoodNameFormat(orderList.get(i), g2, height);

                        g2.drawString(" * " + orderList.get(i).getFoodNum(),
                                (float) x + 160, (float) y);

                        // 获取口味
                        String foodPre = getFoodPre(orderList.get(i));
                        if (foodPre != "") {
                            setFoodPreFormat(foodPre, g2, height);
                        }

                        // 循环子菜单
                        for (SubFoodEntity subFoodEntity : orderList.get(i)
                                .getFoodNameList()) {
                            if ("3".equals(subFoodEntity.getFoodType())) {
                                setSubFoodNameFormat(subFoodEntity.getFoodName(), g2, height);
                            }
                        }
                    }
//                } else {
//                    y += height;
//                    // 显示套餐名称
//                    // 打印菜单名
//                    setFoodNameFormat(orderList.get(i), g2, height);
//
//                    g2.drawString(" * " + orderList.get(i).getFoodNum(),
//                            (float) x + 160, (float) y);
//
//                    // 获取口味
//                    String foodPre = getFoodPre(orderList.get(i));
//                    if (foodPre != "") {
//                        setFoodPreFormat(foodPre, g2, height);
//                    }
//
//                    // 循环子菜单
//                    for (SubFoodEntity subFoodEntity : orderList.get(i)
//                            .getFoodNameList()) {
//                        setSubFoodNameFormat(subFoodEntity.getFoodName(), g2, height);
//                    }
                }
            } else {
                if (isIncludeMain) {
                    y += height;
                    // 只打印餐食
                    if ("0".equals(orderList.get(i).getFoodType())) {
                        // 显示套餐名称
                        setFoodNameFormat(orderList.get(i), g2, height);

                        g2.drawString(" * " + orderList.get(i).getFoodNum(),
                                (float) x + 160, (float) y);
                        // 获取口味
                        String foodPre = getFoodPre(orderList.get(i));
                        if (foodPre != "") {
                            setFoodPreFormat(foodPre, g2, height);
                        }
                    }
                } else if (isIncludeDrink) {
                    y += height;
                    // 只打印饮料
                    if ("1".equals(orderList.get(i).getFoodType())) {
                        // 显示套餐名称
                        setFoodNameFormat(orderList.get(i), g2, height);

                        g2.drawString(" * " + orderList.get(i).getFoodNum(),
                                (float) x + 160, (float) y);
                        // 获取口味
                        String foodPre = getFoodPre(orderList.get(i));
                        if (foodPre != "") {
                            setFoodPreFormat(foodPre, g2, height);
                        }
                    }
                } else if (isIncludeNoodle) {
                    y += height;
                    // 只打印面食
                    if ("3".equals(orderList.get(i).getFoodType())) {
                        // 显示套餐名称
                        setFoodNameFormat(orderList.get(i), g2, height);

                        g2.drawString(" * " + orderList.get(i).getFoodNum(),
                                (float) x + 160, (float) y);
                        // 获取口味
                        String foodPre = getFoodPre(orderList.get(i));
                        if (foodPre != "") {
                            setFoodPreFormat(foodPre, g2, height);
                        }
                    }
                } else if (isIncludeMain || isIncludeDrink || isIncludeNoodle) {
                    y += height;
                    // 显示套餐名称
                    setFoodNameFormat(orderList.get(i), g2, height);
                    g2.drawString(" * " + orderList.get(i).getFoodNum(),
                            (float) x + 160, (float) y);
                    // 获取口味
                    String foodPre = getFoodPre(orderList.get(i));
                    if (foodPre != "") {
                        setFoodPreFormat(foodPre, g2, height);
                    }
                } else if (!isSetIncludeMain && !isSetIncludeDrink && !isSetIncludeNoodle) {
                    y += height;
                    // 显示套餐名称
                    setFoodNameFormat(orderList.get(i), g2, height);
                    g2.drawString(" * " + orderList.get(i).getFoodNum(),
                            (float) x + 160, (float) y);
                    // 获取口味
                    String foodPre = getFoodPre(orderList.get(i));
                    if (foodPre != "") {
                        setFoodPreFormat(foodPre, g2, height);
                    }
                }
            }
        }

        y += height;
        g2.drawString("", (float) x, (float) y);

        y += height;
        g2.drawString("-------------------------------------", (float) x,
                (float) y);

        y += height;
        // 空行
        g2.drawString("", (float) x, (float) y);
        y += height;
        // 空行

        g2.drawString("Ref No."
                        + printEntity.getOrderList().get(0).getOrderTime()
                        + printEntity.getOrderList().get(0).getOrderId(), (float) x,
                (float) y);

        switch (pageIndex) {
            case 0:

                return PAGE_EXISTS;
            default:
                return NO_SUCH_PAGE;

        }
    }


    /**
     * 打印菜单名字
     **/
    private void setFoodNameFormat(OrderEntity orderEntity, Graphics2D g2, float height) {
        // 如果名字过长截位
        if (orderEntity.getFoodName().length() >= 25) {
            String[] arrayName = subString(orderEntity
                    .getFoodName());
            y += height;
            // 显示套餐名称
            g2.drawString(" -" + arrayName[0], (float) x, (float) y);

            for (int j = 1; j < arrayName.length; j++) {
                y += height;
                g2.drawString("  " + arrayName[j], (float) x,
                        (float) y);
            }
        } else {
            y += height;
            // 显示套餐名称
            g2.drawString(" -" + orderEntity.getFoodName(),
                    (float) x, (float) y);
        }
    }


    /**
     * 打印口味名字
     **/
    private void setFoodPreFormat(String foodPre, Graphics2D g2, float height) {
        // 如果字符长度大于25
        if (foodPre.length() > 25) {
            // 根据25截位
            String[] arryName = subString(foodPre);
            y += height;
            // 显示口味第一组
            g2.drawString("  (" + arryName[0], (float) x + 10,
                    (float) y);
            // 循环剩下的口味
            for (int j = 1; j < arryName.length; j++) {
                // 最后一组口味加右括号
                if (j == arryName.length - 1) {
                    y += height;
                    g2.drawString(arryName[j] + ")",
                            (float) x + 10, (float) y);
                } else {
                    y += height;
                    g2.drawString("  " + arryName[j],
                            (float) x + 10, (float) y);
                }
            }
        } else {
            y += height;
            //
            g2.drawString("  ( " + foodPre + ")", (float) x + 10,
                    (float) y);
        }
    }

    /**
     * 打印子菜单名字
     **/
    private void setSubFoodNameFormat(String foodName, Graphics2D g2, float height) {
        // 如果名字过长截位
        if (foodName.length() >= 25) {
            String[] arrayName = subString(foodName);
            // 显示套餐名称
            for (int j = 0; j < arrayName.length; j++) {
                y += height;
                g2.drawString("   " + arrayName[j], (float) x,
                        (float) y);
            }
        } else {
            y += height;
            // 显示套餐名称
            g2.drawString("   " + foodName, (float) x, (float) y);
        }
    }


    private String getFoodPre(OrderEntity orderEntity) {
        String foodPre = "";
        List<String> foodPreList = orderEntity.getFoodPreList();
        if (foodPreList != null && foodPreList.size() != 0) {
            for (String strFoodPre : foodPreList) {
                foodPre += strFoodPre + " ";
            }
        }
        if (orderEntity.getRemark() != null && orderEntity.getRemark() != "") {
            foodPre = foodPre + orderEntity.getRemark() + " ";
        }

        return foodPre;
    }


    private String[] subString(String name) {
        String str = WordUtils.wrap(name, 25, null, true);
        return str.split("\n");
    }
}