import SwiftUI
import NucleicProtocol

/// Projects overview (mirrors the Mac's per-project pages): each project with its session
/// counts; tap through to that project's sessions + a scoped composer.
struct ProjectsView: View {
    @EnvironmentObject var store: RemoteStore
    @State private var showAddProject = false

    var body: some View {
        NavigationStack {
            Group {
                if store.dashboard.projects.isEmpty {
                    ContentUnavailableView {
                        Label("No projects", systemImage: "folder")
                    } description: {
                        Text(store.canCreateProject
                            ? "Add a project here, or on the Mac."
                            : "Add a project on the Mac to see it here.")
                    } actions: {
                        if store.canCreateProject {
                            Button("Add Project") { showAddProject = true }
                        }
                    }
                } else {
                    List(store.dashboard.projects) { project in
                        NavigationLink {
                            ProjectDetailView(project: project)
                        } label: {
                            HStack(spacing: 12) {
                                Image(systemName: "folder.fill").foregroundStyle(Palette.accent)
                                VStack(alignment: .leading, spacing: 2) {
                                    Text(project.name).font(.body.weight(.medium))
                                    Text(project.defaultBranch).font(.caption).foregroundStyle(.secondary)
                                }
                                Spacer()
                                if project.activeCount > 0 {
                                    Text("\(project.activeCount) active")
                                        .font(.caption2.bold())
                                        .padding(.horizontal, 7).padding(.vertical, 3)
                                        .background(Palette.active.opacity(0.18), in: Capsule())
                                        .foregroundStyle(Palette.active)
                                }
                                Text("\(project.sessionCount)").foregroundStyle(.secondary)
                            }
                        }
                    }
                    .compactTabBarInset()
                }
            }
            .navigationTitle("Projects")
            .refreshable { store.refreshSessions() }
            .toolbar {
                // "Add a project" (CLOUD_RUNTIME §4.3): clone a git URL on a connected host —
                // how a fresh Covalence runner gets its first project. Hidden when no live
                // host advertises `canCreateProjects` (an older Mac would reject the verb).
                if store.canCreateProject {
                    ToolbarItem(placement: .primaryAction) {
                        Button { showAddProject = true } label: {
                            Label("Add Project", systemImage: "plus")
                        }
                    }
                }
            }
            .sheet(isPresented: $showAddProject) {
                AddProjectSheet()
            }
        }
    }
}

/// Clone-and-register a project on a connected host: git URL (+ optional name/branch) and,
/// with more than one capable host, a destination picker. The request settles asynchronously
/// (`RemoteStore.addProject`); the sheet shows progress, the failure message, or dismisses on
/// success — the new project row arrives via the dashboard push.
private struct AddProjectSheet: View {
    @EnvironmentObject var store: RemoteStore
    @Environment(\.dismiss) private var dismiss
    @State private var gitURL = ""
    @State private var name = ""
    @State private var branch = ""
    @State private var hostID: String?

    private var hosts: [(hostID: String, name: String)] { store.projectCreationHosts }
    private var creating: Bool { store.addProject == .creating }
    private var canSubmit: Bool {
        !gitURL.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !creating
    }

    var body: some View {
        NavigationStack {
            Form {
                Section {
                    TextField("Git URL", text: $gitURL, prompt: Text("https://github.com/you/repo"))
                        .textContentType(.URL)
                        .keyboardType(.URL)
                        .textInputAutocapitalization(.never)
                        .autocorrectionDisabled()
                } footer: {
                    Text("The host clones this repository and manages the checkout itself.")
                }
                Section("Options") {
                    TextField("Name (optional)", text: $name)
                    TextField("Branch (optional)", text: $branch)
                        .textInputAutocapitalization(.never)
                        .autocorrectionDisabled()
                }
                if hosts.count > 1 {
                    Section("Create on") {
                        Picker("Host", selection: $hostID) {
                            ForEach(hosts, id: \.hostID) { host in
                                Text(host.name).tag(Optional(host.hostID))
                            }
                        }
                    }
                }
                if case .failed(let message) = store.addProject {
                    Section {
                        Label(message, systemImage: "exclamationmark.triangle")
                            .foregroundStyle(.red)
                    }
                }
            }
            .navigationTitle("Add Project")
            .navigationBarTitleDisplayMode(.inline)
            .interactiveDismissDisabled(creating)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }.disabled(creating)
                }
                ToolbarItem(placement: .confirmationAction) {
                    if creating {
                        ProgressView()
                    } else {
                        Button("Create") {
                            store.createProject(
                                gitURL: gitURL.trimmingCharacters(in: .whitespacesAndNewlines),
                                name: name, branch: branch, onHost: hostID)
                        }
                        .disabled(!canSubmit)
                    }
                }
            }
            .onAppear { if hostID == nil { hostID = hosts.first?.hostID } }
            .onChange(of: store.addProject) { _, state in
                if case .created = state { dismiss() }
            }
            .onDisappear { store.resetAddProject() }
        }
        .presentationDetents([.medium])
    }
}

struct ProjectDetailView: View {
    @EnvironmentObject var store: RemoteStore
    @Environment(\.horizontalSizeClass) private var sizeClass
    let project: WireProject
    @State private var showNewChat = false

    private var sessions: [WireSessionSummary] {
        store.liveSessions
            .filter { $0.projectID == project.id.rawValue }
            .sorted(by: StatusStyle.attentionThenRecency)
    }

    var body: some View {
        List {
            Section("Sessions") {
                if sessions.isEmpty {
                    Text("No sessions yet.").foregroundStyle(.secondary)
                }
                ForEach(sessions, id: \.sessionID) { summary in
                    NavigationLink {
                        SessionDetailView(sessionID: summary.sessionID)
                    } label: { SessionRow(summary: summary, showProjectName: false) }
                }
            }
        }
        .navigationTitle(project.name)
        .navigationBarTitleDisplayMode(.inline)
        .scrollDismissesKeyboard(.interactively)
        .compactTabBarInset()
        // A floating "+" scoped to this project — the glass composer opens pre-locked to it. Only
        // at regular width; on compact the shared tab-bar "+" (project picker) covers new chats.
        .newChatAffordance(project: project, isPresented: $showNewChat, enabled: sizeClass == .regular)
    }
}
