import AppKit
import SwiftUI
import TokenLensCore

struct DashboardView: View {
    @StateObject private var store = UsageStore.shared
    @State private var appeared = false
    @State private var showingDetails = false
    @State private var trendMode = "每日"
    @State private var shareMode = "按 Tokens"
    @State private var toolFilter = "全部工具"

    var filteredRows: [ToolRow] {
        if toolFilter == "全部工具" { return store.summary.toolRows }
        return store.summary.toolRows.filter { $0.provider.rawValue == toolFilter }
    }

    private var bottomPanelHeight: CGFloat {
        336
    }

    private var sidePanelWidth: CGFloat {
        420
    }

    var body: some View {
        ZStack {
            AmbientBackground()
            if showingDetails {
                DailyUsageDetailPage(summary: store.summary) {
                    withAnimation(pageAnimation) {
                        showingDetails = false
                    }
                }
                .transition(.asymmetric(
                    insertion: .move(edge: .trailing).combined(with: .opacity),
                    removal: .move(edge: .trailing).combined(with: .opacity)
                ))
            } else {
                dashboardContent
                    .transition(.asymmetric(
                        insertion: .move(edge: .leading).combined(with: .opacity),
                        removal: .move(edge: .leading).combined(with: .opacity)
                    ))
            }
        }
        .animation(pageAnimation, value: showingDetails)
        .overlay(alignment: .top) {
            TitlebarDoubleClickZone()
                .frame(height: 32)
                .ignoresSafeArea(edges: .top)
        }
        .task {
            appeared = true
            store.start()
        }
    }

    private var pageAnimation: Animation {
        .spring(response: 0.42, dampingFraction: 0.90, blendDuration: 0.08)
    }

    private var dashboardContent: some View {
        VStack(spacing: 0) {
            HeaderBar(store: store) {
                withAnimation(pageAnimation) {
                    showingDetails = true
                }
            }
            .animatedAppearance(appeared, delay: 0.02)
            VStack(spacing: 0) {
                ScrollView(showsIndicators: false) {
                    VStack(spacing: 18) {
                        MetricGrid(cards: store.summary.cards)
                            .animatedAppearance(appeared, delay: 0.08)
                        HStack(spacing: 18) {
                            GlassPanel(title: "Tokens 使用趋势") {
                                TrendChart(summary: store.summary, mode: TrendMode(rawValue: trendMode) ?? .daily)
                            } accessory: {
                                NativeMenuPicker(selection: $trendMode, options: TrendMode.allCases.map(\.rawValue))
                                    .frame(width: 126)
                            }
                            .frame(maxWidth: .infinity)

                            GlassPanel(title: "使用占比") {
                                UsageShare(summary: store.summary)
                            } accessory: {
                                NativeMenuPicker(selection: $shareMode, options: ["按 Tokens", "按占比"])
                                    .frame(width: 154)
                            }
                            .frame(width: sidePanelWidth)
                        }
                        .animatedAppearance(appeared, delay: 0.15)
                        HStack(alignment: .top, spacing: 18) {
                            ToolBreakdown(rows: filteredRows, selection: $toolFilter)
                                .frame(maxWidth: .infinity)
                                .frame(height: bottomPanelHeight, alignment: .top)
                            TokenActivityHeatmap(summary: store.summary)
                                .frame(width: sidePanelWidth)
                                .frame(height: bottomPanelHeight, alignment: .top)
                        }
                        .frame(height: bottomPanelHeight)
                        .animatedAppearance(appeared, delay: 0.22)
                    }
                    .padding(.horizontal, 26)
                    .padding(.top, 22)
                    .padding(.bottom, 26)
                }
            }
        }
    }
}

private struct TitlebarDoubleClickZone: NSViewRepresentable {
    func makeNSView(context: Context) -> NSView {
        TitlebarHitView()
    }

    func updateNSView(_ nsView: NSView, context: Context) {}
}

private final class TitlebarHitView: NSView {
    override var acceptsFirstResponder: Bool { true }

    override func mouseDown(with event: NSEvent) {
        guard event.clickCount >= 2 else {
            window?.performDrag(with: event)
            return
        }
        if let window {
            WindowActions.toggleMaximize(window)
        }
    }
}

