import SwiftUI
import CoreImage
import QRCode

// MARK: - 二维码生成工具类
class QRCodeGenerator {
    
    // MARK: - 生成基本二维码（使用Core Image）
    static func generateBasicQRCode(content: String) -> UIImage {
        let data = content.data(using: .utf8)
        let qrFilter = CIFilter.qrCodeGenerator()
        qrFilter.setValue(data, forKey: "inputMessage")
        qrFilter.setValue("H", forKey: "inputCorrectionLevel")
        
        guard let outputImage = qrFilter.outputImage else {
            return UIImage(systemName: "qrcode") ?? UIImage()
        }
        
        let context = CIContext()
        guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return UIImage(systemName: "qrcode") ?? UIImage()
        }
        
        return UIImage(cgImage: cgImage)
    }
    
    // MARK: - 生成高质量二维码（使用QRCode库）
    static func generateHighQualityQRCode(
        content: String,
        styleData: QRCodeStyleData? = nil
    ) -> UIImage {
        do {
            let document = try createQRCodeDocument(content: content, styleData: styleData)
            let imageData = try document.pngData(dimension: 600)
            return UIImage(data: imageData) ?? generateBasicQRCode(content: content)
        } catch {
            print("生成高质量二维码失败：\(error.localizedDescription)")
            return generateBasicQRCode(content: content)
        }
    }
    
    // MARK: - 创建QRCode文档
    private static func createQRCodeDocument(
        content: String,
        styleData: QRCodeStyleData?
    ) throws -> QRCode.Document {
        let document = try QRCode.Document(engine: QRCodeEngineExternal())
        
        // 设置内容
        document.utf8String = content
        
        // 如果没有样式数据，使用默认样式
        guard let styleData = styleData else {
            // 使用默认样式
            document.design.backgroundColor(CGColor(red: 1, green: 1, blue: 1, alpha: 1)) // 白色背景
            document.design.style.eye = QRCode.FillStyle.Solid(CGColor(red: 0, green: 0, blue: 0, alpha: 1)) // 黑色眼睛
            document.design.style.eyeBackground = CGColor(red: 1, green: 1, blue: 1, alpha: 1) // 白色眼睛背景
            document.design.shape.onPixels = QRCode.PixelShape.Square() // 方形点
            document.design.style.onPixels = QRCode.FillStyle.Solid(CGColor(red: 0, green: 0, blue: 0, alpha: 1)) // 黑色点
            document.design.style.onPixelsBackground = CGColor(red: 1, green: 1, blue: 1, alpha: 1) // 白色点背景
            document.design.shape.offPixels = QRCode.PixelShape.Square() // 方形空白
            document.design.style.offPixels = QRCode.FillStyle.Solid(CGColor(red: 1, green: 1, blue: 1, alpha: 1)) // 白色空白
            document.design.style.offPixelsBackground = CGColor(red: 1, green: 1, blue: 1, alpha: 1) // 白色空白背景
            document.design.shape.eye = QRCode.EyeShape.Square() // 方形眼睛
            return document
        }
        
        // 应用样式数据
        applyStyleData(styleData, to: document)
        
        return document
    }
    
    // MARK: - 应用样式数据
    private static func applyStyleData(_ styleData: QRCodeStyleData, to document: QRCode.Document) {
        // 设置背景色
        if let backgroundColor = getColor(from: styleData.backgroundColor) {
            document.design.backgroundColor(backgroundColor)
        }
        
        // 设置前景色
        let foregroundColor = getColor(from: styleData.foregroundColor) ?? CGColor(red: 0, green: 0, blue: 0, alpha: 1)
        
        // 设置眼睛样式
        document.design.style.eye = QRCode.FillStyle.Solid(foregroundColor)
        document.design.style.eyeBackground = getColor(from: styleData.backgroundColor) ?? CGColor(red: 1, green: 1, blue: 1, alpha: 1)
        
        // 设置点样式
        let dotType = getDotType(from: styleData.dotType)
        document.design.shape.onPixels = dotType
        document.design.style.onPixels = QRCode.FillStyle.Solid(foregroundColor)
        document.design.style.onPixelsBackground = getColor(from: styleData.backgroundColor) ?? CGColor(red: 1, green: 1, blue: 1, alpha: 1)
        
        document.design.shape.offPixels = dotType
        document.design.style.offPixels = QRCode.FillStyle.Solid(getColor(from: styleData.backgroundColor) ?? CGColor(red: 1, green: 1, blue: 1, alpha: 1))
        document.design.style.offPixelsBackground = getColor(from: styleData.backgroundColor) ?? CGColor(red: 1, green: 1, blue: 1, alpha: 1)
        
        // 设置眼睛形状
        let eyeType = getEyeType(from: styleData.eyeType)
        document.design.shape.eye = eyeType
        
        // 设置Logo
        if let logo = styleData.logo {
            applyLogo(logo, hasCustomLogo: styleData.hasCustomLogo, customLogoFileName: styleData.customLogoFileName, to: document)
        }
    }
    
    // MARK: - 应用Logo
    private static func applyLogo(
        _ logoIdentifier: String,
        hasCustomLogo: Bool,
        customLogoFileName: String?,
        to document: QRCode.Document
    ) {
        if hasCustomLogo, let fileName = customLogoFileName {
            // 加载自定义Logo
            if let customLogoImage = loadCustomLogoImage(fileName: fileName),
               let cgImage = customLogoImage.cgImage {
                document.logoTemplate = QRCode.LogoTemplate.CircleCenter(image: cgImage, inset: 0)
            }
        } else {
            // 加载预设Logo
            if let qrCodeLogo = QRCodeLogo(rawValue: logoIdentifier),
               let logoImage = qrCodeLogo.image,
               let cgImage = logoImage.cgImage {
                document.logoTemplate = QRCode.LogoTemplate.CircleCenter(image: cgImage)
            }
        }
    }
    
    // MARK: - 加载自定义Logo图片
    private static func loadCustomLogoImage(fileName: String) -> UIImage? {
        guard let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
            return nil
        }
        
        let customLogosPath = documentsPath.appendingPathComponent("CustomLogos")
        let imagePath = customLogosPath.appendingPathComponent(fileName)
        
        return UIImage(contentsOfFile: imagePath.path)
    }
    
    // MARK: - 颜色转换
    private static func getColor(from colorString: String) -> CGColor? {
        switch colorString.lowercased() {
        case "black": return CGColor(red: 0, green: 0, blue: 0, alpha: 1)
        case "white": return CGColor(red: 1, green: 1, blue: 1, alpha: 1)
        case "red": return CGColor(red: 1, green: 0, blue: 0, alpha: 1)
        case "blue": return CGColor(red: 0, green: 0, blue: 1, alpha: 1)
        case "green": return CGColor(red: 0, green: 1, blue: 0, alpha: 1)
        case "yellow": return CGColor(red: 1, green: 1, blue: 0, alpha: 1)
        case "purple": return CGColor(red: 0.5, green: 0, blue: 0.5, alpha: 1)
        case "orange": return CGColor(red: 1, green: 0.5, blue: 0, alpha: 1)
        case "pink": return CGColor(red: 1, green: 0.75, blue: 0.8, alpha: 1)
        case "cyan": return CGColor(red: 0, green: 1, blue: 1, alpha: 1)
        case "magenta": return CGColor(red: 1, green: 0, blue: 1, alpha: 1)
        case "brown": return CGColor(red: 0.6, green: 0.4, blue: 0.2, alpha: 1)
        case "gray": return CGColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1)
        case "navy": return CGColor(red: 0, green: 0, blue: 0.5, alpha: 1)
        case "teal": return CGColor(red: 0, green: 0.5, blue: 0.5, alpha: 1)
        case "indigo": return CGColor(red: 0.3, green: 0, blue: 0.7, alpha: 1)
        case "lime": return CGColor(red: 0.5, green: 1, blue: 0, alpha: 1)
        case "maroon": return CGColor(red: 0.5, green: 0, blue: 0, alpha: 1)
        case "olive": return CGColor(red: 0.5, green: 0.5, blue: 0, alpha: 1)
        case "silver": return CGColor(red: 0.75, green: 0.75, blue: 0.75, alpha: 1)
        default: return nil
        }
    }
    
    // MARK: - 点类型转换
    private static func getDotType(from dotTypeString: String) -> QRCodePixelShapeGenerator {
        // 根据字符串匹配到对应的QRCodeDotType
        if let dotType = QRCodeDotType.allCases.first(where: { $0.rawValue == dotTypeString }) {
            return dotType.pixelShape
        }
        
        // 如果没有找到匹配的类型，返回默认的方形
        return QRCode.PixelShape.Square()
    }
    
    // MARK: - 眼睛类型转换
    private static func getEyeType(from eyeTypeString: String) -> QRCodeEyeShapeGenerator {
        // 根据字符串匹配到对应的QRCodeEyeType
        if let eyeType = QRCodeEyeType.allCases.first(where: { $0.rawValue == eyeTypeString }) {
            return eyeType.eyeShape
        }
        
        // 如果没有找到匹配的类型，返回默认的方形
        return QRCode.EyeShape.Square()
    }
}
