package com.gingersoft.gsa.cloud.print.newprint;

import android.bluetooth.BluetoothDevice;
import android.os.AsyncTask;

import com.gingersoft.gsa.cloud.common.logan.LoganManager;
import com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean;
import com.gingersoft.gsa.cloud.print.PrintDataMaker;
import com.gingersoft.gsa.cloud.print.PrintExecutor;
import com.gingersoft.gsa.cloud.print.PrintSocketHolder;

import java.util.List;

public class PrintUtil {

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

    private PrintSocketHolder holder;
    private int mReconnectTimes = 0;
    private int time = 0;
    private String prjIds;
    private PrintSocketHolder.OnStateChangedListener listener;
    private PrintExecutor.OnPrintResultListener mListener;
    private PrintExecutor.OnPrjPrintResultListener onPrjPrintResultListener;

    public PrintUtil() {
//        holder = new PrintSocketHolder(printerDeviceBean);
    }

    /**
     * 执行打印请求
     *
     * @return 错误代码
     */
    private int doRequest(PrintDataMaker maker) {
        LoganManager.w_printer(TAG,"PrintTask  doRequest");
        if (mReconnectTimes == 0) {
            holder.onPrinterStateChanged(PrintSocketHolder.STATE_0);
            List<byte[]> data = maker.getPrintData();
            prjIds = maker.getPrjIds();
            if (!holder.isSocketPrepared()) {
                int prepare = holder.prepareSocket();
                if (prepare != PrintSocketHolder.ERROR_0)
                    return prepare;
            }
            return holder.sendData(data);
        } else {
            holder.onPrinterStateChanged(PrintSocketHolder.STATE_0);
            List<byte[]> data = maker.getPrintData();
            prjIds = maker.getPrjIds();
            if (holder.isSocketPrepared()) {
                if (sendData(data))
                    return PrintSocketHolder.ERROR_0;
                else
                    return PrintSocketHolder.ERROR_100;
            } else {
                if (prepareSocket() && sendData(data)) {
                    return PrintSocketHolder.ERROR_0;
                } else {
                    return PrintSocketHolder.ERROR_100;
                }
            }
        }
    }

    /**
     * 执行打印请求
     *
     * @return 错误代码
     */
    public int doPrinterRequest(PrintDataMaker maker) {
        holder.setOnStateChangedListener(listener);
        return doRequest(maker);
    }

    private boolean prepareSocket() {
        time++;
        return time < mReconnectTimes &&
                (holder.prepareSocket() == PrintSocketHolder.ERROR_0 || prepareSocket());
    }

    private boolean sendData(List<byte[]> data) {
        if (holder.sendData(data) == PrintSocketHolder.ERROR_0) {
            LoganManager.w_printer(TAG,"PrintTask  sendData(List<byte[]> data) -------------打印完成------------------>");
            time = 0;
            return true;
        } else {
            LoganManager.w_printer(TAG,"PrintTask  sendData(List<byte[]> data) -------------递归打印------------------>");
            return prepareSocket() && sendData(data);
        }
    }

    /**
     * 异步执行打印请求
     */
    public void doPrinterRequestAsync(PrintDataMaker maker) {
//        new PrintExecutor.PrintTask().execute(maker);
    }

    /**
     * 销毁
     */
    public int closeSocket() {
        return holder.closeSocket();
    }

    /**
     * 设置IP及端口
     */
    public void setIp(PrinterDeviceBean printerDeviceBean) {
        holder.setIp(printerDeviceBean);
    }

    /**
     * 设置蓝牙
     *
     * @param device 设备
     */
    public void setDevice(BluetoothDevice device) {
        holder.setDevice(device);
    }

    /**
     * 设置状态监听
     *
     * @param listener 监听
     */
    public void setOnStateChangedListener(PrintSocketHolder.OnStateChangedListener listener) {
        this.listener = listener;
    }

    /**
     * 设置重连次数
     *
     * @param times 次数
     */
    public void setReconnectTimes(int times) {
        mReconnectTimes = times;
    }

    /**
     * 设置结果回调
     *
     * @param listener 回调
     */
    public void setOnPrintResultListener(PrintExecutor.OnPrintResultListener listener) {
        this.mListener = listener;
    }

    public interface OnPrintResultListener {
        void onResult(int errorCode, PrinterDeviceBean printerDeviceBean);
    }

    /**
     * PRJ打印結果回調
     */
    public interface OnPrjPrintResultListener {
        void onResult(int errorCode, String ids);
    }

    public void setOnPrjPrintResultListener(PrintExecutor.OnPrjPrintResultListener onPrjPrintResultListener) {
        this.onPrjPrintResultListener = onPrjPrintResultListener;
    }

    private class PrintTask extends AsyncTask<PrintDataMaker, Integer, Integer> implements
            PrintSocketHolder.OnStateChangedListener {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            holder.setOnStateChangedListener(this);
        }

        @Override
        protected Integer doInBackground(PrintDataMaker... makers) {
            if (makers == null || makers.length < 1)
                return PrintSocketHolder.ERROR_0;
            return doRequest(makers[0]);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if (values == null || values.length < 1)
                return;
            if (listener != null)
                listener.onStateChanged(values[0], holder.getPrinterDeviceBean());
        }

        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);
            if (integer != null) {
                onResult(integer);
            }
        }

        /**
         * 打印结果
         *
         * @param errorCode 错误代码
         */
        private void onResult(int errorCode) {
            try {
                if (mListener != null)
                    mListener.onResult(errorCode, holder.getPrinterDeviceBean());
                if (onPrjPrintResultListener != null) {
                    onPrjPrintResultListener.onResult(errorCode, prjIds);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

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