#if os(iOS) || os(macOS)
    import Foundation
    import Library
    import SwiftUI

    @MainActor
    public struct EditProfileContentView: View {
        #if os(macOS)
            public static let windowID = "edit-profile-content"
        #endif

        public struct Context: Codable, Hashable {
            public let profileID: Int64
            public let readOnly: Bool
        }

        private let profileID: Int64?
        private let readOnly: Bool

        public init(_ context: Context?) {
            profileID = context?.profileID
            readOnly = context?.readOnly == true
        }

        @Environment(\.dismiss) private var dismiss

        @State private var isLoading = true
        @State private var profile: Profile!
        @State private var profileContent: String = ""
        @State private var isChanged = false
        @State private var alert: Alert?

        public var body: some View {
            viewBuilder {
                if isLoading {
                    ProgressView().onAppear {
                        Task {
                            await loadContent()
                        }
                    }
                } else {
                    viewBuilder {
                        if readOnly {
                            TextEditor(text: .constant(profileContent))
                        } else {
                            TextEditor(text: $profileContent)
                        }
                    }
                    .font(Font.system(.caption2, design: .monospaced))
                    .autocorrectionDisabled(true)
                    // https://stackoverflow.com/questions/66721935/swiftui-how-to-disable-the-smart-quotes-in-texteditor
                    // https://stackoverflow.com/questions/74034171/textfield-with-autocorrectiondisabled-still-shows-predictive-text-bar
                    .textContentType(.init(rawValue: ""))
                    #if os(iOS)
                        .keyboardType(.asciiCapable)
                        .textInputAutocapitalization(.none)
                        .background(Color(UIColor.secondarySystemGroupedBackground))
                    #elseif os(macOS)
                        .padding()
                    #endif
                        .onChangeCompat(of: profileContent) {
                            isChanged = true
                        }
                }
            }
            .alertBinding($alert)
            .navigationTitle(navigationTitle)
            #if os(macOS)
                .toolbar {
                    ToolbarItemGroup(placement: .navigation) {
                        if !readOnly {
                            Button {
                                Task {
                                    await saveContent()
                                }
                            } label: {
                                Image("save", label: Text("Save"))
                            }
                            .disabled(!isChanged)
                        }
                    }
                }
            #elseif os(iOS)
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        if !readOnly {
                            Button("Save") {
                                Task {
                                    await saveContent()
                                }
                            }.disabled(!isChanged)
                        }
                    }
                }
                .navigationBarTitleDisplayMode(.inline)
            #endif
        }

        private var navigationTitle: String {
            if readOnly {
                return "View Content"
            } else {
                return "Edit Content"
            }
        }

        private func loadContent() async {
            do {
                try await loadContentBackground()
            } catch {
                alert = Alert(error)
            }
            isLoading = false
        }

        private nonisolated func loadContentBackground() async throws {
            guard let profileID else {
                throw NSError(domain: "Context destroyed", code: 0)
            }
            guard let profile = try await ProfileManager.get(profileID) else {
                throw NSError(domain: "Profile missing", code: 0)
            }
            let profileContent = try profile.read()
            await MainActor.run {
                self.profile = profile
                self.profileContent = profileContent
            }
        }

        private func saveContent() async {
            guard let profile else {
                return
            }
            do {
                try await saveContentBackground(profile)
            } catch {
                alert = Alert(error)
                return
            }
            isChanged = false
        }

        private nonisolated func saveContentBackground(_ profile: Profile) async throws {
            try await profile.write(profileContent)
        }
    }

#endif
