import MarkdownUI
import Observation
import SwiftUI

struct SybilQuickQuestionView: View {
    @Bindable var viewModel: SybilViewModel
    var focusRequest: Int

    @Environment(\.dismiss) private var dismiss
    @FocusState private var promptFocused: Bool
    @State private var promptSelection: TextSelection?

    private var hasAnswerContent: Bool {
        !viewModel.quickQuestionMessages.isEmpty || viewModel.quickQuestionError != nil
    }

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

                answerArea

                composer
            }
            .padding(.horizontal, 16)
            .padding(.top, 18)
            .padding(.bottom, 12)
            .frame(maxWidth: 640, maxHeight: .infinity, alignment: .top)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
        .background(SybilTheme.backgroundGradient)
        .preferredColorScheme(.dark)
        .task(id: focusRequest) {
            try? await Task.sleep(for: .milliseconds(260))
            guard !Task.isCancelled else {
                return
            }
            promptFocused = true
            let prompt = viewModel.quickQuestionPrompt
            promptSelection = TextSelection(range: prompt.startIndex..<prompt.endIndex)
        }
    }

    private var header: some View {
        HStack {
            Image(systemName: "sparkles")
                .font(.system(size: 21, weight: .semibold))
                .foregroundStyle(SybilTheme.primary)
            
            Text("Quick question")
                .font(.title3.weight(.semibold))
                .foregroundStyle(SybilTheme.text)
                .lineLimit(1)
            
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }

    private var answerArea: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 12) {
                if hasAnswerContent {
                    ForEach(viewModel.quickQuestionMessages) { message in
                        QuickQuestionMessageView(
                            message: message,
                            isSending: viewModel.isQuickQuestionSending,
                            streamingAssistantPresentation: viewModel.quickQuestionStreamingAssistantPresentation
                        )
                    }

                    if let error = viewModel.quickQuestionError {
                        Text(error)
                            .font(.caption)
                            .foregroundStyle(SybilTheme.danger)
                            .fixedSize(horizontal: false, vertical: true)
                    }
                }
            }
            .frame(maxWidth: .infinity, alignment: .topLeading)
            .padding(14)
        }
        .scrollDismissesKeyboard(.interactively)
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
        .background(
            RoundedRectangle(cornerRadius: 12)
                .fill(Color.black.opacity(0.36))
        )
        .overlay(
            RoundedRectangle(cornerRadius: 12)
                .stroke(SybilTheme.border.opacity(0.55), lineWidth: 1)
        )
    }

    private var composer: some View {
        VStack(alignment: .leading, spacing: 10) {
            HStack(alignment: .bottom, spacing: 10) {
                TextField(
                    "Ask anything...",
                    text: Binding(
                        get: { viewModel.quickQuestionPrompt },
                        set: { viewModel.updateQuickQuestionPrompt($0) }
                    ),
                    selection: $promptSelection,
                    axis: .horizontal
                )
                .focused($promptFocused)
                .font(.body)
                .textInputAutocapitalization(.sentences)
                .autocorrectionDisabled(false)
                .submitLabel(.send)
                .onSubmit(submitQuestion)
                .padding(.horizontal, 12)
                .padding(.vertical, 10)
                .background(
                    RoundedRectangle(cornerRadius: 12)
                        .fill(SybilTheme.composerGradient)
                        .opacity(0.98)
                )
                .foregroundStyle(SybilTheme.text)

                Button(action: submitQuestion) {
                    Image(systemName: "arrow.up")
                        .font(.body.weight(.semibold))
                        .frame(width: 40, height: 40)
                        .background(
                            Circle()
                                .fill(
                                    viewModel.canSendQuickQuestion
                                        ? AnyShapeStyle(SybilTheme.primaryGradient)
                                        : AnyShapeStyle(SybilTheme.surfaceStrong.opacity(0.92))
                                )
                        )
                        .foregroundStyle(viewModel.canSendQuickQuestion ? SybilTheme.text : SybilTheme.textMuted)
                }
                .buttonStyle(.plain)
                .disabled(!viewModel.canSendQuickQuestion)
                .accessibilityLabel("Ask quick question")
            }

            controlsRow
        }
    }

    private var convertButton: some View {
        Button {
            Task {
                let didConvert = await viewModel.convertQuickQuestionToChat()
                if didConvert {
                    dismiss()
                }
            }
        } label: {
            Label("Chat", systemImage: "bubble.left")
                .font(.caption.weight(.medium))
                .lineLimit(1)
                .minimumScaleFactor(0.8)
        }
        .buttonStyle(.plain)
        .foregroundStyle(viewModel.canConvertQuickQuestion ? SybilTheme.text : SybilTheme.textMuted)
        .padding(.horizontal, 10)
        .frame(maxWidth: .infinity, minHeight: 40)
        .background(
            RoundedRectangle(cornerRadius: 12)
                .fill(SybilTheme.surfaceStrong.opacity(0.78))
                .overlay(
                    RoundedRectangle(cornerRadius: 12)
                        .stroke(SybilTheme.border.opacity(0.78), lineWidth: 1)
                )
        )
        .disabled(!viewModel.canConvertQuickQuestion)
    }

    private var controlsRow: some View {
        HStack(alignment: .center, spacing: 10) {
            providerMenu
            modelMenu
            convertButton
        }
    }

    private var providerMenu: some View {
        Menu {
            ForEach(viewModel.providerOptions, id: \.self) { provider in
                Button {
                    viewModel.setQuickQuestionProvider(provider)
                } label: {
                    if viewModel.quickQuestionProvider == provider {
                        Label(provider.displayName, systemImage: "checkmark")
                    } else {
                        Text(provider.displayName)
                    }
                }
            }
        } label: {
            QuickQuestionPickerPill(title: viewModel.quickQuestionProvider.displayName)
        }
        .frame(maxWidth: .infinity)
        .disabled(viewModel.isQuickQuestionSending || viewModel.isConvertingQuickQuestion)
        .accessibilityLabel("Quick question provider")
    }

    private var modelMenu: some View {
        Menu {
            if viewModel.quickQuestionProviderModelOptions.isEmpty {
                Text("No models")
            } else {
                ForEach(viewModel.quickQuestionProviderModelOptions, id: \.self) { model in
                    Button {
                        viewModel.setQuickQuestionModel(model)
                    } label: {
                        if viewModel.quickQuestionModel == model {
                            Label(model, systemImage: "checkmark")
                        } else {
                            Text(model)
                        }
                    }
                }
            }
        } label: {
            QuickQuestionPickerPill(title: viewModel.quickQuestionModel.isEmpty ? "No model" : viewModel.quickQuestionModel)
        }
        .frame(maxWidth: .infinity)
        .disabled(viewModel.isQuickQuestionSending || viewModel.isConvertingQuickQuestion)
        .accessibilityLabel("Quick question model")
    }

    private func submitQuestion() {
        guard viewModel.canSendQuickQuestion else {
            return
        }

        promptFocused = false
        _ = viewModel.sendQuickQuestion()
    }
}

