import SwiftUI
import UIKit

/// Modal sheet for scanning nearby BLE audio recording devices and binding them to the logged-in user.
struct DeviceScanView: View {
    @Environment(\.dismiss) private var dismiss
    @ObservedObject var bleManager: BLEManager = .shared
    @ObservedObject var authManager: AuthManager = .shared
    
    @State private var boundSuccessMessage: String?
    @State private var bindingDeviceID: String?
    @State private var bindingErrorMessage: String?
    @State private var debugDeviceID: String?
    @State private var copiedCompatibilityLog = false
    
    var body: some View {
        ZStack {
            Color.spaceBlack.ignoresSafeArea()
            
            VStack(spacing: 20) {
                // Top Header
                HStack {
                    VStack(alignment: .leading, spacing: 4) {
                        Text("搜索与绑定录音设备")
                            .font(.system(size: 18, weight: .bold))
                            .foregroundStyle(Color.primary)
                        
                        Text("请确保设备已开启蓝牙广播模式并靠拢 iPhone")
                            .font(.system(size: 12))
                            .foregroundStyle(Color.secondary)
                    }
                    
                    Spacer()
                    
                    Button {
                        bleManager.stopScanning()
                        dismiss()
                    } label: {
                        Image(systemName: "xmark.circle.fill")
                            .font(.system(size: 22))
                            .foregroundStyle(Color.secondary.opacity(0.6))
                    }
                }
                .padding(.horizontal, 20)
                .padding(.top, 20)
                
                // Scanning Status Indicator
                HStack(spacing: 12) {
                    if bleManager.isScanning {
                        ProgressView()
                            .tint(Color.primary)
                    } else {
                        Image(systemName: "radiowaves.left.and.right")
                            .font(.system(size: 16))
                            .foregroundStyle(Color.primary)
                    }
                    
                    Text(scanStatusText)
                        .font(.system(size: 13, weight: .medium))
                        .foregroundStyle(Color.primary)
                    
                    Spacer()
                    
                    Button {
                        if bleManager.isScanning {
                            bleManager.stopScanning()
                        } else {
                            bleManager.startScanning()
                        }
                    } label: {
                        Text(bleManager.isScanning ? "停止扫描" : "重新扫描")
                            .font(.system(size: 12, weight: .regular))
                            .foregroundStyle(Color.primary)
                            .padding(.horizontal, 10)
                            .padding(.vertical, 6)
                            .overlay(
                                RoundedRectangle(cornerRadius: 6)
                                    .stroke(Color.primary.opacity(0.3), lineWidth: 1)
                            )
                    }
                }
                .padding(14)
                .background(Color.cardBackground.opacity(0.4))
                .businessBorder(cornerRadius: 10)
                .padding(.horizontal, 20)

                if let issue = bleManager.scanUnavailableMessage {
                    VStack(alignment: .leading, spacing: 10) {
                        Label(issue, systemImage: "exclamationmark.triangle.fill")
                            .font(.system(size: 12))
                            .foregroundStyle(Color.orange)

                        if bleManager.state == .unauthorized {
                            Button("打开系统设置") {
                                guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
                                UIApplication.shared.open(url)
                            }
                            .font(.system(size: 12, weight: .medium))
                        }
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(14)
                    .background(Color.orange.opacity(0.08))
                    .businessBorder(cornerRadius: 10)
                    .padding(.horizontal, 20)
                }

                formalBindingSection

                if let debugDeviceID {
                    communicationDebugPanel(deviceID: debugDeviceID)
                } else if !bleManager.observedAdvertisements.isEmpty {
                    VStack(alignment: .leading, spacing: 10) {
                        HStack {
                            Text("BLE 广播调试")
                                .font(.system(size: 13, weight: .semibold))
                                .foregroundStyle(Color.primary)

                            Spacer()

                            Text("\(bleManager.observedAdvertisements.count) 个设备 · 最多显示 50 个")
                                .font(.system(size: 11, design: .monospaced))
                                .foregroundStyle(Color.secondary)
                        }

                        ScrollView {
                            LazyVStack(spacing: 8) {
                                ForEach(bleManager.observedAdvertisements) { advertisement in
                                    observedAdvertisementRow(advertisement)
                                }
                            }
                        }
                        .frame(height: 300)
                    }
                    .padding(14)
                    .background(Color.cardBackground.opacity(0.4))
                    .businessBorder(cornerRadius: 10)
                    .padding(.horizontal, 20)
                }
                
                // Success Toast Banner
                if let successMsg = boundSuccessMessage {
                    HStack(spacing: 8) {
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundStyle(Color.primary)
                        Text(successMsg)
                            .font(.system(size: 13, weight: .medium))
                            .foregroundStyle(Color.primary)
                    }
                    .padding(.vertical, 10)
                    .padding(.horizontal, 16)
                    .background(Color.primary.opacity(0.1))
                    .cornerRadius(8)
                    .transition(.move(edge: .top).combined(with: .opacity))
                }
                
            }
        }
        .onAppear {
            bleManager.startScanning()
        }
        .onDisappear {
            bleManager.stopScanning()
        }
        .alert("无法绑定微光", isPresented: Binding(
            get: { bindingErrorMessage != nil },
            set: { if !$0 { bindingErrorMessage = nil } }
        )) {
            Button("知道了", role: .cancel) { bindingErrorMessage = nil }
        } message: {
            Text(bindingErrorMessage ?? "请稍后重试。")
        }
    }

    @ViewBuilder
    private var formalBindingSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text("正式绑定设备（仅显示 YLF20）")
                .font(.system(size: 13, weight: .semibold))
                .foregroundStyle(Color.primary)

            if bleManager.discoveredDevices.isEmpty {
                Text(
                    bleManager.observedPeripheralCount > 0
                        ? "暂未发现名称以 YLF20 开头的设备。"
                        : "正在等待 YLF20 设备广播…"
                )
                .font(.system(size: 11))
                .foregroundStyle(Color.secondary)
                .frame(maxWidth: .infinity, minHeight: 54, alignment: .center)
            } else {
                ScrollView {
                    LazyVStack(spacing: 8) {
                        ForEach(bleManager.discoveredDevices) { device in
                            discoveredDeviceRow(device)
                        }
                    }
                }
                .frame(maxHeight: 150)
            }
        }
        .padding(14)
        .background(Color.cardBackground.opacity(0.4))
        .businessBorder(cornerRadius: 10)
        .padding(.horizontal, 20)
    }

    private func communicationDebugPanel(deviceID: String) -> some View {
        let logs = bleManager.communicationLogs(for: deviceID)

        return VStack(alignment: .leading, spacing: 10) {
            HStack {
                Text("绑定与协议通信调试")
                    .font(.system(size: 13, weight: .semibold))
                    .foregroundStyle(Color.primary)

                Spacer()

                Button(copiedCompatibilityLog ? "已复制" : "复制兼容日志") {
                    copyCompatibilityLogs(deviceID: deviceID)
                }
                .font(.system(size: 11, weight: .medium))
                .disabled(compatibilityLogs(deviceID: deviceID).isEmpty)

                Button("重新测试") {
                    bleManager.runProtocolDiagnostics(deviceID: deviceID)
                }
                .font(.system(size: 11, weight: .medium))
                .disabled(bindingDeviceID != nil)
            }

            ScrollViewReader { proxy in
                ScrollView {
                    LazyVStack(alignment: .leading, spacing: 5) {
                        ForEach(logs) { entry in
                            HStack(alignment: .top, spacing: 7) {
                                Text(entry.timestamp.formatted(date: .omitted, time: .standard))
                                    .foregroundStyle(Color.secondary)

                                Text(entry.kind)
                                    .foregroundStyle(logColor(entry.kind))
                                    .frame(width: 38, alignment: .leading)

                                Text(entry.message)
                                    .foregroundStyle(Color.primary)
                                    .textSelection(.enabled)
                            }
                            .font(.system(size: 9, design: .monospaced))
                            .id(entry.id)
                        }
                    }
                }
                .onChange(of: logs.count) {
                    if let last = logs.last {
                        withAnimation {
                            proxy.scrollTo(last.id, anchor: .bottom)
                        }
                    }
                }
            }
            .frame(height: 300)
        }
        .padding(14)
        .background(Color.cardBackground.opacity(0.4))
        .businessBorder(cornerRadius: 10)
        .padding(.horizontal, 20)
    }

    private func compatibilityLogs(deviceID: String) -> [BLECommunicationLogEntry] {
        let logs = bleManager.communicationLogs(for: deviceID)
        guard let startIndex = logs.lastIndex(where: {
            $0.message.contains("开始只读兼容探测")
        }) else {
            return []
        }
        return Array(logs[startIndex...])
    }

    private func copyCompatibilityLogs(deviceID: String) {
        let logs = compatibilityLogs(deviceID: deviceID)
        guard !logs.isEmpty else { return }

        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "HH:mm:ss.SSS"

        let lines = logs.map {
            "\(formatter.string(from: $0.timestamp)) [\($0.kind)] \($0.message)"
        }
        let header = [
            "YLF20 BLE 兼容探测日志",
            "设备标识：\(deviceID)",
            "导出时间：\(Date().formatted(date: .numeric, time: .standard))",
            String(repeating: "-", count: 36)
        ]
        UIPasteboard.general.string = (header + lines).joined(separator: "\n")
        copiedCompatibilityLog = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            copiedCompatibilityLog = false
        }
    }

    private func logColor(_ kind: String) -> Color {
        switch kind {
        case "OK": return .green
        case "ERROR": return .red
        case "TX": return .blue
        case "RX": return .orange
        default: return .secondary
        }
    }

    private var scanStatusText: String {
        if bleManager.isScanning {
            return "正在扫描附近的蓝牙录音设备..."
        }
        switch bleManager.state {
        case .unknown, .resetting:
            return "正在初始化系统蓝牙..."
        case .poweredOn:
            return "扫描已停止"
        case .poweredOff:
            return "系统蓝牙未开启"
        case .unauthorized:
            return "没有蓝牙访问权限"
        case .unsupported:
            return "当前设备不支持 BLE 扫描"
        @unknown default:
            return "蓝牙状态不可用"
        }
    }

    private func observedAdvertisementRow(_ advertisement: ObservedBLEAdvertisement) -> some View {
        VStack(alignment: .leading, spacing: 3) {
            HStack(spacing: 8) {
                Text(advertisement.name)
                    .font(.system(size: 12, weight: .medium))
                    .foregroundStyle(Color.primary)
                    .lineLimit(1)

                if advertisement.matchesSpark {
                    Text("匹配 Spark")
                        .font(.system(size: 9, weight: .semibold))
                        .foregroundStyle(Color.green)
                        .padding(.horizontal, 6)
                        .padding(.vertical, 2)
                        .background(Color.green.opacity(0.12))
                        .clipShape(Capsule())
                }

                if !advertisement.isPresent {
                    debugBadge("刚消失", color: .red)
                } else if advertisement.reappearanceCount > 0 {
                    debugBadge("重新出现 ×\(advertisement.reappearanceCount)", color: .orange)
                } else if Date().timeIntervalSince(advertisement.firstSeenAt) < 8 {
                    debugBadge("新出现", color: .blue)
                }

                if advertisement.isStrongSignal {
                    debugBadge("强信号", color: .green)
                }

                Spacer()

                Text("\(advertisement.rssi) dBm")
                    .font(.system(size: 10, design: .monospaced))
                    .foregroundStyle(Color.secondary)
            }

            Text("设备：\(advertisement.id) · \(advertisement.lastSeenAt.formatted(date: .omitted, time: .standard))")
                .font(.system(size: 9, design: .monospaced))
                .foregroundStyle(Color.secondary.opacity(0.8))
                .textSelection(.enabled)

            Text(
                advertisement.serviceUUIDs.isEmpty
                    ? "Service UUID：广播中未提供"
                    : "Service UUID：\(advertisement.serviceUUIDs.joined(separator: ", "))"
            )
            .font(.system(size: 9, design: .monospaced))
            .foregroundStyle(Color.secondary.opacity(0.8))
            .textSelection(.enabled)

        }
        .padding(7)
        .background(Color.spaceBlack.opacity(0.35))
        .clipShape(RoundedRectangle(cornerRadius: 7))
        .opacity(advertisement.isPresent ? 1 : 0.65)
    }

    private func debugBadge(_ text: String, color: Color) -> some View {
        Text(text)
            .font(.system(size: 9, weight: .semibold))
            .foregroundStyle(color)
            .padding(.horizontal, 6)
            .padding(.vertical, 2)
            .background(color.opacity(0.12))
            .clipShape(Capsule())
    }
    
    private func discoveredDeviceRow(_ device: DiscoveredBLEDevice) -> some View {
        let isAlreadyBound = bleManager.boundDevices.contains(where: { $0.id == device.id })
        
        return HStack(spacing: 14) {
            ZStack {
                Circle()
                    .fill(Color.primary.opacity(0.06))
                    .frame(width: 42, height: 42)
                
                Image(systemName: "mic.fill")
                    .font(.system(size: 16))
                    .foregroundStyle(Color.primary)
            }
            
            VStack(alignment: .leading, spacing: 4) {
                Text("微光(Spark)")
                    .font(.system(size: 14, weight: .medium))
                    .foregroundStyle(Color.primary)
                
                HStack(spacing: 8) {
                    Text("信号强度: \(device.rssi) dBm")
                        .font(.system(size: 11, design: .monospaced))
                        .foregroundStyle(Color.secondary)
                    
                    Text("•")
                        .font(.system(size: 10))
                        .foregroundStyle(Color.secondary)
                    
                    Text("设备标识: " + String(device.peripheralUUID.prefix(8)))
                        .font(.system(size: 11, design: .monospaced))
                        .foregroundStyle(Color.secondary)
                }

                Text("广播名称: \(device.name)")
                    .font(.system(size: 10))
                    .foregroundStyle(Color.secondary.opacity(0.8))
            }
            
            Spacer()
            
            if isAlreadyBound {
                Button("测试通信") {
                    debugDeviceID = device.id
                    bleManager.runProtocolDiagnostics(deviceID: device.id)
                }
                .font(.system(size: 12, weight: .medium))
                .disabled(bindingDeviceID != nil)
            } else {
                Button {
                    guard let userId = authManager.currentUser?.id else { return }
                    debugDeviceID = device.id
                    boundSuccessMessage = nil
                    bindingErrorMessage = nil
                    bindingDeviceID = device.id
                    bleManager.connectAndBind(device, userId: userId) { result in
                        bindingDeviceID = nil
                        switch result {
                        case .success(let bound):
                            Task {
                                do {
                                    let remote = try await DeviceCloudService.shared.register(bound)
                                    bleManager.updateCloudRegistration(deviceID: bound.id, cloudID: remote.id, error: nil)
                                    boundSuccessMessage = "设备已绑定并登记到云端"
                                } catch {
                                    bleManager.updateCloudRegistration(deviceID: bound.id, cloudID: nil, error: error.localizedDescription)
                                    boundSuccessMessage = "设备已在本机绑定，云端登记将在稍后重试"
                                }
                            }
                        case .failure(let error):
                            bindingErrorMessage = error.localizedDescription
                        }
                    }
                } label: {
                    Group {
                        if bindingDeviceID == device.id {
                            ProgressView()
                                .tint(Color.spaceBlack)
                        } else {
                            Text("绑定设备")
                                .font(.system(size: 13, weight: .semibold))
                        }
                    }
                    .foregroundStyle(Color.spaceBlack)
                    .frame(minWidth: 72)
                    .padding(.horizontal, 14)
                    .padding(.vertical, 7)
                    .background(Color.primary)
                    .cornerRadius(6)
                }
                .disabled(bindingDeviceID != nil)
            }
        }
        .padding(14)
        .background(Color.cardBackground.opacity(0.3))
        .businessBorder(cornerRadius: 10)
    }
}

#Preview {
    DeviceScanView()
}
