package com.mortals.xhx.module.demo.print;

import com.mortals.framework.util.StringUtils;

import javax.print.DocPrintJob;
import javax.print.PrintService;
import java.awt.*;
import java.awt.print.*;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class ThermalPrinter implements Printable {


    private YcCustSale custSale;

    private List<YcCustSaleDetail> custSaleDetailList;

    private YcStore ycStore;

    private YcUser ycUser;

    /**
     * 页面布局
     */
    @Override
    public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (page > 0) {
            return NO_SUCH_PAGE;
        }
        AtomicInteger flag = null;
        Graphics2D g2d = (Graphics2D) g;
        g2d.setFont(new Font("Tahoma", Font.PLAIN, 9));
        if (this.ycStore != null && ycUser != null && custSale != null) {
            g2d.drawString("欢迎光临" + this.ycStore.getStoreName(), 14, 10);
            try {
                g2d.drawString("机台名称：" + InetAddress.getLocalHost().getHostName().toString(), 14, 20);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            g2d.drawString("收银员：" + ycUser.getLoginName(), 14, 30);
            int wordWrap = wordWrap(g2d, "流水号：" + custSale.getId(), new AtomicInteger(40), 24);
            flag = new AtomicInteger(wordWrap);
        }
        g2d.drawString("------------------销-----售-----------------------", 7, flag.getAndAdd(20));
        g2d.drawString("货号    品名    单价    数量     金额", 14, flag.getAndAdd(10));
        if (custSaleDetailList != null && custSaleDetailList.size() > 0) {
            for (int i = 0; i < custSaleDetailList.size(); i++) {
                if (custSaleDetailList.get(i) != null
                        && StringUtils.isNotBlank(custSaleDetailList.get(i).getGoodsCode())) {
                    String data = custSaleDetailList.get(i).getSalePrice() + "     "
                            + custSaleDetailList.get(i).getNum() + "     " + custSaleDetailList.get(i).getTotalPrice();
                    g2d.drawString(custSaleDetailList.get(i).getGoodsCode(), 13, flag.getAndAdd(10));//商品条码
                    int wordWrap2 = wordWrap(g2d, "      " + custSaleDetailList.get(i).getGoodsName(), flag, 17);//商品名称
                    flag = new AtomicInteger(wordWrap2 + 10);
                    //设置价格对齐
                    if (data.length() > 28) {
                        int wordWrap = wordWrap(g2d, data, flag, 28);
                        flag = new AtomicInteger(wordWrap);
                    } else {
                        g2d.drawString("" + custSaleDetailList.get(i).getSalePrice(), 55, flag.get());
                        g2d.drawString("" + custSaleDetailList.get(i).getNum(), 85, flag.get());
                        g2d.drawString("" + custSaleDetailList.get(i).getTotalPrice(), 110, flag.get());
                        flag.getAndAdd(10);
                    }
                }
            }
        }
        g2d.drawString("------------------------------------------------", 7, flag.getAndAdd(20));
        if (custSale != null && ycStore != null) {
            g2d.drawString(custSale.getTotalPrice() == null ? "合计   0.00" : "合计   " + custSale.getTotalPrice(), 13, flag.getAndAdd(10));
            g2d.drawString(custSale.getNum() == null ? "总数   0" : "总数   " + custSale.getNum(), 13, flag.getAndAdd(10));
            g2d.drawString(custSale.getSsPrice() == null ? "应付    0.00" : "应付   " + custSale.getYsPrice(), 13, flag.getAndAdd(10));
            g2d.drawString(custSale.getYhPrice() == null ? "实收   0.00" : "实收   " + custSale.getSsPrice(), 13, flag.getAndAdd(10));
            g2d.drawString(custSale.getYhPrice() == null ? "优惠   0.00" : "优惠   " + custSale.getYhPrice(), 13, flag.getAndAdd(10));
            g2d.drawString(StringUtils.isNotBlank(custSale.getMemberPhone()) ? "会员   " + custSale.getMemberPhone() : "会员   ", 13, flag.getAndAdd(10));
            g2d.drawString("积分   " + custSale.getMemberScore(), 13, flag.getAndAdd(10));
            g2d.drawString(custSale.getZlPrice() == null ? "找零   0.00" : "找零   " + custSale.getZlPrice(), 13, flag.getAndAdd(10));
            g2d.drawString("------------------------------------------------", 7, flag.getAndAdd(20));
            //g2d.drawString("支付方式   " + PayTypeEnum.getValue(custSale.getPayType()), 13, flag.getAndAdd(10));
            g2d.drawString("交易时间   " + sdf.format(custSale.getCreateDate()), 13, flag.getAndAdd(10));
            g2d.drawString("送货电话   " + ycStore.getPhone(), 13, flag.getAndAdd(10));
            int rowFlag = wordWrap(g2d, "地址   " + ycStore.getAddress(), new AtomicInteger(flag.get()), 17);
            g2d.drawString("   谢谢惠顾！欢迎再次光临本店！", 13, rowFlag);
        }
        return PAGE_EXISTS;
    }

    /**
     * 开启打印
     */
    public void printData() {
        int height = 200 + 3 * 15 + 60;
        if (custSaleDetailList != null && custSaleDetailList.size() > 0) {
            height = 200 + custSaleDetailList.size() * 40 + 60;
        }
        // 通俗理解就是书、文档
        Book book = new Book();
        // 打印格式
        PageFormat pf = new PageFormat();
        pf.setOrientation(PageFormat.PORTRAIT);
        // 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
        Paper p = new Paper();
        p.setSize(230, height);
        p.setImageableArea(5, -20, 230, height + 20);
        pf.setPaper(p);
        // 把 PageFormat 和 Printable 添加到书中，组成一个页面
        book.append(this, pf);
        // 获取打印服务对象
        PrintService[] printServices = PrinterJob.lookupPrintServices();

        for (int i = 0; i < printServices.length; i++) {
            PrintService printService = printServices[i];


            DocPrintJob printJob = printService.createPrintJob();

        }
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPageable(book);
        try {
            job.print();
        } catch (PrinterException e) {
            System.out.println("================打印出现异常");
        }
    }

    /**
     * 自动换行
     *
     * @param g2d          构图对象
     * @param data         打印的数据
     * @param rowNum       当前行数
     * @param characterNum 字符换行数
     * @return
     */
    public int wordWrap(Graphics2D g2d, String data, AtomicInteger rowNum, Integer characterNum) {
        if (data.length() < 15) {
            int andAdd = rowNum.getAndAdd(10);
            g2d.drawString(data, 14, andAdd);
            return andAdd;
        } else {
            int num = rowNum.get();
            // 将字符串转变为指定长度的字符串集合
            List<String> strList = getStrList(data, characterNum);
            if (strList != null && strList.size() > 0) {
                for (String wrapData : strList) {
                    g2d.drawString(wrapData, 14, rowNum.getAndAdd(10));
                    num += 10;
                }
            }
            return num;
        }
    }

    /**
     * 把原始字符串分割成指定长度的字符串列表
     *
     * @param inputString 原始字符串
     * @param length      指定长度
     * @return
     */
    public List<String> getStrList(String inputString, int length) {
        int size = inputString.length() / length;
        if (inputString.length() % length != 0) {
            size += 1;
        }
        return getStrList(inputString, length, size);
    }

    /**
     * 把原始字符串分割成指定长度的字符串列表
     *
     * @param inputString 原始字符串
     * @param length      指定长度
     * @param size        指定列表大小
     * @return
     */
    public List<String> getStrList(String inputString, int length, int size) {
        List<String> list = new ArrayList<String>();
        for (int index = 0; index < size; index++) {
            String childStr = substring(inputString, index * length, (index + 1) * length);
            list.add(childStr);
        }
        return list;
    }

    /**
     * 分割字符串，如果开始位置大于字符串长度，返回空
     *
     * @param str 原始字符串
     * @param f   开始位置
     * @param t   结束位置
     * @return
     */
    public String substring(String str, int f, int t) {
        if (f > str.length())
            return null;
        if (t > str.length()) {
            return str.substring(f, str.length());
        } else {
            return str.substring(f, t);
        }
    }


    @SuppressWarnings({"unused", "resource"})
    public boolean printTest(String ip, int port, String str, String code, int skip) throws Exception {
        Socket client = new java.net.Socket();
        PrintWriter socketWriter;
        client.connect(new InetSocketAddress(ip, port), 1000); // 创建一个 socket
        socketWriter = new PrintWriter(client.getOutputStream());// 创建输入输出数据流
        /* 纵向放大一倍 */
        socketWriter.write(0x1c);
        socketWriter.write(0x21);
        socketWriter.write(8);
        socketWriter.write(0x1b);
        socketWriter.write(0x21);
        socketWriter.write(8);
        socketWriter.println(str);
        // 打印条形码
        socketWriter.write(0x1d);
        socketWriter.write(0x68);
        socketWriter.write(120);
        socketWriter.write(0x1d);
        socketWriter.write(0x48);
        socketWriter.write(0x01);
        socketWriter.write(0x1d);
        socketWriter.write(0x6B);
        socketWriter.write(0x02);
        socketWriter.println(code);
        socketWriter.write(0x00);
        for (int i = 0; i < skip; i++) {
            socketWriter.println(" ");// 打印完毕自动走纸
        }
        return true;
    }

    public YcCustSale getCustSale() {
        return custSale;
    }

    public void setCustSale(YcCustSale custSale) {
        this.custSale = custSale;
    }

    public List<YcCustSaleDetail> getCustSaleDetailList() {
        return custSaleDetailList;
    }

    public void setCustSaleDetailList(List<YcCustSaleDetail> custSaleDetailList) {
        this.custSaleDetailList = custSaleDetailList;
    }

    public YcStore getYcStore() {
        return ycStore;
    }

    public void setYcStore(YcStore ycStore) {
        this.ycStore = ycStore;
    }

    public YcUser getYcUser() {
        return ycUser;
    }

    public void setYcUser(YcUser ycUser) {
        this.ycUser = ycUser;
    }
}