import SwiftUI

struct WorkspaceSwitcherView: View {
    @ObservedObject var screen: ScreenContext
    let orchestrator: NotchOrchestrator
    @ObservedObject private var screenRegistry = ScreenRegistry.shared
    @ObservedObject private var workspaceRegistry = WorkspaceRegistry.shared

    @State private var isRenameAlertPresented = false
    @State private var isDeleteConfirmationPresented = false
    @State private var renameDraft = ""

    private var currentWorkspaceSummary: WorkspaceSummary {
        workspaceRegistry.summary(for: screen.workspaceID)
            ?? workspaceRegistry.allWorkspaceSummaries().first
            ?? WorkspaceSummary(id: screen.workspaceID, name: "Workspace")
    }

    private var deletionFallbackSummary: WorkspaceSummary? {
        guard let fallbackWorkspaceID = workspaceRegistry.deletionFallbackWorkspaceID(
            forDeleting: screen.workspaceID,
            preferredFallback: workspaceRegistry.defaultWorkspaceID
        ) else {
            return nil
        }

        return workspaceRegistry.summary(for: fallbackWorkspaceID)
    }

    private var assignedScreenCount: Int {
        screenRegistry.assignedScreenCount(to: screen.workspaceID)
    }

    var body: some View {
        Menu {
            ForEach(workspaceRegistry.workspaceSummaries) { summary in
                Button {
                    selectWorkspace(summary.id)
                } label: {
                    if summary.id == screen.workspaceID {
                        Label(summary.name, systemImage: "checkmark")
                    } else {
                        Text(summary.name)
                    }
                }
            }

            Divider()

            Button("New Workspace") {
                let workspaceID = workspaceRegistry.createWorkspace()
                selectWorkspace(workspaceID)
            }

            Button("Rename Current Workspace") {
                renameDraft = currentWorkspaceSummary.name
                syncFocusLossSuppression(renamePresented: true, deletePresented: isDeleteConfirmationPresented)
                isRenameAlertPresented = true
            }

            Button("Delete Current Workspace", role: .destructive) {
                syncFocusLossSuppression(renamePresented: isRenameAlertPresented, deletePresented: true)
                isDeleteConfirmationPresented = true
            }
            .disabled(!workspaceRegistry.canDeleteWorkspace(id: screen.workspaceID))
        } label: {
            switcherLabel
        }
        .menuStyle(.borderlessButton)
        .accessibilityIdentifier("notch.workspace-switcher")
        .accessibilityLabel("Workspace Switcher")
        .accessibilityValue(currentWorkspaceSummary.name)
        .fixedSize(horizontal: false, vertical: true)
        .help("Switch workspace for this screen")
        .alert("Rename Workspace", isPresented: $isRenameAlertPresented) {
            TextField("Workspace name", text: $renameDraft)
            Button("Cancel", role: .cancel) {}
            Button("Save") {
                workspaceRegistry.renameWorkspace(id: screen.workspaceID, to: renameDraft)
            }
        } message: {
            Text("This only renames the shared workspace. Screens assigned to it keep following the new name.")
        }
        .confirmationDialog("Delete Workspace", isPresented: $isDeleteConfirmationPresented, titleVisibility: .visible) {
            Button("Delete Workspace", role: .destructive) {
                deleteCurrentWorkspace()
            }
        } message: {
            Text(deleteMessage)
        }
        .onChange(of: isRenameAlertPresented) { _, isPresented in
            syncFocusLossSuppression(renamePresented: isPresented, deletePresented: isDeleteConfirmationPresented)
        }
        .onChange(of: isDeleteConfirmationPresented) { _, isPresented in
            syncFocusLossSuppression(renamePresented: isRenameAlertPresented, deletePresented: isPresented)
        }
        .onDisappear {
            screen.setCloseOnFocusLossSuppressed(false)
        }
    }

    private var deleteMessage: String {
        if let fallback = deletionFallbackSummary {
            return "This reassigns \(assignedScreenCount) screen\(assignedScreenCount == 1 ? "" : "s") to \(fallback.name) and closes this workspace."
        }

        return "At least one workspace must remain."
    }

    private var switcherLabel: some View {
        HStack(spacing: 6) {
            Image(systemName: "rectangle.3.group")
                .font(.system(size: 11, weight: .medium))
            Text(currentWorkspaceSummary.name)
                .font(.system(size: 11, weight: .medium))
                .lineLimit(1)
            Image(systemName: "chevron.down")
                .font(.system(size: 9, weight: .semibold))
        }
        .foregroundStyle(.white.opacity(0.7))
        .padding(.horizontal, 8)
        .padding(.vertical, 4)
        .background(
            RoundedRectangle(cornerRadius: 8)
                .fill(Color.white.opacity(0.08))
        )
        .contentShape(Rectangle())
        .accessibilityElement(children: .ignore)
        .accessibilityLabel("Workspace Switcher")
        .accessibilityValue(currentWorkspaceSummary.name)
        .accessibilityIdentifier("notch.workspace-switcher")
    }

    private func selectWorkspace(_ workspaceID: WorkspaceID) {
        screenRegistry.assignWorkspace(workspaceID, to: screen.id)

        if screen.notchState == .open {
            orchestrator.open(screenID: screen.id)
        }
    }

    private func deleteCurrentWorkspace() {
        guard let fallback = screenRegistry.deleteWorkspace(
            screen.workspaceID,
            preferredFallback: workspaceRegistry.defaultWorkspaceID
        ) else {
            return
        }

        screenRegistry.assignWorkspace(fallback, to: screen.id)
        if screen.notchState == .open {
            orchestrator.open(screenID: screen.id)
        } else {
            screen.requestTerminalFocus?()
        }
    }

    private func syncFocusLossSuppression(renamePresented: Bool, deletePresented: Bool) {
        screen.setCloseOnFocusLossSuppressed(renamePresented || deletePresented)
    }
}
