package com.jeeplus.hotelorder.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 二维码生成工具类
 * 用于生成房间点餐二维码，包含签名校验机制
 * @author jeeplus
 */
public class QrCodeUtils {

    /** 二维码默认尺寸 */
    private static final int DEFAULT_SIZE = 400;

    /** 二维码签名密钥（生产环境应配置到Nacos） */
    private static final String QR_SIGN_SECRET = "hotel_qr_secret_2026";

    /**
     * 生成二维码Base64图片
     * @param content 二维码内容（URL）
     * @return Base64编码的PNG图片
     * @throws Exception 生成异常
     */
    public static String generateQrCodeBase64(String content) throws Exception {
        return generateQrCodeBase64(content, DEFAULT_SIZE);
    }

    /**
     * 生成二维码Base64图片（指定尺寸）
     * @param content 二维码内容（URL）
     * @param size 图片尺寸（像素）
     * @return Base64编码的PNG图片
     * @throws Exception 生成异常
     */
    public static String generateQrCodeBase64(String content, int size) throws Exception {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 4);

        BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, size, size, hints);
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", pngOutputStream);
        byte[] pngData = pngOutputStream.toByteArray();
        return Base64.encode(pngData);
    }

    /**
     * 生成二维码签名
     * 签名算法：MD5(roomId + roomNo + timestamp + 固定密钥)
     * @param roomId 房间ID
     * @param roomNo 房间号
     * @param timestamp 生成时间戳
     * @return MD5签名值
     */
    public static String generateSign(String roomId, String roomNo, long timestamp) {
        String raw = roomId + roomNo + timestamp + QR_SIGN_SECRET;
        return SecureUtil.md5(raw);
    }

    /**
     * 校验二维码签名
     * @param roomId 房间ID
     * @param roomNo 房间号
     * @param timestamp 时间戳
     * @param sign 待校验的签名
     * @return 签名是否有效
     */
    public static boolean verifySign(String roomId, String roomNo, long timestamp, String sign) {
        String expectedSign = generateSign(roomId, roomNo, timestamp);
        return expectedSign.equals(sign);
    }

    /**
     * 构建二维码URL内容
     * @param baseUrl 基础域名（如 https://hotel.example.com）
     * @param shortCode 房间短码
     * @param roomId 房间ID
     * @param roomNo 房间号
     * @param timestamp 时间戳
     * @return 完整的二维码URL
     */
    public static String buildQrCodeUrl(String baseUrl, String shortCode, String roomId, String roomNo, long timestamp) {
        String sign = generateSign(roomId, roomNo, timestamp);
        return baseUrl + "/h5/order?r=" + shortCode + "&sign=" + sign;
    }
}
