import SwiftUI

struct MeterDetailView: View {
    @EnvironmentObject private var appData: AppData
    @Environment(\.dismiss) private var dismiss
    @State private var editorVisibility = false
    @State private var deleteConfirmationVisibility = false

    let meterSummary: AppData.MeterSummary

    var body: some View {
        ScrollView {
            VStack(spacing: 18) {
                headerCard
                statusCard
                identifiersCard
                chargedDevicesCard
                chargersCard
            }
            .padding()
        }
        .background(
            LinearGradient(
                colors: [meterSummary.tint.opacity(0.18), Color.clear],
                startPoint: .topLeading,
                endPoint: .bottomTrailing
            )
            .ignoresSafeArea()
        )
        .navigationTitle(meterSummary.displayName)
        .toolbar {
            ToolbarItemGroup(placement: .primaryAction) {
                Button("Edit") {
                    editorVisibility = true
                }
                Button(role: .destructive) {
                    deleteConfirmationVisibility = true
                } label: {
                    Image(systemName: "trash")
                }
            }
        }
        .sheet(isPresented: $editorVisibility) {
            MeterEditorSheetView(existingMeterSummary: meterSummary)
                .environmentObject(appData)
        }
        .alert("Delete Meter?", isPresented: $deleteConfirmationVisibility) {
            Button("Delete", role: .destructive) {
                if appData.deleteMeter(macAddress: meterSummary.macAddress) {
                    dismiss()
                }
            }
            Button("Cancel", role: .cancel) {}
        } message: {
            Text("This removes the stored meter entry and its saved metadata from the sidebar until the meter is discovered again.")
        }
    }

    private var headerCard: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text(meterSummary.displayName)
                .font(.title2.weight(.semibold))
            Text(meterSummary.modelSummary)
                .font(.subheadline)
                .foregroundColor(.secondary)
            if let advertisedName = meterSummary.advertisedName {
                Text("Advertised as " + advertisedName)
                    .font(.caption2)
                    .foregroundColor(.secondary)
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(18)
        .meterCard(tint: meterSummary.tint, fillOpacity: 0.22, strokeOpacity: 0.28, cornerRadius: 20)
    }

