import SwiftUI

struct OLTDetailView: View {
    let connection: MCMSConnection
    @State private var vm: OLTDetailViewModel
    @State private var showResetConfirm = false
    private let title: String

    init(connection: MCMSConnection, oltId: String, title: String? = nil) {
        self.connection = connection
        self.title = title ?? oltId
        _vm = State(initialValue: OLTDetailViewModel(connection: connection, oltId: oltId))
    }

    var body: some View {
        Group {
            switch vm.phase {
            case .idle:
                LoadingView()
            case .loading where vm.olt == nil:
                LoadingView()
            case .failed(let msg):
                ErrorStateView(message: msg) { Task { await vm.load() } }
            default:
                content
            }
        }
        .navigationTitle(title)
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Menu {
                    Button(role: .destructive) { showResetConfirm = true } label: {
                        Label("Reset OLT", systemImage: "arrow.clockwise")
                    }
                } label: {
                    Image(systemName: "ellipsis.circle")
                }
                .disabled(vm.isPerformingAction)
            }
        }
        .sheet(isPresented: $showResetConfirm) {
            ResetConfirmSheet(deviceKind: "OLT", deviceName: title) {
                Task { await vm.reset() }
            }
        }
        .alert("Operation", isPresented: Binding(
            get: { vm.actionMessage != nil },
            set: { if !$0 { vm.actionMessage = nil } }
        )) {
            Button("OK") { vm.actionMessage = nil }
        } message: {
            Text(vm.actionMessage ?? "")
        }
        .task { if vm.phase == .idle { await vm.load() } }
        .refreshable { await vm.load() }
    }

    @ViewBuilder
    private var content: some View {
        if let olt = vm.olt {
            List {
                Section("Status") {
                    LabeledContent("ONUs", value: onuSummary(olt))
                    if let model = olt.model { LabeledContent("Model", value: model) }
                    if let mode = olt.ponMode { LabeledContent("PON mode", value: mode) }
                    if let fw = olt.firmwareVersion { LabeledContent("Firmware", value: fw) }
                    if let online = olt.onlineTime {
                        if let up = MongoTimestamp.duration(from: online, to: olt.lastUpdate) {
                            LabeledContent("Uptime", value: up)
                        }
                        LabeledContent("Online since", value: MongoTimestamp.displayString(online) ?? online)
                    }
                    if let updated = MongoTimestamp.displayString(olt.lastUpdate) {
                        LabeledContent("Last update", value: updated)
                    }
                }

                if olt.rxRateBps != nil || olt.txRateBps != nil || olt.txUtilPercent != nil {
                    Section("PON traffic") {
                        LabeledContent("Downstream",
                                       value: "\(Format.bps(olt.txRateBps)) · \(Format.percent(olt.txUtilPercent)) util")
                        LabeledContent("Upstream",
                                       value: "\(Format.bps(olt.rxRateBps)) · \(Format.percent(olt.rxUtilPercent)) util")
                    }
                }

                if olt.asicTempC != nil || olt.voltage != nil {
                    Section("Environment") {
                        if let temp = olt.asicTempC { LabeledContent("ASIC temp", value: "\(temp) °C") }
                        if let volts = olt.voltage {
                            LabeledContent("Voltage", value: "\(volts.formatted(.number.precision(.fractionLength(2)))) V")
                        }
                    }
                }

                if let switchName = olt.switchName {
                    Section("Uplink") {
                        LabeledContent("Switch", value: switchName)
                        if let port = olt.switchPort { LabeledContent("Port", value: port) }
                        if let addr = olt.switchAddress { LabeledContent("Address", value: addr) }
                    }
                }

                if olt.populatedBuckets.isEmpty {
                    Section { Text("No ONUs registered on this OLT.").foregroundStyle(.secondary) }
                } else {
                    ForEach(olt.populatedBuckets, id: \.name) { bucket in
                        Section {
                            ForEach(bucket.ids, id: \.self) { onuId in
                                NavigationLink {
                                    ONUDetailView(connection: connection, onuId: onuId)
                                } label: {
                                    Text(onuId)
                                }
                            }
                        } header: {
                            HStack {
                                StateBadge(text: bucket.state.label, color: bucket.state.color)
                                Spacer()
                                Text("\(bucket.ids.count)")
                                    .font(.caption.monospacedDigit())
                                    .foregroundStyle(.secondary)
                            }
                        }
                    }
                }

                Section("Raw document") {
                    JSONTreeView(value: olt.raw)
                }
            }
        }
    }

    private func onuSummary(_ olt: OLTStateDoc) -> String {
        let down = olt.totalONUs - olt.onlineONUs
        var summary = "\(olt.totalONUs) · \(olt.onlineONUs) online"
        if down > 0 { summary += " · \(down) down" }
        return summary
    }
}
