import SwiftData
import SwiftUI

struct ChatBufferView: View {
    let bufferName: String
    let canSend: Bool
    var onDM: ((SavedMessage) -> Void)?
    @Environment(ConnectionManager.self) private var manager
    @Environment(\.modelContext) private var modelContext
    @Query private var messages: [SavedMessage]
    @State private var messageText = ""
    @FocusState private var isInputFocused: Bool

    init(bufferName: String, canSend: Bool, onDM: ((SavedMessage) -> Void)? = nil) {
        self.bufferName = bufferName
        self.canSend = canSend
        self.onDM = onDM

        let buf = bufferName
        _messages = Query(
            filter: #Predicate<SavedMessage> { $0.buffer == buf },
            sort: \.timestamp
        )
    }

    var body: some View {
        VStack(spacing: 0) {
            ScrollViewReader { proxy in
                ScrollView {
                    LazyVStack(alignment: .leading, spacing: 12) {
                        ForEach(messages) { message in
                            MessageRow(
                                message: message,
                                onDM: onDM
                            )
                            .id(message.persistentModelID)
                        }
                    }
                    .padding()
                }
                .onChange(of: isInputFocused) { _, focused in
                    if focused, let last = messages.last {
                        proxy.scrollTo(last.persistentModelID, anchor: .bottom)
                    }
                }
                .onChange(of: messages.count) {
                    guard let last = messages.last, last.sessionId == manager.sessionId else { return }
                    Task { @MainActor in
                        proxy.scrollTo(last.persistentModelID, anchor: .bottom)
                    }

                    let isActive = bufferName == manager.activeBuffer
                    let playBackground = UserDefaults.standard.bool(forKey: "sounds_background_buffers", default: true)

                    // Sound — plays for active buffer, or background if enabled
                    if isActive || playBackground {
                        playBufferSound()
                    }

                    // Announce + haptic
                    let announceOther = UserDefaults.standard.bool(forKey: "announce_other_buffers")
                    if isActive || announceOther {
                        if !last.isSystem {
                            AccessibilityNotification.Announcement(
                                "\(last.senderName): \(last.content)"
                            ).post()
                        }
                        if UserDefaults.standard.bool(forKey: "haptics_enabled", default: true),
                           UserDefaults.standard.bool(forKey: "haptics_messages", default: true) {
                            UIImpactFeedbackGenerator(style: .soft).impactOccurred()
                        }
                    }
                }
            }

            if canSend {
                HStack(spacing: 8) {
                    TextField("Message...", text: $messageText, axis: .vertical)
                        .focused($isInputFocused)
                        .textFieldStyle(.roundedBorder)
                        .lineLimit(1...4)
                        .onSubmit { sendMessage() }
                        .toolbar {
                            ToolbarItemGroup(placement: .keyboard) {
                                Button("/command", systemImage: "slash.circle") {
                                    if !messageText.hasPrefix("/") {
                                        messageText = "/" + messageText
                                    }
                                }
                                .labelStyle(.titleAndIcon)
                                Spacer()
                            }
                        }

                    Button("Send", systemImage: "arrow.up.circle.fill", action: sendMessage)
                        .labelStyle(.iconOnly)
                        .font(.title)
                        .buttonStyle(.borderedProminent)
                        .buttonBorderShape(.circle)
                        .disabled(messageText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
                }
                .padding(.horizontal)
                .padding(.vertical, 8)
                .background(.bar)
            }
        }
    }

    private func sendMessage() {
        let text = messageText.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !text.isEmpty else { return }

        manager.sendChatMessage(buffer: bufferName, content: text)
        messageText = ""
        isInputFocused = true
    }

    private func playBufferSound() {
        guard UserDefaults.standard.bool(forKey: "sounds_enabled", default: true) else { return }
        switch bufferName {
        case "global":
            guard UserDefaults.standard.bool(forKey: "sounds_global", default: true) else { return }
            SoundPlayer.play("global")
        case "map":
            guard UserDefaults.standard.bool(forKey: "sounds_map", default: true) else { return }
            SoundPlayer.play("map")
        case "direct-messages":
            guard UserDefaults.standard.bool(forKey: "sounds_dm", default: true) else { return }
            SoundPlayer.play("direct-message")
        default:
            break
        }
    }
}
