package cn.novalon.gym.manage.groupcourse.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 二维码生成工具类
 */
public class QRCodeUtil {
    
    private static final Logger logger = LoggerFactory.getLogger(QRCodeUtil.class);
    
    // 二维码默认保存路径（本地临时路径）
    private static final String DEFAULT_SAVE_PATH = "D:\\Games\\exmp\\image";
    
    // 二维码尺寸
    private static final int QR_CODE_WIDTH = 300;
    private static final int QR_CODE_HEIGHT = 300;
    
    /**
     * 生成二维码并保存到指定路径
     * 
     * @param content 二维码内容
     * @param savePath 保存路径
     * @param fileName 文件名（不含扩展名）
     * @return 生成的二维码文件完整路径
     */
    public static String generateQRCode(String content, String savePath, String fileName) {
        try {
            Path directory = Paths.get(savePath);
            if (!Files.exists(directory)) {
                Files.createDirectories(directory);
                logger.info("创建二维码保存目录: {}", savePath);
            }
            
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.MARGIN, 1);
            
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, QR_CODE_WIDTH, QR_CODE_HEIGHT, hints);
            
            String filePath = Paths.get(savePath, fileName + ".png").toString();
            Path path = Paths.get(filePath);
            
            MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
            logger.info("二维码生成成功: {}", filePath);
            
            return filePath;
        } catch (WriterException e) {
            logger.error("二维码生成失败 - WriterException: {}", e.getMessage(), e);
            throw new RuntimeException("二维码生成失败: " + e.getMessage(), e);
        } catch (IOException e) {
            logger.error("二维码保存失败 - IOException: {}", e.getMessage(), e);
            throw new RuntimeException("二维码保存失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 生成二维码并保存到默认路径
     * 文件名格式: UUID + 创建时间
     * 
     * @param content 二维码内容
     * @return 生成的二维码文件完整路径
     */
    public static String generateQRCode(String content) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String fileName = uuid + "_" + timestamp;
        
        return generateQRCode(content, DEFAULT_SAVE_PATH, fileName);
    }
    
    /**
     * 生成二维码并保存到默认路径，使用自定义文件名
     * 
     * @param content 二维码内容
     * @param fileName 文件名（不含扩展名）
     * @return 生成的二维码文件完整路径
     */
    public static String generateQRCodeWithFileName(String content, String fileName) {
        return generateQRCode(content, DEFAULT_SAVE_PATH, fileName);
    }
    
    /**
     * 生成二维码并上传到阿里云OSS
     * 文件名格式: UUID + 创建时间
     * 
     * @param content 二维码内容
     * @return 阿里云OSS访问地址
     */
    public static String generateQRCodeAndUploadToOSS(String content) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String fileName = uuid + "_" + timestamp + ".png";
        
        return generateQRCodeAndUploadToOSS(content, fileName);
    }
    
    /**
     * 生成二维码并上传到阿里云OSS
     * 
     * @param content 二维码内容
     * @param fileName 文件名（含扩展名）
     * @return 阿里云OSS访问地址
     */
    public static String generateQRCodeAndUploadToOSS(String content, String fileName) {
        try {
            Path tempDir = Files.createTempDirectory("qrcode_temp");
            String tempFilePath = tempDir.resolve(fileName).toString();
            
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.MARGIN, 1);
            
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, QR_CODE_WIDTH, QR_CODE_HEIGHT, hints);
            
            MatrixToImageWriter.writeToPath(bitMatrix, "PNG", Paths.get(tempFilePath));
            logger.info("二维码临时文件生成成功: {}", tempFilePath);
            
            String ossUrl = OSSUtil.uploadToOSS(tempFilePath, fileName);
            
            Files.deleteIfExists(Paths.get(tempFilePath));
            Files.deleteIfExists(tempDir);
            logger.info("临时文件已删除: {}", tempFilePath);
            
            return ossUrl;
        } catch (WriterException e) {
            logger.error("二维码生成失败 - WriterException: {}", e.getMessage(), e);
            throw new RuntimeException("二维码生成失败: " + e.getMessage(), e);
        } catch (IOException e) {
            logger.error("二维码处理失败 - IOException: {}", e.getMessage(), e);
            throw new RuntimeException("二维码处理失败: " + e.getMessage(), e);
        }
    }
}