struct HeaderBar: View {
    @ObservedObject var store: UsageStore
    let onShowDetails: () -> Void

    var body: some View {
        HStack(spacing: 16) {
            BrandMark(phase: 0)
                .frame(width: 42, height: 42)
            Text("TokenLens 用量统计")
                .font(.system(size: 24, weight: .bold, design: .rounded))

            StatusPill(isRefreshing: store.isRefreshing, phase: 0)

            Spacer()

            Button(action: onShowDetails) {
                Label("查看详情", systemImage: "list.bullet.rectangle.portrait")
                    .labelStyle(.titleAndIcon)
            }
            .buttonStyle(GlassButtonStyle())

            VStack(alignment: .leading, spacing: 2) {
                Text("上次更新 \(store.summary.generatedAt.formatted(date: .omitted, time: .shortened))")
                Text("已刷新 \(store.refreshCount) 次")
                    .foregroundStyle(.secondary)
            }
            .font(.system(size: 12, weight: .medium))
            .foregroundStyle(.secondary)
        }
        .padding(.leading, 26)
        .padding(.trailing, 28)
        .frame(height: 78)
        .background(.ultraThinMaterial)
        .overlay(alignment: .bottom) {
            Rectangle()
                .fill(.white.opacity(0.08))
                .frame(height: 1)
        }
    }
}

struct DailyUsageDetailPage: View {
    let summary: UsageSummary
    let onBack: () -> Void
    @State private var selectedYear = ""
    @State private var selectedMonth = ""
    @State private var selectedDay = "全部"

    private var details: [DailyUsageDetail] {
        summary.dailyUsageDetails()
    }

    private var calendar: Calendar {
        var calendar = Calendar.current
        calendar.firstWeekday = 2
        return calendar
    }

    private var yearOptions: [String] {
        let years = Set(details.map { calendar.component(.year, from: $0.date) })
        let fallbackYear = calendar.component(.year, from: summary.generatedAt)
        let sortedYears = years.isEmpty ? [fallbackYear] : years.sorted(by: >)
        return sortedYears.map { "\($0)年" }
    }

    private var monthLabels: [String] {
        (1...12).map { "\($0)月" }
    }

    private var dayLabels: [String] {
        guard let monthDate = selectedMonthDate,
              let range = calendar.range(of: .day, in: .month, for: monthDate)
        else {
            return ["全部"]
        }
        return ["全部"] + range.map { "\($0)日" }
    }

    private var selectedYearValue: Int? {
        Int(selectedYear.replacingOccurrences(of: "年", with: ""))
    }

    private var selectedMonthValue: Int? {
        Int(selectedMonth.replacingOccurrences(of: "月", with: ""))
    }

    private var selectedDayValue: Int? {
        guard selectedDay != "全部" else { return nil }
        return Int(selectedDay.replacingOccurrences(of: "日", with: ""))
    }

    private var selectedMonthDate: Date? {
        guard let selectedYearValue, let selectedMonthValue else { return nil }
        var components = DateComponents()
        components.year = selectedYearValue
        components.month = selectedMonthValue
        components.day = 1
        return calendar.date(from: components)
    }

    private var filteredDetails: [DailyUsageDetail] {
        guard let selectedYearValue, let selectedMonthValue else { return [] }
        return details.filter {
            let components = calendar.dateComponents([.year, .month, .day], from: $0.date)
            guard components.year == selectedYearValue, components.month == selectedMonthValue else {
                return false
            }
            if let selectedDayValue {
                return components.day == selectedDayValue
            }
            return true
        }
    }

    private var selectedRangeTotal: Int {
        filteredDetails.reduce(0) { $0 + $1.totalTokens }
    }

