package com.gingersoft.gsa.cloud.print;

import android.util.Log;

import com.gingersoft.gsa.cloud.common.constans.PrintConstans;
import com.gingersoft.gsa.cloud.common.logan.LoganManager;
import com.gingersoft.gsa.cloud.common.printer.plugins.PrinterPlugins;
import com.gingersoft.gsa.cloud.common.utils.other.TextUtil;
import com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean;
import com.scwang.smartrefresh.layout.listener.OnStateChangedListener;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.List;

/**
 * 打印Socket
 */
public class PrintSocketHolder {

    private final static PrintSocketHolder printSocketHolder = new PrintSocketHolder();

    public static PrintSocketHolder getInstance() {
        synchronized (printSocketHolder) {
            return printSocketHolder;
        }
    }

    protected final String TAG = this.getClass().getSimpleName();

    public static final int STATE_0 = 10;// 生成测试页面数据
    public static final int STATE_1 = 1;// 创建Socket连接
    public static final int STATE_2 = 2;// 获取输出流
    public static final int STATE_3 = 3;// 写入测试页面数据
    public static final int STATE_4 = 4;// 关闭输出流
    public static final int ERROR_0 = 0;// 成功
    public static final int ERROR_1 = -1;// 生成测试页面数据失败
    public static final int ERROR_2 = -2;// 创建Socket失败，未連接到打印機
    public static final int ERROR_3 = -3;// 获取输出流失败
    public static final int ERROR_4 = -4;// 写入测试页面数据失败
    public static final int ERROR_5 = -5;// 必要参数不能为空
    public static final int ERROR_6 = -6;// 关闭Socket出错
    public static final int ERROR_100 = -100;// 失败

    private Socket socket;
    private OutputStream out;
    private WeakReference<OnStateChangedListener> mListener;

    private PrintSocketHolder() {
    }

    public int createSocket(String ip, int port) {
        onPrinterStateChanged(STATE_1);
        if (TextUtil.isEmptyOrNullOrUndefined(ip)) {
            return ERROR_5;
        }
        try {
            PrinterPlugins.getOnPrinterFlowHandler().connectionBefore("網絡打印機", ip, port, PrintConstans.SO_TIMEOUT, PrintConstans.PRINT_TIMEOUT);
            socket = new Socket();
            //建立連接
            InetSocketAddress socketAddress = new InetSocketAddress(ip, port);
            //设置超时时间
            socket.setSoTimeout(PrintConstans.SO_TIMEOUT);
            //开始连接ip
            socket.connect(socketAddress, PrintConstans.PRINT_TIMEOUT);
        } catch (SocketException e) {
            e.printStackTrace();
            PrinterPlugins.getOnPrinterFlowHandler().connectionError(e);
            return ERROR_2;
        } catch (IOException e) {
            e.printStackTrace();
            PrinterPlugins.getOnPrinterFlowHandler().connectionError(e);
            return ERROR_2;
        }
        return ERROR_0;
    }

    public int getOutputStream() {
        onPrinterStateChanged(STATE_2);
        try {
            out = socket.getOutputStream();
        } catch (IOException e) {
            closeSocket();
            PrinterPlugins.getOnPrinterFlowHandler().connectionError(e);
            return ERROR_3;
        }
        return ERROR_0;
    }

    /**
     * 是否連接
     */
    public boolean isSocketPrepared() {
        return socket != null && out != null;
    }

    /**
     * 發送數據
     *
     * @param data 需要發送的數據
     * @return 發送狀態：是否成功
     */
    public int sendData(List<byte[]> data) {
        onPrinterStateChanged(STATE_3);
        if (data == null || data.size() <= 0) {
            return ERROR_0;
        }
        for (byte[] item : data) {
            try {
                out.write(item);
                out.flush();
            } catch (IOException | NullPointerException e) {
                PrinterPlugins.getOnPrinterFlowHandler().onPrintError(e,ERROR_4);
                LoganManager.w_printer(TAG, "打印异常: " + e.getMessage());
                closeSocket();
                return ERROR_4;
            }
        }
        closeSocket();//成功後關閉連接
        return ERROR_0;
    }

    public int prepareSocket(String ip, int port) {
        LoganManager.w_printer(TAG, "准备尝试连接打印机" + ip + ":" + port);
        //創建連接
        int create = createSocket(ip, port);
        //判斷連接狀態
        if (create != PrintSocketHolder.ERROR_0) {
            return create;
        }
        //獲取打印機寫入
        int result = getOutputStream();
        if (result == ERROR_0) {
            PrinterPlugins.getOnPrinterFlowHandler().connectionSuccess();
        }
        return result;
    }

    /**
     * 销毁
     */
    public int closeSocket() {
        onPrinterStateChanged(STATE_4);
        boolean error = false;
        try {
            if (out != null) {
                out.close();
                out = null;
                LoganManager.w_printer(TAG, "关闭打印机輸出连接");
            }
        } catch (IOException e) {
            LoganManager.w_printer(TAG, "关闭打印机连接异常");
            out = null;
            error = true;
        }
        try {
            if (socket != null) {
                socket.close();
                socket = null;
                LoganManager.w_printer(TAG, "关闭打印机socket连接");
            }
        } catch (IOException e) {
            LoganManager.w_printer(TAG, "关闭打印机连接异常");
            socket = null;
            error = true;
        }
        PrinterPlugins.getOnPrinterFlowHandler().disconnect();
        return error ? ERROR_6 : ERROR_0;
    }

    /**
     * 打印状态变化
     *
     * @param state 打印状态
     */
    public void onPrinterStateChanged(int state) {
        try {
            if (mListener != null && mListener.get() != null) {
                mListener.get().onStateChanged(state);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置状态监听
     *
     * @param listener 监听
     */
    public void setOnStateChangedListener(OnStateChangedListener listener) {
        mListener = new WeakReference<>(listener);
    }

    public interface OnStateChangedListener {
        void onStateChanged(int state);
    }
}