private struct QuickQuestionPickerPill: View {
    var title: String

    var body: some View {
        HStack(spacing: 8) {
            Text(title)
                .font(.caption.weight(.medium))
                .foregroundStyle(SybilTheme.text)
                .lineLimit(1)
                .minimumScaleFactor(0.8)

            Image(systemName: "chevron.down")
                .font(.caption.weight(.semibold))
                .foregroundStyle(SybilTheme.textMuted)
        }
        .padding(.horizontal, 10)
        .frame(maxWidth: .infinity, minHeight: 40)
        .background(
            RoundedRectangle(cornerRadius: 12)
                .fill(SybilTheme.surfaceStrong.opacity(0.78))
                .overlay(
                    RoundedRectangle(cornerRadius: 12)
                        .stroke(SybilTheme.border.opacity(0.78), lineWidth: 1)
                )
        )
    }
}

private struct QuickQuestionMessageView: View {
    var message: Message
    var isSending: Bool
    var streamingAssistantPresentation: StreamingAssistantPresentation?

    private var matchingStreamingAssistantPresentation: StreamingAssistantPresentation? {
        guard streamingAssistantPresentation?.messageID == message.id else { return nil }
        return streamingAssistantPresentation
    }

    var body: some View {
        if let metadata = message.toolCallMetadata {
            Text(toolCallSummary(for: metadata, fallbackContent: message.content))
                .font(.caption)
                .foregroundStyle(SybilTheme.textMuted)
                .fixedSize(horizontal: false, vertical: true)
        } else if message.id.hasPrefix("temp-assistant-quick-") {
            StreamingAssistantContentView(
                content: message.content,
                isSending: isSending,
                presentation: matchingStreamingAssistantPresentation
            )
        } else if !message.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            Markdown(message.content)
                .font(.body)
                .tint(SybilTheme.primary)
                .foregroundStyle(SybilTheme.text.opacity(0.96))
                .textSelection(.enabled)
        }
    }

    private func toolCallSummary(for metadata: ToolCallMetadata, fallbackContent: String) -> String {
        if let summary = metadata.summary?.trimmingCharacters(in: .whitespacesAndNewlines), !summary.isEmpty {
            return summary
        }
        if !fallbackContent.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            return fallbackContent
        }
        return "Ran \(metadata.toolName ?? "tool")."
    }
}