    private var statusCard: some View {
        VStack(alignment: .leading, spacing: 10) {
            HStack(spacing: 8) {
                Text("Status")
                    .font(.headline)
                ContextInfoButton(
                    title: "Status",
                    message: "The meter is not currently connected. Bring it within Bluetooth range or wake it up to open live diagnostics."
                )
            }
            HStack(spacing: 8) {
                Circle()
                    .fill(meterSummary.tint)
                    .frame(width: 10, height: 10)
                Text("Offline")
                    .font(.caption.weight(.semibold))
                    .foregroundColor(.secondary)
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(18)
        .meterCard(tint: meterSummary.tint, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 18)
    }

    private var identifiersCard: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text("Identifiers")
                .font(.headline)
            infoRow(label: "MAC Address", value: meterSummary.macAddress)
            if let advertisedName = meterSummary.advertisedName {
                infoRow(label: "Advertised as", value: advertisedName)
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(18)
        .meterCard(tint: .secondary, fillOpacity: 0.12, strokeOpacity: 0.18, cornerRadius: 18)
    }

    private var chargedDevicesCard: some View {
        let chargedDevices = appData.chargedDevices(for: meterSummary.macAddress)

        return VStack(alignment: .leading, spacing: 10) {
            HStack(spacing: 8) {
                Text("Devices")
                    .font(.headline)
                ContextInfoButton(
                    title: "Devices",
                    message: "Link devices to this meter from Charge Record to keep capacity learning and charge curves tied to the right hardware."
                )
            }

            if chargedDevices.isEmpty {
                Text("No devices linked yet.")
                    .font(.caption)
                    .foregroundColor(.secondary)
            } else {
                ForEach(chargedDevices.prefix(3)) { chargedDevice in
                    NavigationLink(destination: ChargedDeviceDetailView(chargedDeviceID: chargedDevice.id)) {
                        HStack(spacing: 12) {
                            ChargedDeviceQRCodeView(qrIdentifier: chargedDevice.qrIdentifier, side: 52)

                            VStack(alignment: .leading, spacing: 4) {
                                ChargedDeviceIdentityLabelView(
                                    chargedDevice: chargedDevice,
                                    iconPointSize: 15
                                )
                                .font(.subheadline.weight(.semibold))
                                Text(chargedDevice.estimatedBatteryCapacityWh.map { "\($0.format(decimalDigits: 2)) Wh" } ?? "Capacity: learning")
                                    .font(.caption)
                                    .foregroundColor(.secondary)
                            }

                            Spacer()
                        }
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(18)
        .meterCard(tint: .orange, fillOpacity: 0.12, strokeOpacity: 0.18, cornerRadius: 18)
    }

    private var chargersCard: some View {
        let chargers = appData.chargers(for: meterSummary.macAddress)

        return VStack(alignment: .leading, spacing: 10) {
            HStack(spacing: 8) {
                Text("Chargers")
                    .font(.headline)
                ContextInfoButton(
                    title: "Chargers",
                    message: "Link chargers to this meter for wireless sessions so the app can keep charger-specific learning and efficiency data separate."
                )
            }

            if chargers.isEmpty {
                Text("No chargers linked yet.")
                    .font(.caption)
                    .foregroundColor(.secondary)
            } else {
                ForEach(chargers.prefix(3)) { charger in
                    NavigationLink(destination: ChargedDeviceDetailView(chargedDeviceID: charger.id)) {
                        HStack(spacing: 12) {
                            ChargedDeviceQRCodeView(qrIdentifier: charger.qrIdentifier, side: 52)

                            VStack(alignment: .leading, spacing: 4) {
                                ChargedDeviceIdentityLabelView(
                                    chargedDevice: charger,
                                    iconPointSize: 15
                                )
                                .font(.subheadline.weight(.semibold))
                                Text(charger.chargerMaximumPowerWatts.map { "Max power: \($0.format(decimalDigits: 2)) W" } ?? "Wireless charger")
                                    .font(.caption)
                                    .foregroundColor(.secondary)
                            }

                            Spacer()
                        }
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(18)
        .meterCard(tint: .pink, fillOpacity: 0.12, strokeOpacity: 0.18, cornerRadius: 18)
    }

    private func infoRow(label: String, value: String) -> some View {
        HStack {
            Text(label)
            Spacer()
            Text(value)
                .foregroundColor(.secondary)
                .font(.caption)
        }
    }
}

struct MeterDetailView_Previews: PreviewProvider {
    static var previews: some View {
        MeterDetailView(
            meterSummary: AppData.MeterSummary(
                macAddress: "AA:BB:CC:DD:EE:FF",
                displayName: "Desk Meter",
                modelSummary: "UM25C",
                advertisedName: "UM25C-123",
                lastSeen: Date(),
                lastConnected: Date().addingTimeInterval(-3600),
                meter: nil
            )
        )
        .environmentObject(appData)
    }
}

struct MeterEditorSheetView: View {
    @EnvironmentObject private var appData: AppData
    @Environment(\.dismiss) private var dismiss

    let existingMeterSummary: AppData.MeterSummary?

    @State private var customName: String
    @State private var macAddress: String
    @State private var advertisedName: String
    @State private var selectedModel: Model

    init(existingMeterSummary: AppData.MeterSummary? = nil) {
        self.existingMeterSummary = existingMeterSummary
        _customName = State(initialValue: existingMeterSummary?.displayName ?? "")
        _macAddress = State(initialValue: existingMeterSummary?.macAddress ?? "")
        _advertisedName = State(initialValue: existingMeterSummary?.advertisedName ?? "")
        _selectedModel = State(initialValue: Self.model(for: existingMeterSummary?.modelSummary))
    }

    var body: some View {
        NavigationView {
            Form {
                Section(
                    header: ContextInfoHeader(
                        title: "Identity",
                        message: "Use the real BLE MAC address format `AA:BB:CC:DD:EE:FF`. Saved meters remain visible in the sidebar even when they are currently offline."
                    )
                ) {
                    TextField("Display name", text: $customName)
                    TextField("MAC Address", text: $macAddress)
                        .textInputAutocapitalization(.characters)
                        .disableAutocorrection(true)
                        .disabled(existingMeterSummary != nil)

                    Picker("Model", selection: $selectedModel) {
                        ForEach(Model.allCases, id: \.self) { model in
                            Text(model.canonicalName)
                                .tag(model)
                        }
                    }

                    TextField("Advertised name", text: $advertisedName)
                }
            }
            .navigationTitle(existingMeterSummary == nil ? "New Meter" : "Edit Meter")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") {
                        dismiss()
                    }
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button(existingMeterSummary == nil ? "Save" : "Update") {
                        let normalizedMAC = AppData.normalizedMACAddress(macAddress)
                        let didSave = appData.createKnownMeter(
                            macAddress: normalizedMAC,
                            customName: customName,
                            modelName: selectedModel.canonicalName,
                            advertisedName: advertisedName
                        )
                        if didSave {
                            dismiss()
                        }
                    }
                    .disabled(isSaveDisabled)
                }
            }
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }

    private var isSaveDisabled: Bool {
        AppData.isValidMACAddress(AppData.normalizedMACAddress(macAddress)) == false
    }

    private static func model(for summary: String?) -> Model {
        if summary?.contains("UM34C") == true {
            return .UM34C
        }
        if summary?.contains("TC66C") == true {
            return .TC66C
        }
        return .UM25C
    }
}
