package com.stand.standapp.printer;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.CompoundButton;

import androidx.appcompat.app.AppCompatActivity;

import com.dp.dp_serialportlist.Serialport_Factory;
import com.stand.standapp.R;
import com.stand.standapp.AppConfig;

import java.io.IOException;
import java.io.InputStream;

public class PrintTestActivity extends AppCompatActivity implements View.OnClickListener {

    static {
        try {
            System.loadLibrary("szzkserialport");
        } catch (UnsatisfiedLinkError e) {
            e.printStackTrace();
        }
    }

    private Spinner spPortPath, spBaudrate;
    private EditText etManualPath;
    private CheckBox cbManualMode;
    private Button btnOpen;
    private TextView tvStatus;
    
    private Serialport_Factory sf;
    private String[] portNames;

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == Serialport_Factory.PAPER_STATE) {
                boolean hasPaper = msg.getData().getBoolean("PAPER_STATE");
                tvStatus.setText("打印机状态: " + (hasPaper ? "有纸" : "缺纸"));
                Toast.makeText(PrintTestActivity.this, hasPaper ? "打印机有纸" : "打印机缺纸", Toast.LENGTH_SHORT).show();
            }
            return true;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_printer_test);

        initViews();
        
        sf = Serialport_Factory.getSerialport_Factory(this, mHandler);
        
        // 预填配置好的串口地址
        String savedPort = AppConfig.INSTANCE.getSerialPort(this);
        etManualPath.setText(savedPort);
        
        loadSerialPorts();
    }

    private void initViews() {
        spPortPath = findViewById(R.id.sp_port_path);
        spBaudrate = findViewById(R.id.sp_baudrate);
        etManualPath = findViewById(R.id.et_manual_path);
        cbManualMode = findViewById(R.id.cb_manual_mode);
        btnOpen = findViewById(R.id.btn_open);
        tvStatus = findViewById(R.id.tv_status);

        cbManualMode.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                spPortPath.setVisibility(isChecked ? View.GONE : View.VISIBLE);
                etManualPath.setVisibility(isChecked ? View.VISIBLE : View.GONE);
            }
        });

        btnOpen.setOnClickListener(this);
        findViewById(R.id.btn_print_text).setOnClickListener(this);
        findViewById(R.id.btn_print_barcode).setOnClickListener(this);
        findViewById(R.id.btn_print_qr).setOnClickListener(this);
        findViewById(R.id.btn_print_img).setOnClickListener(this);
        findViewById(R.id.btn_print_column).setOnClickListener(this);
        findViewById(R.id.btn_print_demo1).setOnClickListener(this);
        findViewById(R.id.btn_print_demo2).setOnClickListener(this);
        findViewById(R.id.btn_print_alarm).setOnClickListener(this);
        findViewById(R.id.btn_print_test_page).setOnClickListener(this);
        findViewById(R.id.btn_check_paper).setOnClickListener(this);
        findViewById(R.id.btn_cut_all).setOnClickListener(this);
        findViewById(R.id.btn_back).setOnClickListener(this);
    }

    private void loadSerialPorts() {
        try {
            portNames = sf.getAllDevices();
            if (portNames != null && portNames.length > 0) {
                ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, portNames);
                adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                spPortPath.setAdapter(adapter);
            } else {
                Toast.makeText(this, "未检测到串口设备，请检查硬件权限", Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btn_open) {
            openPort();
        } else if (id == R.id.btn_back) {
            finish();
        } else {
            if (!sf.isConnection()) {
                Toast.makeText(this, "请先开启串口", Toast.LENGTH_SHORT).show();
                return;
            }
            handlePrintAction(id);
        }
    }

    private void openPort() {
        String path;
        if (cbManualMode.isChecked()) {
            path = etManualPath.getText().toString().trim();
        } else {
            if (spPortPath.getSelectedItem() == null) return;
            path = spPortPath.getSelectedItem().toString();
        }
        
        String baudrate = spBaudrate.getSelectedItem().toString();
        try {
            if (sf.OpenPort(path, baudrate)) {
                tvStatus.setText("状态: 已连接 (" + path + ")");
                tvStatus.setTextColor(0xFF4CAF50);
                Toast.makeText(this, "串口已开启", Toast.LENGTH_SHORT).show();
            } else {
                tvStatus.setText("状态: 连接失败");
                tvStatus.setTextColor(0xFFFF0000);
                Toast.makeText(this, "串口开启失败", Toast.LENGTH_SHORT).show();
            }
        } catch (Throwable e) {
            tvStatus.setText("状态: 驱动加载失败");
            tvStatus.setTextColor(0xFFFF0000);
            Toast.makeText(this, "串口驱动异常(可能缺少64位库): " + e.getMessage(), Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }

    private void handlePrintAction(int id) {
        if (id == R.id.btn_print_text) {
            sf.PrintText("StandAPP 打印测试", 2, 1, 30);
            sf.PrintText("文本内容居左测试", 1, 1, 20);
            sf.PaperCut();
        } else if (id == R.id.btn_print_barcode) {
            sf.PrintBarcode("88888888", 3, 100, 5, 2, 2);
            sf.PrintText("\n", 1, 1, 50);
            sf.PaperCut();
        } else if (id == R.id.btn_print_qr) {
            sf.PrintQR("StandAPP-Integrated", 6, 2);
            sf.PrintText("\n", 1, 1, 50);
            sf.PaperCut();
        } else if (id == R.id.btn_print_img) {
            Bitmap bm = getImageFromAssetsFile("1.jpg");
            if (bm != null) {
                sf.PrintImage(bm, 384, 0, 2);
                sf.PrintText("\n", 1, 1, 50);
                sf.PaperCut();
            }
        } else if (id == R.id.btn_print_column) {
            sf.Printcolumncontent("项目", 0, "单价", 180, "数量", 250, "金额", 320);
            sf.Printcolumncontent("测试商品", 0, "10.0", 180, "1", 250, "10.0", 320, 70);
            sf.PrintText("\n", 1, 1, 50);
            sf.PaperCut();
        } else if (id == R.id.btn_print_demo1) {
            printDemo(false);
        } else if (id == R.id.btn_print_demo2) {
            printDemo(true);
        } else if (id == R.id.btn_print_alarm) {
            printAlarmNotice();
        } else if (id == R.id.btn_print_test_page) {
            sf.PrintTestPage();
        } else if (id == R.id.btn_check_paper) {
            sf.Check_Paper();
        } else if (id == R.id.btn_cut_all) {
            sf.PaperAllCut();
        }
    }

    private void printAlarmNotice() {
        // 1. 标题
        sf.PrintText("警情通知单", 2, 2, 40);
        sf.PaperCut();
        // 2. 二维码 (居中)
        sf.PrintQR("ALARM_20260304172432", 7, 2);
        sf.PrintText("\n", 1, 1, 20);
        sf.PaperCut();
        // 3. 详情列表
        sf.PrintText("报警时间: 2026-03-04 17:24:32", 1, 1, 20);
        sf.PrintText("报警人: 张先生", 1, 1, 20);
        sf.PrintText("报警人电话: 18722727636", 1, 1, 20);
        sf.PrintText("灾害地址: 贵州省安顺市西秀区(赵家山村)宋旗镇赵家山村", 1, 1, 20);
        sf.PrintText("警情分类: 抢险救援", 1, 1, 20);
        sf.PrintText("报警描述: 车祸", 1, 1, 20);
        sf.PrintText("主管救援站联系电话: 0851-33410119", 1, 1, 20);
        sf.PrintText("出动车辆: ", 1, 1, 20);
        
        // 4. 分割线
        sf.PrintText("--------------------------------", 1, 1, 10);
        
        // 5. 注意事项
        sf.PrintText("注意事项:", 1, 1, 20);
        sf.PrintText("1、请专职消防队人员穿戴好防护装备，携带灭火、救援器材赶往现场科学处置。", 1, 1, 20);
        sf.PrintText("2、到达现场后及时上报情况，注意安全，做好个人防护和现场警戒。", 1, 1, 20);
        sf.PrintText("3、根据现场情况迅速组织人员疏散，并在确保安全的前提下利用灭火救援装备开展救援。", 1, 1, 20);
        sf.PrintText("4、待责任消防救援站力量到达现场后，主动与其汇报现场已知情况，并协助做好灭火救援工作。", 1, 1, 20);
        sf.PrintText("5、严格落实作战行动安全规定，防止触电、溺水、烧伤、坠落、中毒、砸伤、放射线等伤害。", 1, 1, 20);
        
        // 6. 结尾
        sf.PrintText("--------------------------------", 1, 1, 10);
        sf.PrintText("\n\n\n", 1, 1, 10);
        
        // 7. 切纸
        sf.PaperCut();
    }

    private void printDemo(boolean is3Inch) {
        int width = is3Inch ? 400 : 300;
        int right = is3Inch ? 120 : 100;
        sf.PrintText("\nStandAPP 业务测试单", 2, 1, 30);
        sf.PrintText("--------------------------------", 1, 1, 10);
        sf.Printcolumncontent("名称", 0, "单价", 180, "数量", 250, "金额", width);
        sf.Printcolumncontent("演示商品A", 0, "9.9", 180, "1", 250, "9.90", width, right);
        sf.PrintText("--------------------------------", 1, 1, 10);
        sf.PrintQR("http://www.standapp.com", 6, 2);
        sf.PrintText("\n\n\n", 1, 1, 10);
        sf.PaperCut();
    }

    private Bitmap getImageFromAssetsFile(String fileName) {
        try {
            InputStream is = getAssets().open(fileName);
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            is.close();
            return bitmap;
        } catch (IOException e) {
            return null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (sf != null) sf.Disconnect();
    }
}
