import SwiftUI

struct ContentView: View {
    @ObservedObject var monitor: SystemMonitor
    @ObservedObject private var config = Configuration.shared

    weak var windowController: FloatingWindowController?

    init(monitor: SystemMonitor, windowController: FloatingWindowController? = nil) {
        self.monitor = monitor
        self.windowController = windowController
    }

    var body: some View {
        VStack(spacing: 0) {
            // ── 顶部固定区域：图标 + Monitor + 时间 + 关闭按钮 ──
            headerBar

            Divider()
                .background(Color.white.opacity(0.1))

            // ── 可滚动内容 ──
            ScrollView(.vertical, showsIndicators: false) {
                VStack(spacing: 14) {
                    ForEach(Array(moduleRows.enumerated()), id: \.offset) { _, row in
                        row
                    }
                }
                .padding(.top, 6)
                .padding(.horizontal, 16)
                .padding(.bottom, 16)
            }
        }
        .frame(minWidth: 240, idealWidth: 280, maxWidth: 400,
               minHeight: 200, idealHeight: 480, maxHeight: 700)
        .onAppear {
            monitor.interval = config.refreshInterval
            monitor.topN = config.processCount
            applyOpacity()
        }
        .onChange(of: config.processCount) { _, new in
            monitor.topN = new
        }
        .onChange(of: config.opacity) { _, _ in
            applyOpacity()
        }
        .onReceive(NotificationCenter.default.publisher(for: .refreshIntervalChanged)) { notification in
            if let interval = notification.object as? Double {
                monitor.interval = interval
            }
        }
    }

    // MARK: - 顶部栏（精简版）

    private var headerBar: some View {
        HStack(spacing: 6) {
            Image(systemName: "gauge.with.dots.needle.33percent")
                .font(.system(size: 13, weight: .semibold))
                .foregroundColor(.accentColor)

            Text("Monitor")
                .font(.system(size: config.fontSize, weight: .semibold))
                .foregroundColor(.primary.opacity(0.85))

            Spacer()

            Text(timeString)
                .font(.system(size: 10, design: .monospaced))
                .foregroundColor(.secondary.opacity(0.5))

            Button(action: { windowController?.hide() }) {
                Image(systemName: "xmark")
                    .font(.system(size: 11, weight: .medium))
                    .foregroundColor(.secondary.opacity(0.5))
            }
            .buttonStyle(.plain)
            .help("隐藏窗口（点击菜单栏图标重新打开）")
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 10)
    }

    // MARK: - 各指标

    private var cpuGauge: some View {
        StyledGauge(
            title: "CPU", icon: "cpu",
            value: monitor.info.cpuUsage, unit: "%",
            detail: "\(monitor.info.cpuCores) 核心 · \(monitor.info.cpuModel)",
            style: config.cpuStyle, fontSize: config.fontSize
        )
    }

    private var gpuGauge: some View {
        StyledGauge(
            title: "GPU", icon: "display",
            value: monitor.info.gpuUsage ?? 0, unit: "%",
            detail: monitor.info.gpuModel + (monitor.info.gpuUsage == nil ? " (N/A)" : ""),
            style: config.gpuStyle, fontSize: config.fontSize
        )
    }

    private var memoryGauge: some View {
        StyledGauge(
            title: "内存", icon: "memorychip",
            value: monitor.info.memoryUsagePercent, unit: "%",
            detail: formatBytes(monitor.info.memoryUsed) + " / " + formatBytes(monitor.info.memoryTotal),
            style: config.memoryStyle, fontSize: config.fontSize
        )
    }

    private var swapGauge: some View {
        StyledGauge(
            title: "Swap", icon: "arrow.left.arrow.right",
            value: monitor.info.swapUsagePercent, unit: "%",
            detail: formatBytes(monitor.info.swapUsed) + " / " + formatBytes(monitor.info.swapTotal),
            style: config.swapStyle, fontSize: config.fontSize
        )
    }

    private var processesSection: some View {
        VStack(spacing: 12) {
            ProcessListView(
                processes: monitor.info.topCPUProcesses,
                title: "CPU 消耗 Top", icon: "bolt.horizontal",
                isMemory: false, fontSize: config.fontSize
            )
            ProcessListView(
                processes: monitor.info.topMemoryProcesses,
                title: "内存消耗 Top", icon: "tray.full",
                isMemory: true, fontSize: config.fontSize
            )
        }
    }

    // MARK: - 布局引擎（左/右/全宽排列）

    /// 根据行号 + 列位生成布局
    private var moduleRows: [AnyView] {
        struct Item {
            let name: String
            let row: Int
            let position: ModulePosition
            let view: AnyView
        }

        var items: [Item] = []
        if config.showCPU {
            items.append(Item(name: "CPU", row: config.cpuRow, position: config.cpuPos,
                view: AnyView(cpuGauge)))
        }
        if config.showGPU {
            items.append(Item(name: "GPU", row: config.gpuRow, position: config.gpuPos,
                view: AnyView(gpuGauge.opacity(monitor.info.gpuUsage == nil ? 0.5 : 1.0))))
        }
        if config.showMemory {
            items.append(Item(name: "内存", row: config.memoryRow, position: config.memoryPos,
                view: AnyView(memoryGauge)))
        }
        if config.showSwap {
            items.append(Item(name: "Swap", row: config.swapRow, position: config.swapPos,
                view: AnyView(swapGauge)))
        }
        if config.showTopProcesses {
            items.append(Item(name: "进程", row: config.processesRow, position: config.processesPos,
                view: AnyView(processesSection)))
        }

        // 按行号排序
        items.sort { $0.row < $1.row }

        // 同行 left+right 配对，full 独占
        var rows: [AnyView] = []
        var i = 0
        while i < items.count {
            let item = items[i]
            switch item.position {
            case .full:
                rows.append(item.view)
                i += 1
            case .left:
                // 找同行下一个 right
                if let j = (i+1..<items.count).first(where: { items[$0].row == item.row && items[$0].position == .right }) {
                    rows.append(AnyView(HStack(alignment: .top, spacing: 12) {
                        item.view
                        items[j].view
                    }))
                    items.remove(at: j)
                } else {
                    rows.append(item.view)
                }
                i += 1
            case .right:
                rows.append(item.view)
                i += 1
            }
        }
        return rows
    }

    // MARK: - 工具

    private var timeString: String {
        let f = DateFormatter()
        f.dateFormat = "HH:mm:ss"
        return f.string(from: Date())
    }

    private func formatBytes(_ bytes: UInt64) -> String {
        if bytes >= 1_073_741_824 {
            return String(format: "%.1f GB", Double(bytes) / 1_073_741_824)
        } else if bytes >= 1_048_576 {
            return String(format: "%.0f MB", Double(bytes) / 1_048_576)
        } else if bytes >= 1_024 {
            return String(format: "%.0f KB", Double(bytes) / 1_024)
        } else {
            return "\(bytes) B"
        }
    }

    private func applyOpacity() {
        DispatchQueue.main.async {
            windowController?.applyOpacity(config.opacity)
        }
    }
}
