package com.sy.coinage.util.printer;

import com.alibaba.fastjson.JSONObject;
import com.sy.coinage.util.Common;
import com.sy.coinage.util.RfidEpcTool;
import com.zebra.sdk.comm.Connection;
import com.zebra.sdk.comm.ConnectionException;
import com.zebra.sdk.comm.TcpConnection;
import com.zebra.sdk.printer.PrinterStatus;
import com.zebra.sdk.printer.ZebraPrinter;
import com.zebra.sdk.printer.ZebraPrinterFactory;
import lombok.extern.slf4j.Slf4j;

import java.awt.image.BufferedImage;
import java.io.UnsupportedEncodingException;

/**
 *   zpl打印工具类，采用
 */
@Slf4j
public class ZplImgConvertPrinter {

    private static String DEFAULT_IP_ADDRESS ="192.168.6.228";
    private static Integer DEFAULT_PORT = 9100; // 默认9100端口


    /**
     *
     * @param rfidInfoDTO
     */
    public static  void printZpl( RfidInfoDTO rfidInfoDTO)  throws ConnectionException {

        Connection thePrinterConn = new TcpConnection(DEFAULT_IP_ADDRESS, TcpConnection.DEFAULT_ZPL_TCP_PORT);

        try {
            // Open the connection - physical connection is established here.
            thePrinterConn.open();

            // This example prints "This is a ZPL test." near the top of the label.
             //String zplData = "^XA^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^XZ";
//            String zplData ="^XA^WDE:*.*^XZ";
           String zplData = getZplData(rfidInfoDTO);
            log.info("===zplData is ：{}",zplData);
            // Send the data to printer as a byte array.
            thePrinterConn.write(zplData.getBytes());
        } catch (ConnectionException e) {
            // Handle communications error here.
            e.printStackTrace();
        } finally {
            // Close the connection to release resources.
            thePrinterConn.close();
        }

    }

    /**
     *  指定IP+PORT ,传入待打印数据对象，进行打印
     * @param ipAddress
     * @param portNumber
     * @param rfidInfoDTO
     * @throws ConnectionException
     */
    public static  boolean printZpl(String ipAddress, Integer portNumber, RfidInfoDTO rfidInfoDTO) throws ConnectionException {

        boolean flag = false;
        Connection thePrinterConn = new TcpConnection(ipAddress, portNumber);

        try {
            // Open the connection - physical connection is established here.
            thePrinterConn.open();
            //add by hliu date=20240228,增加打印前的打印机状态的判断
            boolean isReadyToPrint = checkPrinterIsReadyToPrint(thePrinterConn);
            log.info(" printer is ReadyToPrint is :{}",isReadyToPrint);
            if(!isReadyToPrint){
                return false;
            }
            String zplData = getZplData(rfidInfoDTO);
            log.info("=2==zplData is ：{}",zplData);
            // Send the data to printer as a byte array.
            thePrinterConn.write(zplData.getBytes());
            flag = true;
        } catch (ConnectionException e) {
            // Handle communications error here.
            e.printStackTrace();
            log.error(" connet the printer is error:{}",e.getMessage());
            flag = false;
        } finally {
            // Close the connection to release resources.
            thePrinterConn.close();
        }

        return flag;

    }

    /**
     *  打印空白标签方法，即只进行打印rfid内容，其他内容留白
     * @throws ConnectionException
     */
    public static  void printBlankZpl(String ip,int port )  throws ConnectionException {

        Connection thePrinterConn = new TcpConnection(ip, port);

        try {
            // Open the connection - physical connection is established here.
            thePrinterConn.open();

            String zplData = getZplDataBlank();
            log.info("===zplData is ：{}",zplData);
            // Send the data to printer as a byte array.
            thePrinterConn.write(zplData.getBytes());
        } catch (ConnectionException e) {
            // Handle communications error here.
            e.printStackTrace();
        } finally {
            // Close the connection to release resources.
            thePrinterConn.close();
        }

    }

