import SwiftUI
import NucleicProtocol

/// The to-do inbox (mirrors the Mac's idea inbox): capture ideas, group by project, then
/// complete, dispatch (start an agent), or delete each — all control scope.
struct TodosView: View {
    @EnvironmentObject var store: RemoteStore
    @State private var draft = ""

    private var open: [WireTodo] { store.dashboard.todos.filter { $0.status != .done } }

    /// Group open todos by project name ("Unassigned" bucket last).
    private var groups: [(name: String, todos: [WireTodo])] {
        let byProject = Dictionary(grouping: open) { $0.projectName ?? "Unassigned" }
        return byProject
            .map { ($0.key, $0.value.sorted { $0.updatedAt > $1.updatedAt }) }
            .sorted { ($0.name == "Unassigned" ? "zzz" : $0.name) < ($1.name == "Unassigned" ? "zzz" : $1.name) }
    }

    var body: some View {
        NavigationStack {
            List {
                Section {
                    HStack {
                        TextField("Capture an idea…", text: $draft)
                            .textFieldStyle(.roundedBorder)
                            .onSubmit(capture)
                            .keyboardDismissable()
                        Button(action: capture) { Image(systemName: "plus.circle.fill").font(.title3) }
                            .disabled(draft.trimmingCharacters(in: .whitespaces).isEmpty || !store.canControl)
                    }
                }
                if open.isEmpty {
                    ContentUnavailableView("Inbox zero", systemImage: "checkmark.circle",
                        description: Text("Capture an idea above to dispatch later."))
                }
                ForEach(groups, id: \.name) { group in
                    Section(group.name.uppercased()) {
                        ForEach(group.todos) { todo in TodoRow(todo: todo) }
                    }
                }
            }
            .navigationTitle("To-dos")
            .scrollDismissesKeyboard(.interactively)
            .refreshable { store.refreshSessions() }
        }
    }

    private func capture() {
        store.captureTodo(draft, projectID: nil)
        draft = ""
    }
}

private struct TodoRow: View {
    @EnvironmentObject var store: RemoteStore
    let todo: WireTodo

    var body: some View {
        HStack(spacing: 10) {
            Button { store.completeTodo(todo.id) } label: {
                Image(systemName: todo.status == .dispatched ? "circle.dashed" : "circle")
                    .foregroundStyle(.secondary)
            }.buttonStyle(.plain)
            VStack(alignment: .leading, spacing: 2) {
                Text(todo.summary?.isEmpty == false ? todo.summary! : todo.text)
                    .font(.subheadline).lineLimit(2)
                if todo.status == .dispatched {
                    Text("Dispatched").font(.caption2).foregroundStyle(Palette.active)
                }
            }
            Spacer()
            dispatchButton
        }
        .swipeActions {
            Button(role: .destructive) { store.deleteTodo(todo.id) } label: {
                Label("Delete", systemImage: "trash")
            }
        }
    }

    /// Dispatch to the todo's project, or pick one if unassigned.
    @ViewBuilder
    private var dispatchButton: some View {
        if todo.status == .open && store.canControl {
            if let pid = todo.projectID {
                Button { store.dispatchTodo(todo.id, in: pid) } label: {
                    Image(systemName: "play.circle.fill").foregroundStyle(Palette.accent)
                }.buttonStyle(.plain)
            } else if !store.dashboard.projects.isEmpty {
                Menu {
                    ForEach(store.dashboard.projects) { project in
                        Button(project.name) { store.dispatchTodo(todo.id, in: project.id) }
                    }
                } label: {
                    Image(systemName: "play.circle").foregroundStyle(Palette.accent)
                }
            }
        }
    }
}