    var body: some View {
        VStack(spacing: 0) {
            HStack(spacing: 14) {
                Button(action: onBack) {
                    Label("返回", systemImage: "chevron.left")
                        .labelStyle(.titleAndIcon)
                }
                .buttonStyle(GlassButtonStyle())

                VStack(alignment: .leading, spacing: 3) {
                    Text("每日用量详情")
                        .font(.system(size: 24, weight: .bold, design: .rounded))
                    Text("按本地日期汇总输入、输出、缓存和每个工具的 Tokens")
                        .font(.system(size: 13, weight: .medium))
                        .foregroundStyle(.secondary)
                }

                Spacer()

                VStack(alignment: .trailing, spacing: 3) {
                    Text("筛选日期")
                        .font(.system(size: 12, weight: .semibold))
                        .foregroundStyle(.secondary)
                    HStack(spacing: 12) {
                        DateFilterControl(
                            year: $selectedYear,
                            month: $selectedMonth,
                            day: $selectedDay,
                            yearOptions: yearOptions,
                            monthOptions: monthLabels,
                            dayOptions: dayLabels
                        )
                        VStack(alignment: .trailing, spacing: 1) {
                            Text("合计")
                                .font(.system(size: 11, weight: .semibold))
                                .foregroundStyle(.secondary)
                            Text(TokenFormatter.format(selectedRangeTotal))
                                .font(.system(size: 18, weight: .bold, design: .rounded))
                                .monospacedDigit()
                        }
                    }
                }
            }
            .padding(.horizontal, 26)
            .frame(height: 78)
            .background(.ultraThinMaterial)
            .overlay(alignment: .bottom) {
                Rectangle()
                    .fill(.white.opacity(0.08))
                    .frame(height: 1)
            }

            ScrollView(showsIndicators: false) {
                VStack(spacing: 14) {
                    DailyUsageHeader()
                    ForEach(filteredDetails) { detail in
                        DailyUsageRow(detail: detail)
                    }
                    if filteredDetails.isEmpty {
                        EmptyDailyUsageState()
                    }
                }
                .padding(.horizontal, 26)
                .padding(.top, 22)
                .padding(.bottom, 28)
            }
        }
        .onAppear(perform: ensureDateSelection)
        .onChange(of: summary.cards.totalTokens) { _, _ in
            ensureDateSelection()
        }
        .onChange(of: selectedYear) { _, _ in
            ensureDaySelection()
        }
        .onChange(of: selectedMonth) { _, newValue in
            guard !newValue.isEmpty else { return }
            ensureDaySelection()
        }
        .onChange(of: selectedDay) { _, newValue in
            if !dayLabels.contains(newValue) {
                selectedDay = "全部"
            }
        }
    }

    private func ensureDateSelection() {
        let latestDate = details.first?.date ?? summary.generatedAt
        let components = calendar.dateComponents([.year, .month], from: latestDate)
        let fallbackYear = "\(components.year ?? calendar.component(.year, from: summary.generatedAt))年"
        let fallbackMonth = "\(components.month ?? calendar.component(.month, from: summary.generatedAt))月"

        if selectedYear.isEmpty || !yearOptions.contains(selectedYear) {
            selectedYear = yearOptions.first ?? fallbackYear
        }
        if selectedMonth.isEmpty || !monthLabels.contains(selectedMonth) {
            selectedMonth = fallbackMonth
        }
        ensureDaySelection()
    }

    private func ensureDaySelection() {
        if selectedDay.isEmpty || !dayLabels.contains(selectedDay) {
            selectedDay = "全部"
        }
    }
}

private struct DailyUsageHeader: View {
    var body: some View {
        HStack(spacing: 18) {
            Text("日期").frame(width: DailyUsageColumnLayout.date, alignment: .center)
            Text("总量").frame(width: DailyUsageColumnLayout.total, alignment: .center)
            Text("输入").frame(width: DailyUsageColumnLayout.metric, alignment: .center)
            Text("输出").frame(width: DailyUsageColumnLayout.metric, alignment: .center)
            Text("缓存").frame(width: DailyUsageColumnLayout.metric, alignment: .center)
            Text("工具分布").frame(maxWidth: .infinity, alignment: .center)
        }
        .font(.system(size: 13, weight: .semibold))
        .foregroundStyle(.secondary)
        .padding(.horizontal, 22)
        .frame(height: 44)
        .background(.white.opacity(0.055), in: RoundedRectangle(cornerRadius: 14, style: .continuous))
        .overlay(RoundedRectangle(cornerRadius: 14, style: .continuous).stroke(.white.opacity(0.08)))
    }
}

