import AppKit
import SwiftUI
import TokenLensCore

struct FloatingTokenWindow: View {
    @ObservedObject var store: UsageStore
    let onSizeChange: (CGSize) -> Void
    @Environment(\.colorScheme) private var colorScheme
    @StateObject private var settings = AppSettings.shared
    @State private var expanded = false
    @State private var collapseTask: Task<Void, Never>?

    private var todayText: String {
        TokenFormatter.format(store.summary.cards.todayTokens)
    }

    private var targetWidth: CGFloat {
        let digitWidth = CGFloat(max(todayText.count - 3, 0)) * 11
        return expanded ? max(338, 282 + digitWidth) : min(220, max(142, 120 + digitWidth))
    }

    private var visibleProviders: [Provider] {
        Provider.allCases.filter {
            (store.summary.todayProviderTotals[$0]?.totalTokens ?? 0) > 0
        }
    }

    private var providerRowCount: Int {
        max(visibleProviders.count, 1)
    }

    private var activeProviderSignature: String {
        visibleProviders.map(\.rawValue).joined(separator: "|")
    }

    private var targetHeight: CGFloat {
        expanded ? 84 + CGFloat(providerRowCount) * 62 + CGFloat(max(providerRowCount - 1, 0)) * 8 : 36
    }
    private var cornerRadius: CGFloat { expanded ? 18 : targetHeight / 2 }
    private var expansionAnimation: Animation {
        .spring(response: 0.38, dampingFraction: 0.92, blendDuration: 0.10)
    }

    var body: some View {
        ZStack(alignment: .topLeading) {
            RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
                .fill(panelFill)
                .overlay {
                    LinearGradient(
                        colors: [.white.opacity(colorScheme == .dark ? 0.18 : 0.46), .white.opacity(0.04)],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                    .clipShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous))
                }
                .overlay {
                    RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
                        .stroke(.white.opacity(colorScheme == .dark ? 0.18 : 0.54), lineWidth: 1)
                }
                .shadow(color: .black.opacity(colorScheme == .dark ? 0.32 : 0.16), radius: expanded ? 16 : 10, y: expanded ? 10 : 5)

            content
                .padding(expanded ? EdgeInsets(top: 14, leading: 12, bottom: 14, trailing: 12) : EdgeInsets(top: 7, leading: 7, bottom: 7, trailing: 7))
        }
        .frame(width: targetWidth, height: targetHeight, alignment: .topLeading)
        .clipShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous))
        .animation(expansionAnimation, value: expanded)
        .animation(.smooth(duration: 0.22), value: store.summary.cards.totalTokens)
        .contentShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous))
        .onTapGesture {
            toggleExpanded()
        }
        .onChange(of: settings.autoCollapseSeconds) { _, _ in
            if expanded {
                scheduleAutoCollapse()
            }
        }
        .onAppear(perform: reportSize)
        .onChange(of: expanded) { _, _ in reportSize() }
        .onChange(of: todayText) { _, _ in reportSize() }
        .onChange(of: activeProviderSignature) { _, _ in reportSize() }
        .preferredColorScheme(settings.floatingAppearance.colorScheme)
    }

    private var panelFill: Color {
        if colorScheme == .dark {
            return Color(red: 0.08, green: 0.09, blue: 0.11).opacity(0.86)
        }
        return Color.white.opacity(0.88)
    }

    @ViewBuilder
    private var content: some View {
        VStack(alignment: .leading, spacing: expanded ? 12 : 0) {
            if expanded {
                HStack(spacing: 8) {
                    FloatingTrendIcon()
                        .frame(width: 32, height: 32)
                    VStack(alignment: .leading, spacing: 1) {
                        Text("今日 Tokens")
                            .font(.system(size: 12, weight: .semibold))
                            .foregroundStyle(.secondary)
                        Text(todayText)
                            .font(.system(size: 22, weight: .bold, design: .rounded))
                            .foregroundStyle(.primary)
                            .monospacedDigit()
                            .contentTransition(.numericText())
                    }
                    Spacer(minLength: 0)
                    VStack(alignment: .trailing, spacing: 1) {
                        Text("实时")
                            .font(.system(size: 11, weight: .bold))
                        Text("15 秒刷新")
                            .font(.system(size: 10, weight: .medium))
                            .foregroundStyle(.secondary)
                    }
                }

                VStack(spacing: 8) {
                    if visibleProviders.isEmpty {
                        Text("今日暂无工具流量")
                            .font(.system(size: 12, weight: .semibold))
                            .foregroundStyle(.secondary)
                            .frame(maxWidth: .infinity)
                            .frame(height: 54)
                            .background(.white.opacity(0.06), in: RoundedRectangle(cornerRadius: 11, style: .continuous))
                    } else {
                        ForEach(visibleProviders, id: \.self) { provider in
                            FloatingProviderRow(
                                provider: provider,
                                bucket: store.summary.todayProviderTotals[provider] ?? TokenBucket(provider: provider)
                            )
                        }
                    }
                }
                .frame(maxWidth: .infinity)
            } else {
                HStack(spacing: 6) {
                    FloatingTrendIcon()
                        .frame(width: 22, height: 22)
                    Text("今日")
                        .font(.system(size: 10, weight: .semibold))
                        .foregroundStyle(.secondary)
                    Text(todayText)
                        .font(.system(size: 15, weight: .bold, design: .rounded))
                        .foregroundStyle(.primary)
                        .monospacedDigit()
                        .contentTransition(.numericText())
                    Spacer(minLength: 0)
                }
            }
        }
    }

    private func toggleExpanded() {
        collapseTask?.cancel()
        withAnimation(expansionAnimation) {
            expanded.toggle()
        }
        if expanded {
            scheduleAutoCollapse()
        }
    }

    private func scheduleAutoCollapse() {
        collapseTask?.cancel()
        let delay = UInt64(max(1, settings.autoCollapseSeconds)) * 1_000_000_000
        collapseTask = Task { @MainActor in
            try? await Task.sleep(nanoseconds: delay)
            guard !Task.isCancelled else { return }
            withAnimation(expansionAnimation) {
                expanded = false
            }
        }
    }

    private func reportSize() {
        let size = CGSize(width: targetWidth, height: targetHeight)
        DispatchQueue.main.async {
            onSizeChange(size)
        }
    }
}

