import SwiftUI
import DynamicNotchKit

// MARK: - AgentNotchView

struct AgentNotchView: View {
    @ObservedObject var tracker: AgentProgressTracker
    var onCopy: () -> Void
    var onStop: () -> Void
    var onClose: () -> Void
    var onNewConversation: (() -> Void)? = nil
    var onSendText: ((String) -> Void)? = nil
    var onContentSizeChanged: (() -> Void)? = nil

    private let maxHeight: CGFloat = 250
    private let maxStreamingHeight: CGFloat = 120

    @State private var textInput: String = ""
    @State private var scrollWorkItem: DispatchWorkItem?

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            statusHeader

            if !tracker.streamingContent.isEmpty {
                streamingContentView
            } else if !tracker.isTextInputMode && tracker.mode == "thinking" && tracker.toolEntries.isEmpty {
                thinkingView
            }

            if !tracker.toolEntries.isEmpty {
                toolProgressList
            }

            if tracker.mode == "done" {
                doneView
            } else if tracker.mode == "error" {
                errorView
            }

            if tracker.isTextInputMode && tracker.mode != "thinking" && tracker.mode != "running" {
                textInputBar
            }
        }
        .frame(width: 340)
        .colorScheme(.dark)
        .animation(.spring(response: 0.35, dampingFraction: 0.65), value: tracker.mode)
        .animation(.spring(response: 0.35, dampingFraction: 0.65), value: tracker.toolEntries.count)
        .animation(.spring(response: 0.35, dampingFraction: 0.65), value: tracker.isTextInputMode)
        .onChange(of: tracker.mode) { _, _ in onContentSizeChanged?() }
        .onChange(of: tracker.toolEntries.count) { _, _ in onContentSizeChanged?() }
        .onChange(of: tracker.isTextInputMode) { _, _ in onContentSizeChanged?() }
        .onChange(of: tracker.streamingContent.isEmpty) { _, _ in onContentSizeChanged?() }
    }

    // MARK: - 状态头

    private var statusHeader: some View {
        HStack(spacing: 6) {
            Image(systemName: statusIcon)
                .font(.system(size: 10))
                .foregroundColor(statusColor)
                .opacity(tracker.mode == "thinking" ? 1 : (tracker.mode == "running" ? 0.6 : 0.4))

            Text(tracker.summary)
                .font(.system(size: 11, weight: .medium))
                .foregroundColor(.white.opacity(0.7))

            Spacer()

            if tracker.mode == "running" || tracker.mode == "thinking" {
                Button("停止") {
                    onStop()
                }
                .font(.system(size: 10))
                .foregroundColor(.white.opacity(0.6))
                .padding(.horizontal, 6)
                .padding(.vertical, 2)
                .background(.white.opacity(0.1))
                .clipShape(Capsule())
                .buttonStyle(.plain)
            }

            if tracker.mode != "thinking" && tracker.mode != "running",
               let onNew = onNewConversation {
                Button(action: onNew) {
                    Image(systemName: "plus.bubble")
                        .font(.system(size: 9, weight: .medium))
                        .foregroundColor(.white.opacity(0.5))
                        .frame(width: 20, height: 20)
                        .contentShape(Rectangle())
                }
                .buttonStyle(.plain)
                .help("新建对话")
                .padding(.leading, 2)
            }

            Button(action: onClose) {
                Image(systemName: "xmark")
                    .font(.system(size: 9, weight: .medium))
                    .foregroundColor(.white.opacity(0.5))
                    .frame(width: 20, height: 20)
                    .contentShape(Rectangle())
            }
            .buttonStyle(.plain)
            .padding(.leading, 2)
        }
        .padding(.horizontal, 14)
        .padding(.vertical, 8)
    }

    // MARK: - 思考中

    private var thinkingView: some View {
        HStack(spacing: 6) {
            ProgressView()
                .scaleEffect(0.6)
            Text("正在分析你的问题...")
                .font(.system(size: 11))
                .foregroundColor(.white.opacity(0.4))
        }
        .frame(maxWidth: .infinity, alignment: .center)
        .padding(.vertical, 12)
    }

    // MARK: - 实时流式输出

    private var streamingContentView: some View {
        let hasTools = !tracker.toolEntries.isEmpty

        return ScrollViewReader { proxy in
            ScrollView(.vertical, showsIndicators: false) {
                Text(tracker.streamingContent)
                    .font(.system(size: 12))
                    .foregroundColor(.white.opacity(0.85))
                    .lineSpacing(3)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .id("streaming_bottom")
            }
            .frame(height: hasTools ? maxStreamingHeight : nil)
            .frame(maxHeight: maxStreamingHeight)
            .padding(.horizontal, 14)
            .padding(.vertical, 6)
            .onChange(of: tracker.streamingContent) { _, _ in
                withAnimation {
                    proxy.scrollTo("streaming_bottom", anchor: .bottom)
                }
            }
        }
    }

    // MARK: - 工具进度列表（可见 3 条，可滚动查看全部）

    private var toolProgressList: some View {
        ScrollViewReader { proxy in
            ScrollView(.vertical, showsIndicators: false) {
                VStack(alignment: .leading, spacing: 0) {
                    ForEach(Array(tracker.toolEntries.enumerated()), id: \.element.id) { idx, entry in
                        compactToolRow(entry: entry)
                            .id(entry.id)
                            .transition(
                                .asymmetric(
                                    insertion: .move(edge: .bottom).combined(with: .opacity),
                                    removal: .move(edge: .top).combined(with: .opacity)
                                )
                            )
                            .zIndex(Double(-idx))
                    }
                }
            }
            .frame(maxHeight: 60)
            .clipped()
            .padding(.horizontal, 4)
            .onReceive(tracker.$toolEntries) { entries in
                // 并行工具调用防抖：0.1s 内连续出现只滚一次到底
                scrollWorkItem?.cancel()
                let workItem = DispatchWorkItem {
                    withAnimation {
                        if let lastID = entries.last?.id {
                            proxy.scrollTo(lastID, anchor: .bottom)
                        }
                    }
                }
                scrollWorkItem = workItem
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: workItem)
            }
        }
    }

    private func compactToolRow(entry: AgentProgressTracker.ToolEntry) -> some View {
        let hasResult = !entry.resultLines.isEmpty
        let isActive = !hasResult && entry.id == tracker.toolEntries.last?.id && tracker.mode == "running"

        return HStack(spacing: 4) {
            Circle()
                .fill(isActive ? Color.white : Color.white.opacity(0.3))
                .frame(width: 5, height: 5)
            Text(entry.display)
                .font(.system(size: 10, design: .monospaced))
                .foregroundColor(hasResult ? .white.opacity(0.6) : .white.opacity(0.85))
                .lineLimit(1)
                .truncationMode(.tail)
            if isActive {
                Circle()
                    .fill(.white.opacity(0.5))
                    .frame(width: 3, height: 3)
                    .opacity(blinkingOpacity)
            }
            Spacer()
        }
        .padding(.horizontal, 10)
        .padding(.vertical, 4)
    }

    @State private var blinkToggle = false
    private var blinkingOpacity: Double {
        blinkToggle ? 1 : 0.2
    }

    // MARK: - 完成视图

    private var doneView: some View {
        EmptyView()
    }

    // MARK: - 错误视图

    private var errorView: some View {
        Text("❌ \(tracker.errorMessage)")
            .font(.system(size: 12))
            .foregroundColor(.red.opacity(0.8))
            .padding(.horizontal, 14)
            .padding(.vertical, 10)
    }

    // MARK: - 辅助

    private var statusIcon: String {
        switch tracker.mode {
        case "thinking": return "brain"
        case "running":  return "gearshape.2"
        case "done":     return "checkmark.circle"
        case "error":    return "xmark.circle"
        default:         return "circle"
        }
    }

    private var statusColor: Color {
        switch tracker.mode {
        case "thinking": return .blue
        case "running":  return .orange
        case "done":     return .green
        case "error":    return .red
        default:         return .gray
        }
    }

    // MARK: - 文本输入栏

    private var textInputBar: some View {
        let isBusy = tracker.mode == "thinking" || tracker.mode == "running"

        return VStack(spacing: 0) {
            Divider()
                .overlay(.white.opacity(0.1))
                .padding(.horizontal, 10)

            HStack(spacing: 8) {
                AppKitTextField(
                    text: $textInput,
                    placeholder: isBusy ? "等待回复中..." : "输入你的问题...",
                    isEditable: !isBusy,
                    onSubmit: { if !isBusy { sendText() } }
                )
                .frame(height: 28)
                .opacity(isBusy ? 0.5 : 1)

                Button(action: { if !isBusy { sendText() } }) {
                    Image(systemName: "arrow.up.circle.fill")
                        .font(.system(size: 20))
                        .foregroundColor(!isBusy && !textInput.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
                            ? .blue : .white.opacity(0.2))
                }
                .buttonStyle(.plain)
                .disabled(isBusy || textInput.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
            }
            .padding(.horizontal, 14)
            .padding(.vertical, 8)
        }
    }

    private func sendText() {
        let text = textInput.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !text.isEmpty else { return }
        onSendText?(text)
        textInput = ""
    }
}