private struct DateFilterControl: View {
    @Binding var year: String
    @Binding var month: String
    @Binding var day: String
    let yearOptions: [String]
    let monthOptions: [String]
    let dayOptions: [String]

    var body: some View {
        HStack(spacing: 0) {
            PrettyFilterMenu(title: "年", selection: $year, options: yearOptions)
                .frame(width: 104)
            Divider()
                .frame(height: 22)
                .overlay(.white.opacity(0.10))
            PrettyFilterMenu(title: "月", selection: $month, options: monthOptions)
                .frame(width: 86)
            Divider()
                .frame(height: 22)
                .overlay(.white.opacity(0.10))
            PrettyFilterMenu(title: "日", selection: $day, options: dayOptions)
                .frame(width: 86)
        }
        .frame(height: 42)
        .background {
            RoundedRectangle(cornerRadius: 14, style: .continuous)
                .fill(.thinMaterial)
                .overlay {
                    LinearGradient(
                        colors: [.white.opacity(0.20), .white.opacity(0.04)],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                    .clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
                }
        }
        .overlay(RoundedRectangle(cornerRadius: 14, style: .continuous).stroke(.white.opacity(0.18)))
        .shadow(color: .black.opacity(0.12), radius: 12, y: 8)
    }
}

private struct PrettyFilterMenu: View {
    let title: String
    @Binding var selection: String
    let options: [String]
    @State private var showingOptions = false

    var body: some View {
        Button {
            showingOptions.toggle()
        } label: {
            HStack(spacing: 7) {
                Text(title)
                    .font(.system(size: 11, weight: .bold))
                    .foregroundStyle(.secondary)
                Text(selection)
                    .font(.system(size: 14, weight: .bold, design: .rounded))
                    .foregroundStyle(.primary)
                    .lineLimit(1)
                    .minimumScaleFactor(0.82)
                Image(systemName: "chevron.down")
                    .font(.system(size: 9, weight: .black))
                    .foregroundStyle(.secondary)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .contentShape(Rectangle())
        }
        .buttonStyle(.plain)
        .popover(isPresented: $showingOptions, arrowEdge: .bottom) {
            DropdownOptionList(selection: selection, options: options) { option in
                selection = option
                showingOptions = false
            }
        }
    }
}

private struct EmptyDailyUsageState: View {
    var body: some View {
        VStack(spacing: 10) {
            Image(systemName: "calendar.badge.exclamationmark")
                .font(.system(size: 28, weight: .semibold))
                .foregroundStyle(.secondary)
            Text("这个日期范围还没有统计数据")
                .font(.system(size: 16, weight: .bold))
            Text("TokenLens 会继续扫描本地日志，有新记录后这里会自动刷新。")
                .font(.system(size: 13, weight: .medium))
                .foregroundStyle(.secondary)
        }
        .frame(maxWidth: .infinity)
        .padding(.vertical, 42)
    }
}

private struct DailyUsageRow: View {
    let detail: DailyUsageDetail
    @State private var hovering = false

    var body: some View {
        GlassCard {
            HStack(spacing: 18) {
                VStack(alignment: .center, spacing: 4) {
                    Text(detail.date.formatted(.dateTime.month(.twoDigits).day(.twoDigits)))
                        .font(.system(size: 19, weight: .bold, design: .rounded))
                    Text(detail.date.formatted(.dateTime.weekday(.wide)))
                        .font(.system(size: 12, weight: .semibold))
                        .foregroundStyle(.secondary)
                }
                .frame(width: DailyUsageColumnLayout.date, alignment: .center)

                metric(TokenFormatter.format(detail.totalTokens), tint: .primary, width: DailyUsageColumnLayout.total)
                metric(TokenFormatter.format(detail.inputTokens), tint: .blue, width: DailyUsageColumnLayout.metric)
                metric(TokenFormatter.format(detail.outputTokens), tint: .green, width: DailyUsageColumnLayout.metric)
                metric(TokenFormatter.format(detail.cachedTokens), tint: .orange, width: DailyUsageColumnLayout.metric)

                ProviderUsageDistribution(detail: detail)
                    .frame(maxWidth: .infinity)
            }
        }
        .scaleEffect(hovering ? 1.006 : 1)
        .animation(.smooth(duration: 0.18), value: hovering)
        .onHover { hovering = $0 }
    }

