import SwiftData
import SwiftUI

struct ChatView: View {
    @Environment(ConnectionManager.self) private var manager
    @State private var selectedBuffer: String = "global"
    @State private var showSettings = false
    @State private var selectedDMPartner: String?

    var body: some View {
        NavigationStack {
            TabView(selection: $selectedBuffer) {
                ForEach(manager.buffers) { buffer in
                    if buffer.name == "direct-messages" {
                        Tab(buffer.displayName, systemImage: iconForBuffer(buffer.name), value: buffer.name) {
                            DMListView(selectedConversation: $selectedDMPartner)
                        }
                    } else {
                        Tab(buffer.displayName, systemImage: iconForBuffer(buffer.name), value: buffer.name) {
                            ChatBufferView(bufferName: buffer.name, canSend: canSend(buffer)) { message in
                                navigateToDM(message)
                            }
                        }
                    }
                }
            }
            .navigationTitle(titleForBuffer(selectedBuffer))
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Menu("More", systemImage: "ellipsis.circle") {
                        Button("Switch Character", systemImage: "person.2") {
                            manager.switchCharacter()
                        }
                        Button("Settings", systemImage: "gearshape") {
                            showSettings = true
                        }
                        Button("Log Out", systemImage: "rectangle.portrait.and.arrow.right", role: .destructive) {
                            manager.logout()
                        }
                    }
                }
            }
            .navigationDestination(isPresented: $showSettings) {
                SettingsView()
            }
            .navigationDestination(for: String.self) { partnerId in
                let name = partnerName(for: partnerId)
                DMConversationView(partnerId: partnerId, partnerName: name)
            }
            .onChange(of: selectedBuffer) {
                manager.activeBuffer = selectedBuffer
            }
        }
    }

    private func canSend(_ buffer: ChatBuffer) -> Bool {
        if buffer.name == "direct-messages" { return true }
        return buffer.canSend
    }

    private func titleForBuffer(_ name: String) -> String {
        switch name {
        case "global": "Kirandur Global Chat"
        case "map": "Kirandur Map Chat"
        case "debug": "Kirandur Debug Output"
        case "direct-messages": "Kirandur DMs"
        default: "Kirandur \(name.capitalized)"
        }
    }

    private func iconForBuffer(_ name: String) -> String {
        switch name {
        case "global": "globe"
        case "map": "map"
        case "debug": "ladybug"
        case "direct-messages": "envelope"
        default: "bubble.left"
        }
    }

    @Environment(\.modelContext) private var modelContext

    private func partnerName(for partnerId: String) -> String {
        let descriptor = FetchDescriptor<SavedMessage>(
            predicate: #Predicate { $0.buffer == "direct-messages" && $0.senderId == partnerId }
        )
        let results = (try? modelContext.fetch(descriptor)) ?? []
        return results.first?.senderName ?? partnerId
    }

    private func navigateToDM(_ message: SavedMessage) {
        guard let senderId = message.senderId else { return }
        selectedBuffer = "direct-messages"
        selectedDMPartner = senderId
    }
}