    /**
     * 根据对象获取完成的zplData信息
     * @param rfidInfoDTO
     * @return
     */
    private static String getZplData(RfidInfoDTO rfidInfoDTO){

        try {
            BufferedImage labelImg = ImageProducerUtil.createImage95_22(rfidInfoDTO);
//            String zplImg = Image2Zpl.image2Zpl(labelImg);
            String zplImgNoFootDoc = ImgToZpl.convertFromImgNoFootDoc(labelImg);//没有end

//            String zplData = zplImgNoFootDoc + footDoc();
            //当调整好样式后，可以将写入rfid与打印指令加入
           String zplData = zplImgNoFootDoc + getZplRfidAndPrintData(rfidInfoDTO) +footDoc();
           System.out.println(zplData);


            return zplData;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *   获取rfid写入与打印的指令内容
     * @param rfidInfoDTO
     * @return
     */
    private static String getZplRfidAndPrintData(RfidInfoDTO rfidInfoDTO){

        StringBuffer zplSb = new StringBuffer();
        String rfidHex = Common.bytesToHexString(rfidInfoDTO.getRfidEpc().getBytes());
        //写入指令
        zplSb.append("^RFW,H,,12,E^FD").append(rfidHex).append("^FS");
        //打印指令  打印数量1;当每个rfid标签打印2个，每个拷贝是1个
//        zplSb.append("^PQ1,0,1,Y"); //打印一张
        //打印两张
        zplSb.append("^PQ2,0,1,Y");

        return zplSb.toString();
    }


    /**
     * 打印空白标签，获取空白标签 zplData
     * @return
     */
    private static String getZplDataBlank(){

        try {
            //空白标签，都是按照部门9进行统一生成
            String rf = RfidEpcTool.buildEpcCode("9");

            log.info(" print blank tag ,rfid is : {} ",rf);

            BufferedImage labelImg = ImageProducerUtil.createImageBlank95_22(rf);
            String zplImgNoFootDoc = ImgToZpl.convertFromImgNoFootDoc(labelImg);//没有end

            //当调整好样式后，可以将写入rfid与打印指令加入
            String zplData = zplImgNoFootDoc + getZplRfidAndPrintDataBlank(rf) +footDoc();
            System.out.println(zplData);


            return zplData;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 获取打印机状态
     * @return
     */
    private static PrinterStatus getPrinterStatus(Connection connection){
        try {
            if (connection.isConnected()) {
                ZebraPrinter printer = ZebraPrinterFactory.getInstance(connection);

                PrinterStatus printerStatus = printer.getCurrentStatus();
                log.info(" printer current status is :{}", JSONObject.toJSONString(printerStatus));
                return printerStatus;
            }
        }catch (Exception ex){
            log.error("get current status printer is error! pls check printer !,error is :",ex.getMessage());
        }

        return null;
    }

    /**
     * 判断打印机当前状态是否可以打印
     * @param connection
     * @return
     */
    private static boolean  checkPrinterIsReadyToPrint(Connection connection){

        PrinterStatus printerStatus = getPrinterStatus(connection);
        if(printerStatus!=null && printerStatus.isReadyToPrint){
            return true;
        }
        return false;
    }

    /**
     * 空白标签每次只打印一张，写入rfid
     * @param rf
     * @return
     */
    private static String getZplRfidAndPrintDataBlank(String rf){


        StringBuffer zplSb = new StringBuffer();
        String rfidHex = Common.bytesToHexString(rf.getBytes());
        //写入指令
        zplSb.append("^RFW,H,,12,E^FD").append(rfidHex).append("^FS");
        //打印指令  打印数量1;当每个rfid标签打印2个，每个拷贝是1个
        zplSb.append("^PQ1,0,1,Y");

        return zplSb.toString();
    }

    private static String footDoc() {

        String str = "^FS" +
                "^XZ";
        return str;
    }


    public static void main(String args[]){

        try {
            RfidInfoDTO dtl = new RfidInfoDTO();
            dtl.setSecurities("Y225");
            dtl.setSerialNumber("IJ-0340");
            dtl.setTareWeight("54.0kg");
            dtl.setGrossWeight("1205kg");
            dtl.setWeightor("刘宏");
            dtl.setCrownBetween("佰21伍-003-0821 至 佰21伍-003-0880");
            dtl.setWeightTime("19:45:30");
            dtl.setWeightDate("2023-11-11");
            dtl.setRfidEpc("232-6xC6K4Uy");

            //发送指令给打印机
//           printZpl(dtl);
//            printBlankZpl(DEFAULT_IP_ADDRESS,DEFAULT_PORT);
            getZplDataBlank();
//           getZplData(dtl);
            System.out.println("print zpl image is ending...");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


}