    private func metric(_ text: String, tint: Color, width: CGFloat) -> some View {
        Text(text)
            .font(.system(size: 18, weight: .bold, design: .rounded))
            .foregroundStyle(tint)
            .monospacedDigit()
            .lineLimit(1)
            .minimumScaleFactor(0.76)
            .frame(width: width, alignment: .center)
    }
}

private enum DailyUsageColumnLayout {
    static let date: CGFloat = 112
    static let total: CGFloat = 98
    static let metric: CGFloat = 88
}

private struct ProviderUsageDistribution: View {
    let detail: DailyUsageDetail

    var body: some View {
        VStack(alignment: .leading, spacing: 9) {
            GeometryReader { proxy in
                HStack(spacing: 3) {
                    ForEach(activeProviders, id: \.self) { provider in
                        RoundedRectangle(cornerRadius: 5, style: .continuous)
                            .fill(provider.color.gradient)
                            .frame(width: segmentWidths(totalWidth: proxy.size.width)[provider, default: 0])
                    }
                }
                .frame(width: proxy.size.width, alignment: .leading)
                .clipped()
            }
            .frame(height: 11)
            .background(.white.opacity(0.055), in: RoundedRectangle(cornerRadius: 5, style: .continuous))
            .overlay(RoundedRectangle(cornerRadius: 5, style: .continuous).stroke(.white.opacity(0.08)))

            HStack(spacing: 10) {
                ForEach(Provider.allCases, id: \.self) { provider in
                    providerCell(provider)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
            }
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 10)
        .background(.white.opacity(0.045), in: RoundedRectangle(cornerRadius: 15, style: .continuous))
        .overlay(RoundedRectangle(cornerRadius: 15, style: .continuous).stroke(.white.opacity(0.09)))
    }

    private func providerCell(_ provider: Provider) -> some View {
        let value = detail.providerTotals[provider, default: 0]
        let percent = detail.totalTokens > 0 ? Int((Double(value) / Double(detail.totalTokens) * 100).rounded()) : 0
        return HStack(spacing: 7) {
            Circle()
                .fill(provider.color)
                .frame(width: 7, height: 7)
            VStack(alignment: .leading, spacing: 1) {
                Text(provider.rawValue)
                    .font(.system(size: 10, weight: .bold))
                    .foregroundStyle(.secondary)
                Text("\(TokenFormatter.format(value)) · \(percent)%")
                    .font(.system(size: 11, weight: .bold, design: .rounded))
                    .monospacedDigit()
                    .lineLimit(1)
                    .minimumScaleFactor(0.72)
            }
            .frame(minWidth: 0, alignment: .leading)
        }
    }

    private var activeProviders: [Provider] {
        let providers = Provider.allCases.filter { detail.providerTotals[$0, default: 0] > 0 }
        return providers.isEmpty ? Provider.allCases : providers
    }

    private func segmentWidths(totalWidth: CGFloat) -> [Provider: CGFloat] {
        let providers = activeProviders
        guard totalWidth > 0, !providers.isEmpty else { return [:] }

        let spacing: CGFloat = 3
        let totalSpacing = spacing * CGFloat(max(providers.count - 1, 0))
        let availableWidth = max(0, totalWidth - totalSpacing)

        guard detail.totalTokens > 0 else {
            let width = availableWidth / CGFloat(providers.count)
            return Dictionary(uniqueKeysWithValues: providers.map { ($0, width) })
        }

        let minWidth: CGFloat = 8
        let minTotal = minWidth * CGFloat(providers.count)
        if minTotal >= availableWidth {
            let width = availableWidth / CGFloat(providers.count)
            return Dictionary(uniqueKeysWithValues: providers.map { ($0, width) })
        }

        let remainingWidth = availableWidth - minTotal
        return Dictionary(uniqueKeysWithValues: providers.map { provider in
            let value = CGFloat(detail.providerTotals[provider, default: 0])
            let proportional = remainingWidth * value / CGFloat(detail.totalTokens)
            return (provider, minWidth + proportional)
        })
    }
}

struct StatusPill: View {
    let isRefreshing: Bool
    let phase: Double

