import SwiftUI
import AVFoundation

// MARK: - 条码位置标记覆盖层
struct CodePositionOverlay: View {
    let detectedCodes: [DetectedCode]
    let previewLayer: AVCaptureVideoPreviewLayer?
    let onCodeSelected: (DetectedCode) -> Void
    
    var body: some View {
        ZStack {
            GeometryReader { geometry in
                ForEach(detectedCodes) { code in
                    CodePositionMarker(
                        code: code,
                        screenSize: geometry.size,
                        previewLayer: previewLayer,
                        onCodeSelected: onCodeSelected
                    )
                }
                
                // 调试信息：显示触摸区域边界
#if DEBUG
                ForEach(detectedCodes) { code in
                    let position = calculateDebugPosition(code: code, screenSize: geometry.size)
                    Rectangle()
                        .stroke(Color.red, lineWidth: 1)
                        .frame(width: 80, height: 80)
                        .position(x: position.x, y: position.y)
                        .opacity(0.3)
                }
#endif
                            }
                .ignoresSafeArea()
        }
        .allowsHitTesting(true)
        .contentShape(Rectangle()) // 确保整个区域都可以接收触摸事件
        .zIndex(1000) // 确保在最上层，不被其他视图遮挡
    }
    
    // 调试用的位置计算方法
    private func calculateDebugPosition(code: DetectedCode, screenSize: CGSize) -> CGPoint {
        guard let previewLayer = previewLayer else {
            return CGPoint(x: screenSize.width / 2, y: screenSize.height / 2)
        }
        
        let metadataObject = code.bounds
        let convertedPoint = previewLayer.layerPointConverted(fromCaptureDevicePoint: CGPoint(
            x: metadataObject.midX,
            y: metadataObject.midY
        ))
        
        let clampedX = max(40, min(screenSize.width - 40, convertedPoint.x))
        let clampedY = max(40, min(screenSize.height - 40, convertedPoint.y))
        
        return CGPoint(x: clampedX, y: clampedY)
    }
}

// MARK: - 单个条码位置标记
struct CodePositionMarker: View {
    let code: DetectedCode
    let screenSize: CGSize
    let previewLayer: AVCaptureVideoPreviewLayer?
    let onCodeSelected: (DetectedCode) -> Void
    
    var body: some View {
        GeometryReader { geometry in
            let position = calculatePosition(screenSize: geometry.size)
            
            ZStack {
                // 触摸区域背景（透明，但可以接收触摸事件）
                Circle()
                    .fill(Color.clear)
                    .frame(width: 80, height: 80)
                    .contentShape(Circle())
                    .onTapGesture {
                        logDebug("🎯 CodePositionMarker 被点击！", className: "CodePositionMarker")
                        logDebug("  条码ID: \(code.id)", className: "CodePositionMarker")
                        logDebug("  条码类型: \(code.type)", className: "CodePositionMarker")
                        logDebug("  条码内容: \(code.content)", className: "CodePositionMarker")
                        logDebug("  点击位置: x=\(position.x), y=\(position.y)", className: "CodePositionMarker")
                        
                        // 添加触觉反馈
                        let impactFeedback = UIImpactFeedbackGenerator(style: .medium)
                        impactFeedback.impactOccurred()
                        
                        onCodeSelected(code)
                    }
                
                // 外圈
                Circle()
                    .stroke(Color.green, lineWidth: 3)
                    .frame(width: 40, height: 40)
                
                // 内圈
                Circle()
                    .fill(Color.green.opacity(0.3))
                    .frame(width: 20, height: 20)
                
                // 中心点
                Circle()
                    .fill(Color.green)
                    .frame(width: 6, height: 6)
            }
            .position(x: position.x, y: position.y)
            .zIndex(1001) // 确保触摸区域在最上层
            .onAppear {
                logDebug("CodePositionMarker appeared at: x=\(position.x), y=\(position.y)", className: "CodePositionMarker")
                logDebug("Screen size: \(geometry.size)", className: "CodePositionMarker")
                logDebug("Code bounds: \(code.bounds)", className: "CodePositionMarker")
            }
        }
    }
    
    private func calculatePosition(screenSize: CGSize) -> CGPoint {
        guard let previewLayer = previewLayer else {
            logWarning("No preview layer available, using screen center", className: "CodePositionMarker")
            return CGPoint(x: screenSize.width / 2, y: screenSize.height / 2)
        }
        
        // 即使会话停止，我们仍然可以使用预览层进行坐标转换
        // 因为预览层的配置仍然有效
        let metadataObject = code.bounds
        
        // 检查边界值是否有效
        guard metadataObject.width > 0 && metadataObject.height > 0 else {
            logWarning("Invalid metadata bounds: \(metadataObject), using screen center", className: "CodePositionMarker")
            return CGPoint(x: screenSize.width / 2, y: screenSize.height / 2)
        }
        
        let convertedPoint = previewLayer.layerPointConverted(fromCaptureDevicePoint: CGPoint(
            x: metadataObject.midX,
            y: metadataObject.midY
        ))
        
        guard convertedPoint.x.isFinite && convertedPoint.y.isFinite else {
            logWarning("Invalid converted point: \(convertedPoint), using screen center", className: "CodePositionMarker")
            return CGPoint(x: screenSize.width / 2, y: screenSize.height / 2)
        }
        
        // 确保选择点在屏幕范围内
        let clampedX = max(20, min(screenSize.width - 20, convertedPoint.x))
        let clampedY = max(20, min(screenSize.height - 20, convertedPoint.y))
        
        logDebug("AVFoundation bounds: \(code.bounds)", className: "CodePositionMarker")
        logDebug("Converted point: \(convertedPoint)", className: "CodePositionMarker")
        logDebug("Screen size: \(screenSize)", className: "CodePositionMarker")
        logDebug("Clamped: x=\(clampedX), y=\(clampedY)", className: "CodePositionMarker")
        
        return CGPoint(x: clampedX, y: clampedY)
    }
}

// MARK: - 重新扫描按钮样式
struct RescanButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 0.95 : 1.0)
            .opacity(configuration.isPressed ? 0.8 : 1.0)
            .animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
    }
} 
