package cc.winboll.studio.apputils;

/**
 * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/01/18 10:32:21
 * @Describe 二维码解码窗口
 */
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toolbar;
import cc.winboll.studio.apputils.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.common.HybridBinarizer;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.journeyapps.barcodescanner.DefaultDecoderFactory;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

public class QRCodeDecodeActivity extends Activity {

    public static final String TAG = "QRCodeDecodeActivity";
    public static final String EXTRA_RESULT = "EXTRA_RESULT";
    private static final int REQUEST_CAMERA_PERMISSION = 1;
    private static final int REQUEST_PICK_IMAGE = 2;
    private static final int REQUEST_READ_STORAGE_PERMISSION = 3;
    // 图片压缩阈值：超过1000px时压缩，避免内存溢出和解码效率低
    private static final int MAX_BITMAP_SIZE = 1000;

    private TextView resultTextView;
    private DecoratedBarcodeView barcodeView;
    private Button btnDecodeFromAlbum;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qrcodedecode);
        initToolbar();
        initViews();
        checkCameraPermission();
        setAlbumDecodeClickListener();
    }

    private void initToolbar() {
        Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
        if (mToolbar != null) {
            setActionBar(mToolbar);
            if (getActionBar() != null) {
                getActionBar().setDisplayHomeAsUpEnabled(true);
                mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
						@Override
						public void onClick(View v) {
							finish();
						}
					});
            }
        }
    }

    private void initViews() {
        resultTextView = (TextView) findViewById(R.id.activityqrcodedecodeTextView1);
        barcodeView = (DecoratedBarcodeView) findViewById(R.id.activityqrcodedecodeDecoratedBarcodeView1);
        btnDecodeFromAlbum = (Button) findViewById(R.id.btn_decode_from_album);
        // 初始化扫码解码器（支持所有常见码制，避免仅支持QR_CODE的局限）
        List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>();
        formats.add(BarcodeFormat.QR_CODE);
        formats.add(BarcodeFormat.CODE_128);
        formats.add(BarcodeFormat.EAN_13);
        barcodeView.getBarcodeView().setDecoderFactory(new DefaultDecoderFactory(formats));
    }

    private void setAlbumDecodeClickListener() {
        btnDecodeFromAlbum.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {
						requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
										   REQUEST_READ_STORAGE_PERMISSION);
					} else {
						openAlbum();
					}
				}
			});
    }

    private void openAlbum() {
        Intent pickImageIntent = new Intent(Intent.ACTION_PICK);
        pickImageIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        startActivityForResult(pickImageIntent, REQUEST_PICK_IMAGE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_PICK_IMAGE && resultCode == RESULT_OK && data != null) {
            Uri selectedImageUri = data.getData();
            if (selectedImageUri != null) {
                try {
                    // 1. 读取图片并压缩（关键优化：避免大图片解码失败）
                    InputStream imageStream = getContentResolver().openInputStream(selectedImageUri);
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true; // 先获取图片尺寸，不加载像素
                    BitmapFactory.decodeStream(imageStream, null, options);
                    imageStream.close(); // 关闭流，重新读取

                    // 计算压缩比例：超过MAX_BITMAP_SIZE时按比例压缩
                    options.inSampleSize = calculateInSampleSize(options, MAX_BITMAP_SIZE, MAX_BITMAP_SIZE);
                    options.inJustDecodeBounds = false; // 开始加载压缩后的像素
                    imageStream = getContentResolver().openInputStream(selectedImageUri);
                    Bitmap originalBitmap = BitmapFactory.decodeStream(imageStream, null, options);
                    imageStream.close();

                    if (originalBitmap == null) {
                        showToast("图片损坏，无法解析");
                        return;
                    }

                    // 2. 图片预处理：转为灰度图+提高对比度（解决模糊/低对比度图片识别问题）
                    Bitmap processedBitmap = processBitmap(originalBitmap);

                    // 3. 解码预处理后的图片
                    String decodeResult = decodeQrFromBitmap(processedBitmap);

                    // 4. 结果处理
                    if (decodeResult != null && !decodeResult.isEmpty()) {
                        resultTextView.setText("图片解码结果：" + decodeResult);
                        showDecodeResultDialog(decodeResult);
                        returnResultToPreviousPage(decodeResult);
                    } else {
                        // 尝试直接解码原图（防止预处理过度导致识别失败）
                        String originalResult = decodeQrFromBitmap(originalBitmap);
                        if (originalResult != null && !originalResult.isEmpty()) {
                            resultTextView.setText("图片解码结果：" + originalResult);
                            showDecodeResultDialog(originalResult);
                            returnResultToPreviousPage(originalResult);
                        } else {
                            new AlertDialog.Builder(this)
								.setTitle("解码失败")
								.setMessage("图片中未识别到二维码/条码，建议选择清晰、完整的图片")
								.setPositiveButton("确定", new DialogInterface.OnClickListener() {
									@Override
									public void onClick(DialogInterface dialog, int which) {
										dialog.dismiss();
									}
								})
								.show();
                        }
                    }

                    // 回收Bitmap，避免内存泄漏
                    if (!originalBitmap.isRecycled()) originalBitmap.recycle();
                    if (!processedBitmap.isRecycled() && processedBitmap != originalBitmap) {
                        processedBitmap.recycle();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    showToast("图片处理失败：" + e.getMessage());
                }
            } else {
                showToast("未选择图片");
            }
        }
    }

    /**
     * 核心优化1：计算图片压缩比例
     */
    private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            // 找到最接近reqWidth/reqHeight的压缩比例（2的倍数，保证图片质量）
            while ((halfHeight / inSampleSize) >= reqHeight
				   && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    /**
     * 核心优化2：图片预处理（灰度化+提高对比度）
     * 解决模糊、低亮度、低对比度图片识别率低的问题
     */
    private Bitmap processBitmap(Bitmap bitmap) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        // 创建灰度图
        Bitmap grayBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(grayBitmap);
        Paint paint = new Paint();

        // 1. 灰度化矩阵
        ColorMatrix grayMatrix = new ColorMatrix();
        grayMatrix.setSaturation(0); // 饱和度设为0，转为灰度

        // 2. 提高对比度矩阵（alpha=1.5，亮度=0，可根据需求调整）
        ColorMatrix contrastMatrix = new ColorMatrix();
        contrastMatrix.set(new float[]{
							   1.5f, 0, 0, 0, 0,  // 红通道对比度
							   0, 1.5f, 0, 0, 0,  // 绿通道对比度
							   0, 0, 1.5f, 0, 0,  // 蓝通道对比度
							   0, 0, 0, 1f, 0     // alpha通道不变
						   });

        // 合并灰度+对比度矩阵
        ColorMatrix combinedMatrix = new ColorMatrix();
        combinedMatrix.postConcat(grayMatrix);
        combinedMatrix.postConcat(contrastMatrix);

        paint.setColorFilter(new ColorMatrixColorFilter(combinedMatrix));
        canvas.drawBitmap(bitmap, 0, 0, paint);

        return grayBitmap;
    }

    /**
     * 核心优化3：修复解码参数，支持更多场景
     */
    private String decodeQrFromBitmap(Bitmap bitmap) {
        if (bitmap == null) return null;

        try {
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int[] pixels = new int[width * height];
            bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

            // 修复1：使用RGBLuminanceSource，避免YUV格式导致的颜色偏差
            LuminanceSource source = new RGBLuminanceSource(width, height, pixels);
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));

            // 修复2：完善解码参数，解决模糊、变形二维码识别问题
            Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
            // 支持所有常见码制（不仅限于QR_CODE）
            List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>();
            formats.add(BarcodeFormat.QR_CODE);
            formats.add(BarcodeFormat.CODE_128);
            formats.add(BarcodeFormat.EAN_8);
            formats.add(BarcodeFormat.EAN_13);
            hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
            // 字符编码：支持中文等多语言
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            // 容错模式：允许二维码有一定损坏（关键！解决轻微变形/污染的二维码）
            hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
            // 不使用纯条码模式，兼容带logo的二维码
            hints.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);

            MultiFormatReader reader = new MultiFormatReader();
            reader.setHints(hints);
            Result result = reader.decode(binaryBitmap);
            return result.getText();

        } catch (NotFoundException e) {
            // 正常未识别到，不打印异常（避免日志冗余）
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // ==================== 原有逻辑（不变） ====================
    private void checkCameraPermission() {
        if (checkSelfPermission(android.Manifest.permission.CAMERA)
			!= PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{android.Manifest.permission.CAMERA},
							   REQUEST_CAMERA_PERMISSION);
        } else {
            startScanning();
        }
    }

    private void startScanning() {
        barcodeView.decodeContinuous(barcodeCallback);
    }

    private BarcodeCallback barcodeCallback = new BarcodeCallback() {
        @Override
        public void barcodeResult(BarcodeResult result) {
            if (result != null && result.getText() != null) {
                barcodeView.pause();
                String decodeResult = result.getText();
                resultTextView.setText("扫码结果：" + decodeResult);
                showDecodeResultDialog(decodeResult);
                returnResultToPreviousPage(decodeResult);
            }
        }

        @Override
        public void possibleResultPoints(List<ResultPoint> resultPoints) {
        }
    };

    private void showDecodeResultDialog(String result) {
        ScrollView scrollView = new ScrollView(this);
        scrollView.setPadding(dip2px(16), dip2px(16), dip2px(16), dip2px(16));

        TextView dialogTv = new TextView(this);
        dialogTv.setTextSize(16);
        dialogTv.setTextColor(getResources().getColor(android.R.color.black));
        dialogTv.setText(result);
        scrollView.addView(dialogTv);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("解码结果");
        builder.setView(scrollView);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					barcodeView.resume();
				}
			});
        builder.setCancelable(false);
        builder.show();
    }

    private void returnResultToPreviousPage(String result) {
        Intent intent = new Intent();
        intent.putExtra(EXTRA_RESULT, result);
        setResult(RESULT_OK, intent);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults != null && grantResults.length > 0) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    startScanning();
                } else {
                    new AlertDialog.Builder(this)
						.setTitle("权限申请")
						.setMessage("扫码需要相机权限，请在设置中开启")
						.setPositiveButton("确定", new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								finish();
							}
						})
						.setCancelable(false)
						.show();
                }
            }
        } else if (requestCode == REQUEST_READ_STORAGE_PERMISSION) {
            if (grantResults != null && grantResults.length > 0) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    openAlbum();
                } else {
                    new AlertDialog.Builder(this)
						.setTitle("权限申请")
						.setMessage("从相册解码需要存储权限，请在设置中开启")
						.setPositiveButton("确定", new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
							}
						})
						.setCancelable(false)
						.show();
                }
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (barcodeView != null) {
            barcodeView.resume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (barcodeView != null) {
            barcodeView.pause();
        }
    }

    private int dip2px(float dpValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    @Override
    public boolean onOptionsItemSelected(android.view.MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void showToast(String message) {
        android.widget.Toast.makeText(this, message, android.widget.Toast.LENGTH_SHORT).show();
    }
}