    var body: some View {
        HStack(spacing: 8) {
            Circle()
                .fill(isRefreshing ? Color.orange : Color.green)
                .frame(width: 8, height: 8)
                .shadow(color: isRefreshing ? .orange.opacity(0.45) : .green.opacity(0.35), radius: 6)
            Text(isRefreshing ? "正在刷新" : "每 15 秒自动刷新")
                .font(.system(size: 13, weight: .semibold))
        }
        .padding(.horizontal, 12)
        .frame(height: 30)
        .background(.thinMaterial, in: Capsule())
        .overlay(Capsule().stroke(.white.opacity(0.12)))
    }
}

struct MetricGrid: View {
    let cards: SummaryCards

    var body: some View {
        HStack(spacing: 18) {
            MetricCard(title: "今日 Tokens", value: TokenFormatter.format(cards.todayTokens), tint: .blue, icon: "square.stack.3d.down.right.fill", footnote: "实时  本地今日已统计", delay: 0)
            MetricCard(title: "本月 Tokens", value: TokenFormatter.format(cards.monthTokens), tint: .green, icon: "sparkles", footnote: "月度  按本地时区汇总", delay: 0.06)
            MetricCard(title: "历史总量", value: TokenFormatter.format(cards.totalTokens), tint: .purple, icon: "checkmark", footnote: "全部  已扫描 \(cards.sessionCount) 个会话", delay: 0.12)
            MetricCard(title: "缓存命中", value: "\(cards.cacheHitRate)%", tint: .orange, icon: "arrow.up.right", footnote: "缓存  来自缓存上下文", delay: 0.18)
        }
    }
}

struct MetricCard: View {
    let title: String
    let value: String
    let tint: Color
    let icon: String
    let footnote: String
    let delay: Double
    @State private var hovering = false

    var body: some View {
        GlassCard(padding: 18, cornerRadius: 22) {
            HStack(spacing: 16) {
                ZStack {
                    Circle()
                        .fill(tint.gradient)
                    Circle()
                        .stroke(.white.opacity(0.30), lineWidth: 1)
                    Image(systemName: icon)
                        .font(.system(size: 23, weight: .bold))
                        .foregroundStyle(.white.opacity(0.92))
                }
                .frame(width: 54, height: 54)
                .shadow(color: tint.opacity(0.24), radius: 12, y: 6)
                .rotation3DEffect(.degrees(hovering ? 6 : 0), axis: (x: 0, y: 1, z: 0))

                VStack(alignment: .leading, spacing: 6) {
                    HStack(spacing: 5) {
                        Text(title)
                        Image(systemName: "info.circle")
                    }
                    .font(.system(size: 14, weight: .semibold))
                    .foregroundStyle(.secondary)
                    Text(value)
                        .font(.system(size: 32, weight: .bold, design: .rounded))
                        .monospacedDigit()
                        .lineLimit(1)
                        .minimumScaleFactor(0.72)
                        .contentTransition(.numericText())
                    Text(footnote)
                        .font(.system(size: 13, weight: .semibold))
                        .lineLimit(1)
                        .minimumScaleFactor(0.80)
                        .foregroundStyle(tint, .secondary)
                }
                Spacer(minLength: 0)
            }
        }
        .scaleEffect(hovering ? 1.01 : 1)
        .offset(y: hovering ? -2 : 0)
        .animation(.smooth(duration: 0.18), value: hovering)
        .frame(height: 124)
        .onHover { hovering = $0 }
    }
}

struct GlassPanel<Content: View, Accessory: View>: View {
    let title: String
    @ViewBuilder let content: Content
    @ViewBuilder let accessory: Accessory

    var body: some View {
        GlassCard {
            VStack(spacing: 14) {
                HStack {
                    Text(title)
                        .font(.system(size: 21, weight: .bold, design: .rounded))
                    Spacer()
                    accessory
                }
                content
            }
        }
    }
}

struct GlassCard<Content: View>: View {
    @ViewBuilder let content: Content
    var padding: CGFloat = 22
    var cornerRadius: CGFloat = 24
    @State private var hovering = false

