import SwiftUI
import SFSafeSymbols

struct TransferView: View {

    private let storageWarnBytes = 500


    let bluetoothClient: BluetoothDevice

    @Binding
    var info: DeviceInfo?

    @EnvironmentObject
    var storage: PersistentStorage

    @EnvironmentObject
    var transfer: TransferHandler

    private var storageIcon: SFSymbol {
        guard let info else {
            return .externaldrive
        }
        if info.storageSize - info.numberOfRecordedBytes < storageWarnBytes {
            return .externaldriveTrianglebadgeExclamationmark
        }
        return .externaldrive
    }

    private var measurementsText: String {
        guard let info else {
            return "No measurements"
        }
        return "\(info.numberOfStoredMeasurements) measurements (\(info.time.totalNumberOfMeasurements) total)"
    }

    private var storageText: String {
        guard let info else {
            return "No data"
        }
        if info.storageSize <= 0 {
            return "\(info.numberOfRecordedBytes) Bytes"
        }
        return "\(info.numberOfRecordedBytes) / \(info.storageSize) Bytes (\(info.storageFillPercentage) %)"
    }

    private var transferSizeText: String {
        guard let info else {
            return "No transfer size"
        }
        return "\(info.transferBlockSize) Byte Block Size"
    }

    private var transferByteText: String {
        let total = Int(transfer.totalBytes)
        guard total > 0 else {
            return "No data"
        }
        return "\(Int(transfer.bytesTransferred)) / \(total) Bytes"
    }

    private var transferMeasurementText: String {
        guard !transfer.measurements.isEmpty else {
            return "No measurements"
        }
        return "\(transfer.measurements.count) measurements"
    }

    var body: some View {
        NavigationView {
            VStack {
                VStack(alignment: .leading, spacing: 5) {
                    Text("Storage")
                        .font(.headline)
                    IconAndTextView(
                        icon: .speedometer,
                        text: measurementsText)
                    IconAndTextView(
                        icon: storageIcon,
                        text: storageText)
                    IconAndTextView(
                        icon: .iphoneAndArrowForward,
                        text: transferSizeText)
                }

                Button(action: clearStorage) {
                    Text("Remove recorded data")
                }
                .disabled(transfer.transferIsRunning)
                .padding()

                VStack(alignment: .leading, spacing: 5) {
                    Text("Transfer")
                        .font(.headline)
                    ProgressView(value: transfer.bytesTransferred, total: transfer.totalBytes)
                        .progressViewStyle(.linear)
                        .padding(.vertical, 5)
                    IconAndTextView(
                        icon: .externaldrive,
                        text: transferByteText)
                    IconAndTextView(
                        icon: .speedometer,
                        text: transferMeasurementText)
                }
                HStack {
                    Button(action: transferData) {
                        Text("Transfer")
                    }
                    .disabled(transfer.transferIsRunning)
                    .padding()
                    Spacer()
                    Button(action: saveTransfer) {
                        Text("Save")
                    }
                    .disabled(transfer.transferIsRunning || transfer.measurements.isEmpty)
                    .padding()
                    Spacer()
                    Button(action: discardTransfer) {
                        Text("Discard")
                    }
                    .disabled(transfer.transferIsRunning || transfer.measurements.isEmpty)
                    .padding()
                }
                Spacer()
                VStack {

                }
            }
            .padding()
            .navigationTitle("Data Transfer")
            .navigationBarTitleDisplayMode(.large)
        }
    }

    func transferData() {
        guard let info else {
            return
        }
        transfer.startTransfer(from: bluetoothClient, with: info, storage: storage)
    }

    func discardTransfer() {
        transfer.discardTransfer()
    }

    func saveTransfer() {
        transfer.saveTransfer(in: storage)
    }

    func clearStorage() {
        guard let byteCount = info?.numberOfRecordedBytes else {
            return
        }
        Task {
            guard await bluetoothClient.deleteDeviceData(byteCount: byteCount) else {
                log.warning("Failed to delete data")
                return
            }
            log.warning("Device storage cleared")
        }
    }
}

struct TransferView_Previews: PreviewProvider {
    static var previews: some View {
        let storage = PersistentStorage(lastMeasurements: TemperatureMeasurement.mockData)
        TransferView(bluetoothClient: .init(), info: .constant(.mock))
            .environmentObject(storage)
    }
}

private extension TemperatureValue {

    var relativeValue: Double {
        if case .value(let double) = self {
            return double
        }
        return 0
    }
}