private struct FloatingTrendIcon: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 9, style: .continuous)
                .fill(
                    LinearGradient(
                        colors: [.blue.opacity(0.88), .purple.opacity(0.82)],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                )
                .overlay {
                    RoundedRectangle(cornerRadius: 9, style: .continuous)
                        .stroke(.white.opacity(0.26), lineWidth: 1)
                }
            Image(systemName: "chart.line.uptrend.xyaxis")
                .font(.system(size: 14, weight: .bold))
                .foregroundStyle(.white)
        }
        .shadow(color: .blue.opacity(0.24), radius: 8, y: 4)
    }
}

private struct FloatingProviderRow: View {
    let provider: Provider
    let bucket: TokenBucket

    var body: some View {
        VStack(spacing: 5) {
            HStack(spacing: 8) {
                Circle()
                    .fill(provider.color)
                    .frame(width: 7, height: 7)
                Text(provider.rawValue)
                    .font(.system(size: 12, weight: .bold))
                Spacer()
                Text(TokenFormatter.format(bucket.totalTokens))
                    .font(.system(size: 13, weight: .bold, design: .rounded))
                    .monospacedDigit()
            }
            HStack(spacing: 8) {
                detail("输入", bucket.inputTokens)
                detail("输出", bucket.outputTokens)
                detail("缓存", bucket.cachedTokens)
            }
        }
        .padding(.horizontal, 8)
        .padding(.vertical, 7)
        .background(provider.color.opacity(0.08), in: RoundedRectangle(cornerRadius: 11, style: .continuous))
        .overlay(RoundedRectangle(cornerRadius: 11, style: .continuous).stroke(provider.color.opacity(0.16)))
    }

    private func detail(_ label: String, _ value: Int) -> some View {
        HStack(spacing: 3) {
            Text(label)
                .foregroundStyle(.secondary)
            Text(TokenFormatter.format(value))
                .fontWeight(.semibold)
                .monospacedDigit()
        }
        .font(.system(size: 10))
        .lineLimit(1)
    }
}