    init(
        padding: CGFloat = 22,
        cornerRadius: CGFloat = 24,
        @ViewBuilder content: () -> Content
    ) {
        self.padding = padding
        self.cornerRadius = cornerRadius
        self.content = content()
    }

    var body: some View {
        content
            .padding(padding)
            .background {
                RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
                    .fill(.ultraThinMaterial)
                    .overlay {
                        LinearGradient(
                            colors: [.white.opacity(0.18), .white.opacity(0.04), .clear],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        )
                        .clipShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous))
                    }
                    .overlay {
                        RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
                            .stroke(.white.opacity(hovering ? 0.28 : 0.16), lineWidth: 1)
                    }
                    .shadow(color: .black.opacity(0.22), radius: hovering ? 32 : 28, y: hovering ? 20 : 18)
            }
            .animation(.smooth(duration: 0.18), value: hovering)
            .onHover { hovering = $0 }
    }
}

struct NativeMenuPicker: View {
    @Binding var selection: String
    let options: [String]
    @State private var showingOptions = false

    var body: some View {
        Button {
            showingOptions.toggle()
        } label: {
            HStack(spacing: 9) {
                Text(selection)
                    .lineLimit(1)
                    .minimumScaleFactor(0.84)
                Spacer()
                ZStack {
                    Circle()
                        .fill(.white.opacity(0.10))
                        .frame(width: 20, height: 20)
                    Image(systemName: showingOptions ? "chevron.up" : "chevron.down")
                        .font(.system(size: 9, weight: .black))
                        .foregroundStyle(.secondary)
                }
            }
            .font(.system(size: 14, weight: .bold, design: .rounded))
            .padding(.horizontal, 14)
            .frame(height: 42)
            .background {
                RoundedRectangle(cornerRadius: 14, style: .continuous)
                    .fill(.thinMaterial)
                    .overlay {
                        LinearGradient(
                            colors: [.white.opacity(0.22), .white.opacity(0.05)],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        )
                        .clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
                    }
            }
            .overlay(RoundedRectangle(cornerRadius: 14, style: .continuous).stroke(.white.opacity(0.20)))
            .shadow(color: .black.opacity(0.12), radius: 10, y: 7)
        }
        .buttonStyle(.plain)
        .popover(isPresented: $showingOptions, arrowEdge: .bottom) {
            DropdownOptionList(selection: selection, options: options) { option in
                selection = option
                showingOptions = false
            }
        }
    }
}

private struct DropdownOptionList: View {
    let selection: String
    let options: [String]
    let onSelect: (String) -> Void

    var body: some View {
        VStack(spacing: 4) {
            if options.isEmpty {
                Text("暂无选项")
                    .font(.system(size: 13, weight: .semibold))
                    .foregroundStyle(.secondary)
                    .frame(maxWidth: .infinity, minHeight: 34)
            } else {
                ForEach(options, id: \.self) { option in
                    Button {
                        onSelect(option)
                    } label: {
                        HStack(spacing: 9) {
                            Text(option)
                                .lineLimit(1)
                            Spacer()
                            if option == selection {
                                Image(systemName: "checkmark")
                                    .font(.system(size: 11, weight: .bold))
                                    .foregroundStyle(.blue)
                            }
                        }
                        .font(.system(size: 13, weight: option == selection ? .bold : .semibold, design: .rounded))
                        .padding(.horizontal, 10)
                        .frame(height: 34)
                        .background(
                            option == selection ? Color.blue.opacity(0.16) : Color.white.opacity(0.001),
                            in: RoundedRectangle(cornerRadius: 10, style: .continuous)
                        )
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .padding(6)
        .frame(minWidth: 136)
        .background(.ultraThinMaterial)
        .preferredColorScheme(.dark)
    }
}

struct GlassButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .font(.system(size: 15, weight: .semibold))
            .padding(.horizontal, 16)
            .frame(height: 42)
            .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 13, style: .continuous))
            .overlay(RoundedRectangle(cornerRadius: 13).stroke(.white.opacity(0.16)))
            .scaleEffect(configuration.isPressed ? 0.97 : 1)
            .animation(.smooth(duration: 0.16), value: configuration.isPressed)
    }
}
