import Foundation
import SwiftUI
import SaplingCore
import SaplingRenderer

#if os(macOS)
import AppKit
#elseif os(iOS)
import UIKit
#endif

@MainActor
public final class HybridMarkdownEditorViewModel: ObservableObject, EditorCoordinator {
    @Published public private(set) var state: EditorState
    public private(set) var instrumentation = EditorInstrumentationSnapshot()

    public init(document: MarkdownDocument, activeLineIndex: Int = 0) {
        self.state = EditorState(
            document: EditorDocument(markdownDocument: document),
            activeLineIndex: activeLineIndex
        )
    }

    public var document: MarkdownDocument {
        state.document.markdownDocument
    }

    public var hasUnsavedChanges: Bool {
        state.hasUnsavedChanges
    }

    public var activeLineIndex: Int {
        state.activeLineIndex
    }

    public var lineIndex: DocumentLineIndex {
        state.lineIndex
    }

    public func replaceDocument(_ document: EditorDocument) {
        state = EditorState(document: document)
        instrumentation = EditorInstrumentationSnapshot()
    }

    public func updateSource(_ source: String) {
        guard state.document.source != source else { return }
        let previousActiveLineIndex = state.activeLineIndex
        state.updateSource(source)
        instrumentation.recordSourceChange()
        recordActiveLineChangeIfNeeded(previousActiveLineIndex)
    }

    public func updateSource(_ source: String, edit: DocumentLineIndexEdit?, selection: EditorSelection? = nil) {
        guard state.document.source != source else { return }
        let previousActiveLineIndex = state.activeLineIndex
        if let edit {
            state.updateSource(source, edit: edit, selection: selection)
        } else {
            state.updateSource(source)
            if let selection {
                state.updateSelection(selection)
            }
        }
        instrumentation.recordSourceChange()
        recordActiveLineChangeIfNeeded(previousActiveLineIndex)
    }

    public func updateSelection(_ selection: EditorSelection) {
        guard state.selection != selection else { return }
        let previousActiveLineIndex = state.activeLineIndex
        state.updateSelection(selection)
        instrumentation.recordSelectionChange()
        recordActiveLineChangeIfNeeded(previousActiveLineIndex)
    }

    public func recordRenderPass(_ metric: EditorRenderPassMetric) {
        instrumentation.recordRenderPass(metric)
        #if DEBUG
        EditorDiagnostics.logRenderPass(metric)
        #endif
    }

    public func save() throws {
        try state.document.source.write(to: state.document.url, atomically: true, encoding: .utf8)
        state.markSaved()
    }

    public static func loadDocument(at url: URL) throws -> MarkdownDocument {
        let source = try String(contentsOf: url, encoding: .utf8)
        let title = url.deletingPathExtension().lastPathComponent
        return MarkdownDocument(url: url, title: title, content: source)
    }

    private func recordActiveLineChangeIfNeeded(_ previousActiveLineIndex: Int) {
        if previousActiveLineIndex != state.activeLineIndex {
            instrumentation.recordActiveLineChange()
        }
    }
}

public struct HybridMarkdownEditor: View, EditorView {
    @ObservedObject private var viewModel: HybridMarkdownEditorViewModel
    private let renderer: any MarkdownRendering

    public init(
        viewModel: HybridMarkdownEditorViewModel,
        renderer: any MarkdownRendering = MarkdownRenderer()
    ) {
        self.viewModel = viewModel
        self.renderer = renderer
    }

    public var state: EditorState {
        viewModel.state
    }

    public var body: some View {
        VStack(spacing: 0) {
            NativeMarkdownTextView(
                text: Binding(
                    get: { viewModel.state.document.source },
                    set: { viewModel.updateSource($0) }
                ),
                selection: Binding(
                    get: { viewModel.state.selection },
                    set: { viewModel.updateSelection($0) }
                ),
                activeLineIndex: viewModel.state.activeLineIndex,
                lineIndex: viewModel.state.lineIndex,
                onTextEdit: viewModel.updateSource,
                onRenderPass: viewModel.recordRenderPass
            )
            .frame(maxWidth: .infinity, maxHeight: .infinity)

            EditorStatusBar(
                activeLineIndex: viewModel.state.activeLineIndex,
                columnNumber: viewModel.state.activeColumnNumber,
                lineCount: viewModel.state.lineCount,
                hasUnsavedChanges: viewModel.state.hasUnsavedChanges
            )
        }
        .background(platformTextBackground)
    }
}

private struct EditorStatusBar: View {
    let activeLineIndex: Int
    let columnNumber: Int
    let lineCount: Int
    let hasUnsavedChanges: Bool

    var body: some View {
        HStack(spacing: 12) {
            Text("Line \(activeLineIndex + 1)")
            Text("Column \(columnNumber)")
            Text("\(lineCount) lines")
            Text(hasUnsavedChanges ? "Modified" : "Saved")
                .foregroundStyle(hasUnsavedChanges ? .orange : .secondary)
            Spacer()
        }
        .font(.caption.weight(.medium))
        .foregroundStyle(.secondary)
        .padding(.horizontal, 14)
        .padding(.vertical, 7)
        .background(.thinMaterial)
    }
}

#if os(macOS)
private struct NativeMarkdownTextView: NSViewRepresentable {
    @Binding var text: String
    @Binding var selection: EditorSelection
    let activeLineIndex: Int
    let lineIndex: DocumentLineIndex
    let onTextEdit: (String, DocumentLineIndexEdit?, EditorSelection?) -> Void
    let onRenderPass: (EditorRenderPassMetric) -> Void

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeNSView(context: Context) -> NSScrollView {
        let scrollView = ComfortableEditorScrollView()
        scrollView.hasVerticalScroller = true
        scrollView.hasHorizontalScroller = false
        scrollView.autohidesScrollers = true
        scrollView.borderType = .noBorder
        scrollView.drawsBackground = true
        scrollView.backgroundColor = .textBackgroundColor

        let textStorage = NSTextStorage()
        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: NSSize(width: 0, height: CGFloat.greatestFiniteMagnitude))
        textContainer.widthTracksTextView = true
        textContainer.heightTracksTextView = false
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)

        let textView = EditorTextView(frame: scrollView.contentView.bounds, textContainer: textContainer)
        textView.autoresizingMask = [.width]
        textView.minSize = NSSize(width: 0, height: scrollView.contentSize.height)
        textView.maxSize = NSSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
        textView.isVerticallyResizable = true
        textView.isHorizontallyResizable = false

        textView.string = text
        textView.delegate = context.coordinator
        textView.onFocusStateChange = { [weak coordinator = context.coordinator] textView in
            coordinator?.applyHybridAttributes(to: textView)
        }
        textView.onUserEditingInteraction = { [weak coordinator = context.coordinator] textView in
            coordinator?.activateEditingPresentation(in: textView)
        }
        textView.isRichText = false
        textView.isEditable = true
        textView.isSelectable = true
        textView.isAutomaticQuoteSubstitutionEnabled = false
        textView.isAutomaticDashSubstitutionEnabled = false
        textView.isAutomaticTextReplacementEnabled = false
        textView.allowsUndo = true
        textView.usesFindPanel = true
        textView.isContinuousSpellCheckingEnabled = true
        textView.backgroundColor = .textBackgroundColor
        textView.insertionPointColor = .controlAccentColor
        textView.font = .systemFont(ofSize: 16, weight: .regular)
        textView.textContainer?.widthTracksTextView = true
        textView.textContainer?.containerSize = NSSize(
            width: scrollView.contentSize.width,
            height: CGFloat.greatestFiniteMagnitude
        )

        scrollView.documentView = textView
        scrollView.editorTextView = textView
        scrollView.onEditorLayoutInvalidated = { [weak coordinator = context.coordinator] textView in
            coordinator?.syncChecklistControlFrames(in: textView)
        }
        scrollView.updateEditorInsets()
        context.coordinator.applyHybridAttributes(to: textView)
        return scrollView
    }

    func updateNSView(_ scrollView: NSScrollView, context: Context) {
        context.coordinator.parent = self
        context.coordinator.currentLineIndex = lineIndex
        guard let textView = scrollView.documentView as? NSTextView else { return }

        if textView.string != text {
            context.coordinator.performProgrammaticUpdate {
                textView.string = text
            }
            context.coordinator.invalidateStylingCache()
        }

        let selectedRange = selection.range
        if textView.selectedRange() != selectedRange,
           selectedRange.location <= textView.string.utf16.count {
            context.coordinator.setSelection(selectedRange, in: textView)
        }

        context.coordinator.applyHybridAttributes(to: textView)
    }

    final class Coordinator: NSObject, NSTextViewDelegate {
        var parent: NativeMarkdownTextView
        var currentLineIndex: DocumentLineIndex
        private var programmaticUpdateDepth = 0
        private var lastStyledText: String?
        private var lastStyledActiveLineIndex: Int?
        private var lastStyledEditableRegion: EditableRegion?
        private var pendingEdit: DocumentLineIndexEdit?
        private var hasUserActivatedEditing = false
        private var checklistButtons: [Int: ChecklistOverlayButton] = [:]

        init(_ parent: NativeMarkdownTextView) {
            self.parent = parent
            self.currentLineIndex = parent.lineIndex
        }

        func textView(
            _ textView: NSTextView,
            shouldChangeTextIn affectedCharRange: NSRange,
            replacementString: String?
        ) -> Bool {
            pendingEdit = DocumentLineIndexEdit(
                range: affectedCharRange,
                replacement: replacementString ?? ""
            )
            return true
        }

        func textDidChange(_ notification: Notification) {
            guard !isPerformingProgrammaticUpdate else { return }
            guard let textView = notification.object as? NSTextView else { return }

            hasUserActivatedEditing = true
            let selection = EditorSelection(range: textView.selectedRange())
            let edit = pendingEdit
            if let edit {
                currentLineIndex.replace(edit, updatedSource: textView.string)
            } else {
                currentLineIndex = DocumentLineIndex(source: textView.string)
            }
            parent.onTextEdit(textView.string, edit, selection)
            parent.selection = selection
            applyHybridAttributes(to: textView)
            pendingEdit = nil
        }

        func textViewDidChangeSelection(_ notification: Notification) {
            guard !isPerformingProgrammaticUpdate else { return }
            guard let textView = notification.object as? NSTextView else { return }
            let newSelection = EditorSelection(range: textView.selectedRange())
            guard parent.selection != newSelection else { return }
            applyHybridAttributes(to: textView)
            parent.selection = newSelection
        }

        func applyHybridAttributes(to textView: NSTextView) {
            guard let textStorage = textView.textStorage else { return }
            let editableRegion = presentationEditableRegion(in: textView)
            let activeLineIndex = editableRegion.primaryLineIndex
            let invalidationPlan = invalidationPlan(for: textView.string, editableRegion: editableRegion)
            guard invalidationPlan.requiresStyling else { return }

            let selectedRange = textView.selectedRange()
            let visibleOrigin = textView.enclosingScrollView?.contentView.bounds.origin
            let start = Date()
            var stylingResult = MarkdownTextStylingResult.empty
            var didRestoreVisibleOrigin = false
            performProgrammaticUpdate {
                stylingResult = MarkdownTextStyler.apply(
                    to: textStorage,
                    lineIndex: currentLineIndex,
                    invalidationPlan: invalidationPlan,
                    activeLineIndex: activeLineIndex,
                    backgroundColor: .textBackgroundColor,
                    activeLineBackgroundColor: .controlAccentColor.withAlphaComponent(0.10),
                    textColor: .labelColor,
                    secondaryTextColor: .secondaryLabelColor,
                    accentColor: .controlAccentColor,
                    usesRenderedControls: true,
                    editableRegion: editableRegion
                )
                if textView.selectedRange() != selectedRange,
                   selectedRange.location <= textView.string.utf16.count {
                    textView.setSelectedRange(selectedRange)
                }
                didRestoreVisibleOrigin = restoreVisibleOrigin(visibleOrigin, in: textView)
            }

            lastStyledText = textView.string
            lastStyledActiveLineIndex = activeLineIndex
            lastStyledEditableRegion = editableRegion
            syncChecklistControls(
                in: textView,
                stylingResult: stylingResult,
                invalidationPlan: invalidationPlan,
                activeLineIndex: activeLineIndex
            )
            parent.onRenderPass(EditorRenderPassMetric(
                reason: invalidationPlan.reason,
                durationMilliseconds: Date().timeIntervalSince(start) * 1000,
                characterCount: textView.string.utf16.count,
                lineCount: stylingResult.totalLineCount,
                dirtyLineCount: stylingResult.styledLineCount,
                activeLineIndex: activeLineIndex,
                isFullRender: invalidationPlan.isFullRender,
                restoredScrollPosition: didRestoreVisibleOrigin
            ))
        }

        private func presentationEditableRegion(in textView: NSTextView) -> EditableRegion {
            guard hasUserActivatedEditing,
                  textView.window?.firstResponder === textView
            else { return .none() }
            return EditableRegion.selection(textView.selectedRange(), in: currentLineIndex)
        }

        func activateEditingPresentation(in textView: NSTextView) {
            guard !hasUserActivatedEditing else { return }
            hasUserActivatedEditing = true
            applyHybridAttributes(to: textView)
        }

        func setSelection(_ range: NSRange, in textView: NSTextView) {
            guard textView.selectedRange() != range else { return }
            performProgrammaticUpdate {
                textView.setSelectedRange(range)
                textView.scrollRangeToVisible(range)
            }
        }

        func performProgrammaticUpdate(_ updates: () -> Void) {
            programmaticUpdateDepth += 1
            defer {
                programmaticUpdateDepth -= 1
            }
            updates()
        }

        func invalidateStylingCache() {
            lastStyledText = nil
            lastStyledActiveLineIndex = nil
            lastStyledEditableRegion = nil
            hasUserActivatedEditing = false
            removeChecklistControls()
        }

        private var isPerformingProgrammaticUpdate: Bool {
            programmaticUpdateDepth > 0
        }

        private func invalidationPlan(for text: String, editableRegion: EditableRegion) -> EditorDirtyLineInvalidationPlan {
            let previousEditableRegion = lastStyledEditableRegion
            let plan = EditorDirtyLineInvalidator.plan(
                previousText: lastStyledText,
                currentLineIndex: currentLineIndex,
                edit: pendingEdit,
                previousActiveLineIndex: previousEditableRegion?.primaryLineIndex ?? lastStyledActiveLineIndex,
                currentActiveLineIndex: editableRegion.primaryLineIndex
            )
            return plan.includingEditableRegionTransition(
                from: previousEditableRegion,
                to: editableRegion,
                lineCount: currentLineIndex.lineCount
            )
        }

        private func syncChecklistControls(
            in textView: NSTextView,
            stylingResult: MarkdownTextStylingResult,
            invalidationPlan: EditorDirtyLineInvalidationPlan,
            activeLineIndex: Int
        ) {
            let shouldRebuildAll = invalidationPlan.isFullRender || invalidationPlan.reason == .sourceChange
            let renderedTasks = shouldRebuildAll
                ? DocumentPresentationState.renderedTasks(in: currentLineIndex, activeLineIndex: activeLineIndex)
                : stylingResult.renderedTasks
            let tasksByLine = Dictionary(uniqueKeysWithValues: renderedTasks.map { ($0.lineIndex, $0) })

            if shouldRebuildAll {
                let validLineIndexes = Set(tasksByLine.keys)
                for lineIndex in Array(checklistButtons.keys) where !validLineIndexes.contains(lineIndex) {
                    removeChecklistControl(at: lineIndex)
                }
            } else {
                for lineIndex in stylingResult.styledLineIndexes where tasksByLine[lineIndex] == nil {
                    removeChecklistControl(at: lineIndex)
                }
            }

            for task in renderedTasks {
                let button = checklistButtons[task.lineIndex] ?? ChecklistOverlayButton()
                button.task = task
                button.onToggle = { [weak self, weak textView, weak button] in
                    guard let task = button?.task,
                          let textView
                    else { return }
                    self?.toggleTask(task, in: textView)
                }
                button.state = task.checked ? .on : .off
                button.toolTip = task.checked ? "Mark task incomplete" : "Mark task complete"
                if button.superview !== textView {
                    textView.addSubview(button)
                }
                checklistButtons[task.lineIndex] = button
            }

            syncChecklistControlFrames(in: textView)
        }

        func syncChecklistControlFrames(in textView: NSTextView) {
            guard !checklistButtons.isEmpty else { return }

            for (lineIndex, button) in Array(checklistButtons) {
                guard let task = button.task,
                      let frame = checklistFrame(for: task, in: textView)
                else {
                    removeChecklistControl(at: lineIndex)
                    continue
                }
                button.frame = frame
            }
        }

        private func toggleTask(_ task: RenderedTaskElement, in textView: NSTextView) {
            guard task.checkboxRange.upperBound <= textView.string.utf16.count else { return }

            let preservedSelection = textView.selectedRange()
            let wasFirstResponder = textView.window?.firstResponder === textView
            let replacement = task.toggledMarkdownCheckbox
            let edit = DocumentLineIndexEdit(range: task.checkboxRange, replacement: replacement)
            let previousPendingEdit = pendingEdit
            pendingEdit = nil
            guard textView.shouldChangeText(in: task.checkboxRange, replacementString: replacement) else {
                pendingEdit = previousPendingEdit
                return
            }

            performProgrammaticUpdate {
                textView.textStorage?.replaceCharacters(in: task.checkboxRange, with: replacement)
                textView.setSelectedRange(preservedSelection)
                textView.didChangeText()
            }

            currentLineIndex.replace(edit, updatedSource: textView.string)
            let selection = EditorSelection(range: preservedSelection)
            parent.onTextEdit(textView.string, edit, selection)
            parent.selection = selection
            pendingEdit = previousPendingEdit
            applyHybridAttributes(to: textView)

            if wasFirstResponder {
                textView.window?.makeFirstResponder(textView)
            }
        }

        private func checklistFrame(for task: RenderedTaskElement, in textView: NSTextView) -> NSRect? {
            guard let layoutManager = textView.layoutManager,
                  let textContainer = textView.textContainer,
                  task.checkboxRange.location < textView.string.utf16.count
            else { return nil }

            let characterRange = NSRange(location: task.checkboxRange.location, length: 1)
            layoutManager.ensureLayout(forCharacterRange: characterRange)
            let glyphRange = layoutManager.glyphRange(forCharacterRange: characterRange, actualCharacterRange: nil)
            guard glyphRange.length > 0 else { return nil }

            let glyphRect = layoutManager.boundingRect(forGlyphRange: glyphRange, in: textContainer)
            let origin = textView.textContainerOrigin
            return NSRect(
                x: origin.x + glyphRect.minX - 2,
                y: origin.y + glyphRect.minY - 1,
                width: 18,
                height: 18
            )
        }

        private func removeChecklistControl(at lineIndex: Int) {
            checklistButtons[lineIndex]?.removeFromSuperview()
            checklistButtons.removeValue(forKey: lineIndex)
        }

        private func removeChecklistControls() {
            checklistButtons.values.forEach { $0.removeFromSuperview() }
            checklistButtons.removeAll()
        }

        private func restoreVisibleOrigin(_ origin: NSPoint?, in textView: NSTextView) -> Bool {
            guard let origin,
                  let scrollView = textView.enclosingScrollView
            else { return false }

            let maxY = max(0, textView.bounds.height - scrollView.contentView.bounds.height)
            let maxX = max(0, textView.bounds.width - scrollView.contentView.bounds.width)
            let clampedOrigin = NSPoint(
                x: max(0, min(origin.x, maxX)),
                y: max(0, min(origin.y, maxY))
            )
            scrollView.contentView.scroll(to: clampedOrigin)
            scrollView.reflectScrolledClipView(scrollView.contentView)
            return true
        }
    }
}

private final class EditorTextView: NSTextView {
    var onFocusStateChange: ((NSTextView) -> Void)?
    var onUserEditingInteraction: ((NSTextView) -> Void)?

    override var acceptsFirstResponder: Bool {
        true
    }

    override func becomeFirstResponder() -> Bool {
        let becameFirstResponder = super.becomeFirstResponder()
        if becameFirstResponder {
            onFocusStateChange?(self)
        }
        return becameFirstResponder
    }

    override func resignFirstResponder() -> Bool {
        let resignedFirstResponder = super.resignFirstResponder()
        if resignedFirstResponder {
            onFocusStateChange?(self)
        }
        return resignedFirstResponder
    }

    override func mouseDown(with event: NSEvent) {
        onUserEditingInteraction?(self)
        super.mouseDown(with: event)
    }

    override func keyDown(with event: NSEvent) {
        onUserEditingInteraction?(self)
        super.keyDown(with: event)
    }

    override func paste(_ sender: Any?) {
        onUserEditingInteraction?(self)
        super.paste(sender)
    }
}

private final class ChecklistOverlayButton: NSButton {
    var task: RenderedTaskElement?
    var onToggle: (() -> Void)?

    init() {
        super.init(frame: .zero)
        setButtonType(.switch)
        title = ""
        isBordered = false
        imagePosition = .imageOnly
        cell?.refusesFirstResponder = true
        target = self
        action = #selector(toggleCheckbox)
    }

    override var acceptsFirstResponder: Bool {
        false
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        nil
    }

    @objc private func toggleCheckbox() {
        onToggle?()
    }
}

private final class ComfortableEditorScrollView: NSScrollView {
    weak var editorTextView: NSTextView?
    var onEditorLayoutInvalidated: ((NSTextView) -> Void)?
    private var lastLayoutSize: NSSize = .zero

    override func layout() {
        super.layout()
        let didChangeInsets = updateEditorInsets()

        guard let editorTextView else { return }
        let layoutSize = contentView.bounds.size
        if didChangeInsets || layoutSize != lastLayoutSize {
            lastLayoutSize = layoutSize
            onEditorLayoutInvalidated?(editorTextView)
        }
    }

    @discardableResult
    func updateEditorInsets() -> Bool {
        guard let editorTextView else { return false }

        let readableWidth: CGFloat = 760
        let horizontalInset = max(36, floor((contentView.bounds.width - readableWidth) / 2))
        let targetInset = NSSize(width: horizontalInset, height: 38)

        if editorTextView.textContainerInset != targetInset {
            editorTextView.textContainerInset = targetInset
            return true
        }
        return false
    }
}

#if DEBUG
@MainActor
public final class HybridMarkdownLiveEditorHarness {
    public private(set) var text: String
    public private(set) var selection: EditorSelection
    public private(set) var renderPasses: [EditorRenderPassMetric] = []

    private let box: StateBox
    private let coordinator: NativeMarkdownTextView.Coordinator
    private let window: NSWindow
    private let scrollView: ComfortableEditorScrollView
    private let textView: EditorTextView

    public init(
        source: String,
        selectedRange: NSRange = NSRange(location: 0, length: 0),
        initialWidth: CGFloat = 640
    ) {
        let stateBox = StateBox(text: source, selection: EditorSelection(range: selectedRange))
        self.text = source
        self.selection = EditorSelection(range: selectedRange)
        self.box = stateBox

        let lineIndex = DocumentLineIndex(source: source)
        let parent = NativeMarkdownTextView(
            text: Binding(
                get: { stateBox.text },
                set: { stateBox.text = $0 }
            ),
            selection: Binding(
                get: { stateBox.selection },
                set: { stateBox.selection = $0 }
            ),
            activeLineIndex: lineIndex.lineIndex(containing: selectedRange.location),
            lineIndex: lineIndex,
            onTextEdit: { updatedText, edit, updatedSelection in
                stateBox.text = updatedText
                if let edit {
                    stateBox.lineIndex.replace(edit, updatedSource: updatedText)
                } else {
                    stateBox.lineIndex = DocumentLineIndex(source: updatedText)
                }
                if let updatedSelection {
                    stateBox.selection = updatedSelection
                }
            },
            onRenderPass: { metric in
                stateBox.renderPasses.append(metric)
            }
        )

        self.coordinator = parent.makeCoordinator()
        self.coordinator.currentLineIndex = lineIndex
        self.scrollView = ComfortableEditorScrollView()
        self.scrollView.hasVerticalScroller = true
        self.scrollView.hasHorizontalScroller = false
        self.scrollView.autohidesScrollers = true
        self.scrollView.borderType = .noBorder
        self.scrollView.drawsBackground = true
        self.scrollView.backgroundColor = .textBackgroundColor

        let textStorage = NSTextStorage()
        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: NSSize(width: 0, height: CGFloat.greatestFiniteMagnitude))
        textContainer.widthTracksTextView = true
        textContainer.heightTracksTextView = false
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)

        self.textView = EditorTextView(
            frame: NSRect(x: 0, y: 0, width: initialWidth, height: 480),
            textContainer: textContainer
        )
        self.textView.autoresizingMask = [.width]
        self.textView.minSize = NSSize(width: 0, height: 480)
        self.textView.maxSize = NSSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
        self.textView.isVerticallyResizable = true
        self.textView.isHorizontallyResizable = false
        self.textView.onFocusStateChange = { [weak coordinator] textView in
            coordinator?.applyHybridAttributes(to: textView)
        }
        self.textView.onUserEditingInteraction = { [weak coordinator] textView in
            coordinator?.activateEditingPresentation(in: textView)
        }
        self.textView.string = source
        self.textView.delegate = coordinator
        self.textView.setSelectedRange(selectedRange)
        self.textView.isRichText = false
        self.textView.isEditable = true
        self.textView.isSelectable = true
        self.textView.isAutomaticQuoteSubstitutionEnabled = false
        self.textView.isAutomaticDashSubstitutionEnabled = false
        self.textView.isAutomaticTextReplacementEnabled = false
        self.textView.allowsUndo = true
        self.textView.usesFindPanel = true
        self.textView.isContinuousSpellCheckingEnabled = true
        self.textView.backgroundColor = .textBackgroundColor
        self.textView.insertionPointColor = .controlAccentColor
        self.textView.font = .systemFont(ofSize: 16, weight: .regular)
        self.textView.textContainer?.widthTracksTextView = true
        self.textView.textContainer?.containerSize = NSSize(width: initialWidth, height: CGFloat.greatestFiniteMagnitude)

        self.scrollView.frame = NSRect(x: 0, y: 0, width: initialWidth, height: 480)
        self.scrollView.documentView = textView
        self.scrollView.editorTextView = textView
        self.scrollView.onEditorLayoutInvalidated = { [weak coordinator] textView in
            coordinator?.syncChecklistControlFrames(in: textView)
        }
        self.scrollView.updateEditorInsets()

        self.window = NSWindow(
            contentRect: NSRect(x: 0, y: 0, width: initialWidth, height: 480),
            styleMask: [.titled],
            backing: .buffered,
            defer: false
        )
        self.window.contentView = scrollView
        self.coordinator.applyHybridAttributes(to: textView)
        syncState()
    }

    public func simulateLaunchFirstResponder() {
        window.makeFirstResponder(textView)
        syncState()
    }

    public func simulateFocusAway() {
        window.makeFirstResponder(nil)
        syncState()
    }

    public func setSelection(_ range: NSRange) {
        coordinator.activateEditingPresentation(in: textView)
        coordinator.setSelection(range, in: textView)
        coordinator.textViewDidChangeSelection(Notification(name: NSTextView.didChangeSelectionNotification, object: textView))
        syncState()
    }

    public func clickRenderedCheckbox(lineIndex: Int) {
        guard let button = checklistButton(lineIndex: lineIndex) else { return }
        button.performClick(nil)
        syncState()
    }

    public func simulateLayout(width: CGFloat) {
        window.setContentSize(NSSize(width: width, height: 480))
        scrollView.frame = NSRect(x: 0, y: 0, width: width, height: 480)
        textView.frame = NSRect(x: 0, y: 0, width: width, height: textView.frame.height)
        textView.textContainer?.containerSize = NSSize(width: width, height: CGFloat.greatestFiniteMagnitude)
        scrollView.layoutSubtreeIfNeeded()
        scrollView.layout()
        syncState()
    }

    public func headingMarkerIsHidden() -> Bool {
        isHidden(at: 0)
    }

    public func characterIsHidden(at location: Int) -> Bool {
        isHidden(at: location)
    }

    public func point(for text: String) -> CGPoint? {
        let textRange = (textView.string as NSString).range(of: text)
        guard textRange.location != NSNotFound,
              let layoutManager = textView.layoutManager,
              let textContainer = textView.textContainer
        else { return nil }

        layoutManager.ensureLayout(for: textContainer)
        let glyphRange = layoutManager.glyphRange(
            forCharacterRange: NSRange(location: textRange.location, length: 1),
            actualCharacterRange: nil
        )
        guard glyphRange.length > 0 else { return nil }

        let fragment = layoutManager.lineFragmentRect(forGlyphAt: glyphRange.location, effectiveRange: nil)
        let glyphLocation = layoutManager.location(forGlyphAt: glyphRange.location)
        let origin = textView.textContainerOrigin
        return CGPoint(x: origin.x + fragment.minX + glyphLocation.x, y: origin.y + fragment.minY + glyphLocation.y)
    }

    public func presentationSignature() -> String {
        guard let storage = textView.textStorage else { return "" }
        return MarkdownPresentationSnapshot.make(
            from: storage,
            lineIndex: coordinator.currentLineIndex,
            containerWidth: textView.textContainer?.containerSize.width ?? 640
        ).signature
    }

    public func checklistButtonFrame(lineIndex: Int) -> CGRect? {
        checklistButton(lineIndex: lineIndex)?.frame
    }

    public func checklistAlignmentDelta(lineIndex: Int) -> CGFloat? {
        guard let buttonFrame = checklistButtonFrame(lineIndex: lineIndex),
              let labelFrame = checklistLabelFrame(lineIndex: lineIndex)
        else { return nil }

        return abs(buttonFrame.midY - labelFrame.midY)
    }

    public func checklistLabelGap(lineIndex: Int) -> CGFloat? {
        guard let buttonFrame = checklistButtonFrame(lineIndex: lineIndex),
              let labelFrame = checklistLabelFrame(lineIndex: lineIndex)
        else { return nil }

        return labelFrame.minX - buttonFrame.maxX
    }

    public func selectedRange() -> NSRange {
        textView.selectedRange()
    }

    public func source() -> String {
        textView.string
    }

    public func effectiveActiveLineIndex() -> Int {
        coordinator.currentLineIndex.lineIndex(containing: textView.selectedRange().location)
    }

    private func checklistButton(lineIndex: Int) -> ChecklistOverlayButton? {
        textView.subviews.compactMap { $0 as? ChecklistOverlayButton }.first { $0.task?.lineIndex == lineIndex }
    }

    private func checklistLabelFrame(lineIndex: Int) -> CGRect? {
        guard let task = checklistButton(lineIndex: lineIndex)?.task,
              task.contentRange.location < textView.string.utf16.count,
              let layoutManager = textView.layoutManager,
              let textContainer = textView.textContainer
        else { return nil }

        layoutManager.ensureLayout(for: textContainer)
        let glyphRange = layoutManager.glyphRange(
            forCharacterRange: NSRange(location: task.contentRange.location, length: 1),
            actualCharacterRange: nil
        )
        guard glyphRange.length > 0 else { return nil }

        let fragment = layoutManager.lineFragmentRect(forGlyphAt: glyphRange.location, effectiveRange: nil)
        let origin = textView.textContainerOrigin
        return CGRect(
            x: origin.x + fragment.minX,
            y: origin.y + fragment.minY,
            width: fragment.width,
            height: fragment.height
        )
    }

    private func isHidden(at location: Int) -> Bool {
        guard let textStorage = textView.textStorage else { return false }
        let color = textStorage.attribute(.foregroundColor, at: location, effectiveRange: nil) as? NSColor
        let font = textStorage.attribute(.font, at: location, effectiveRange: nil) as? NSFont
        return color?.alphaComponent == 0 && (font?.pointSize ?? 0) < 1
    }

    private func syncState() {
        text = box.text
        selection = box.selection
        renderPasses = box.renderPasses
    }

    private final class StateBox {
        var text: String
        var selection: EditorSelection
        var lineIndex: DocumentLineIndex
        var renderPasses: [EditorRenderPassMetric] = []

        init(text: String, selection: EditorSelection) {
            self.text = text
            self.selection = selection
            self.lineIndex = DocumentLineIndex(source: text)
        }
    }
}
#endif
#elseif os(iOS)
private struct NativeMarkdownTextView: UIViewRepresentable {
    @Binding var text: String
    @Binding var selection: EditorSelection
    let activeLineIndex: Int
    let lineIndex: DocumentLineIndex
    let onTextEdit: (String, DocumentLineIndexEdit?, EditorSelection?) -> Void
    let onRenderPass: (EditorRenderPassMetric) -> Void

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.text = text
        textView.delegate = context.coordinator
        textView.allowsEditingTextAttributes = false
        textView.autocorrectionType = .yes
        textView.smartDashesType = .no
        textView.smartQuotesType = .no
        textView.font = .systemFont(ofSize: 17, weight: .regular)
        textView.textContainerInset = UIEdgeInsets(top: 28, left: 24, bottom: 28, right: 24)
        textView.backgroundColor = .systemBackground
        context.coordinator.applyHybridAttributes(to: textView)
        return textView
    }

    func updateUIView(_ textView: UITextView, context: Context) {
        context.coordinator.parent = self
        context.coordinator.currentLineIndex = lineIndex
        if textView.text != text {
            context.coordinator.performProgrammaticUpdate {
                textView.text = text
            }
            context.coordinator.invalidateStylingCache()
        }
        context.coordinator.applyHybridAttributes(to: textView)
    }

    final class Coordinator: NSObject, UITextViewDelegate {
        var parent: NativeMarkdownTextView
        var currentLineIndex: DocumentLineIndex
        private var programmaticUpdateDepth = 0
        private var lastStyledText: String?
        private var lastStyledActiveLineIndex: Int?
        private var lastStyledEditableRegion: EditableRegion?
        private var pendingEdit: DocumentLineIndexEdit?
        init(_ parent: NativeMarkdownTextView) {
            self.parent = parent
            self.currentLineIndex = parent.lineIndex
        }

        func textView(
            _ textView: UITextView,
            shouldChangeTextIn range: NSRange,
            replacementText text: String
        ) -> Bool {
            pendingEdit = DocumentLineIndexEdit(range: range, replacement: text)
            return true
        }

        func textViewDidChange(_ textView: UITextView) {
            guard !isPerformingProgrammaticUpdate else { return }
            let selection = EditorSelection(range: textView.selectedRange)
            let edit = pendingEdit
            if let edit {
                currentLineIndex.replace(edit, updatedSource: textView.text)
            } else {
                currentLineIndex = DocumentLineIndex(source: textView.text)
            }
            parent.onTextEdit(textView.text, edit, selection)
            parent.selection = selection
            applyHybridAttributes(to: textView)
            pendingEdit = nil
        }

        func textViewDidChangeSelection(_ textView: UITextView) {
            guard !isPerformingProgrammaticUpdate else { return }
            let newSelection = EditorSelection(range: textView.selectedRange)
            guard parent.selection != newSelection else { return }
            applyHybridAttributes(to: textView)
            parent.selection = newSelection
        }

        func applyHybridAttributes(to textView: UITextView) {
            let editableRegion = textView.isFirstResponder
                ? EditableRegion.selection(textView.selectedRange, in: currentLineIndex)
                : .none()
            let activeLineIndex = editableRegion.primaryLineIndex
            let invalidationPlan = invalidationPlan(for: textView.text, editableRegion: editableRegion)
            guard invalidationPlan.requiresStyling else { return }

            let selectedRange = textView.selectedRange
            let contentOffset = textView.contentOffset
            let start = Date()
            var stylingResult = MarkdownTextStylingResult.empty
            var didRestoreContentOffset = false
            performProgrammaticUpdate {
                stylingResult = MarkdownTextStyler.apply(
                    to: textView.textStorage,
                    lineIndex: currentLineIndex,
                    invalidationPlan: invalidationPlan,
                    activeLineIndex: activeLineIndex,
                    backgroundColor: .systemBackground,
                    activeLineBackgroundColor: .systemBlue.withAlphaComponent(0.10),
                    textColor: .label,
                    secondaryTextColor: .secondaryLabel,
                    accentColor: .systemBlue,
                    editableRegion: editableRegion
                )
                if textView.selectedRange != selectedRange,
                   selectedRange.location <= textView.text.utf16.count {
                    textView.selectedRange = selectedRange
                }
                textView.setContentOffset(clampedContentOffset(contentOffset, in: textView), animated: false)
                didRestoreContentOffset = true
            }

            lastStyledText = textView.text
            lastStyledActiveLineIndex = activeLineIndex
            lastStyledEditableRegion = editableRegion
            parent.onRenderPass(EditorRenderPassMetric(
                reason: invalidationPlan.reason,
                durationMilliseconds: Date().timeIntervalSince(start) * 1000,
                characterCount: textView.text.utf16.count,
                lineCount: stylingResult.totalLineCount,
                dirtyLineCount: stylingResult.styledLineCount,
                activeLineIndex: activeLineIndex,
                isFullRender: invalidationPlan.isFullRender,
                restoredScrollPosition: didRestoreContentOffset
            ))
        }

        func textViewDidBeginEditing(_ textView: UITextView) {
            applyHybridAttributes(to: textView)
        }

        func textViewDidEndEditing(_ textView: UITextView) {
            applyHybridAttributes(to: textView)
        }

        func performProgrammaticUpdate(_ updates: () -> Void) {
            programmaticUpdateDepth += 1
            defer {
                programmaticUpdateDepth -= 1
            }
            updates()
        }

        func invalidateStylingCache() {
            lastStyledText = nil
            lastStyledActiveLineIndex = nil
            lastStyledEditableRegion = nil
        }

        private var isPerformingProgrammaticUpdate: Bool {
            programmaticUpdateDepth > 0
        }

        private func invalidationPlan(for text: String, editableRegion: EditableRegion) -> EditorDirtyLineInvalidationPlan {
            let previousEditableRegion = lastStyledEditableRegion
            let plan = EditorDirtyLineInvalidator.plan(
                previousText: lastStyledText,
                currentLineIndex: currentLineIndex,
                edit: pendingEdit,
                previousActiveLineIndex: previousEditableRegion?.primaryLineIndex ?? lastStyledActiveLineIndex,
                currentActiveLineIndex: editableRegion.primaryLineIndex
            )
            return plan.includingEditableRegionTransition(
                from: previousEditableRegion,
                to: editableRegion,
                lineCount: currentLineIndex.lineCount
            )
        }

        private func clampedContentOffset(_ offset: CGPoint, in textView: UITextView) -> CGPoint {
            let maxX = max(0, textView.contentSize.width - textView.bounds.width)
            let maxY = max(0, textView.contentSize.height - textView.bounds.height)
            return CGPoint(x: max(0, min(offset.x, maxX)), y: max(0, min(offset.y, maxY)))
        }
    }
}
#endif

struct MarkdownTextStylingResult {
    var totalLineCount: Int
    var styledLineCount: Int
    var styledLineIndexes: [Int]
    var renderedTasks: [RenderedTaskElement]
    var editableRegion: EditableRegion

    static let empty = MarkdownTextStylingResult(
        totalLineCount: 0,
        styledLineCount: 0,
        styledLineIndexes: [],
        renderedTasks: [],
        editableRegion: .none()
    )
}

enum MarkdownTextStyler {
    #if os(macOS)
    typealias PlatformColor = NSColor
    #elseif os(iOS)
    typealias PlatformColor = UIColor
    #endif

    @discardableResult
    static func apply(
        to textStorage: NSTextStorage,
        lineIndex: DocumentLineIndex,
        invalidationPlan: EditorDirtyLineInvalidationPlan,
        activeLineIndex: Int,
        backgroundColor: PlatformColor,
        activeLineBackgroundColor: PlatformColor,
        textColor: PlatformColor,
        secondaryTextColor: PlatformColor,
        accentColor: PlatformColor,
        usesRenderedControls: Bool = false,
        editableRegion: EditableRegion? = nil
    ) -> MarkdownTextStylingResult {
        let resolvedEditableRegion = editableRegion
            ?? (activeLineIndex >= 0 ? EditableRegion(lineIndexes: [activeLineIndex]) : .none())
        let fullRange = NSRange(location: 0, length: textStorage.length)
        guard fullRange.length > 0 else {
            return MarkdownTextStylingResult(
                totalLineCount: lineIndex.lineCount,
                styledLineCount: lineIndex.lineCount,
                styledLineIndexes: Array(0..<lineIndex.lineCount),
                renderedTasks: [],
                editableRegion: resolvedEditableRegion
            )
        }

        textStorage.beginEditing()
        if invalidationPlan.isFullRender {
            textStorage.setAttributes(baseAttributes(textColor: textColor), range: fullRange)
        }

        let presentationState = DocumentPresentationState(
            lineIndex: lineIndex,
            editableRegion: resolvedEditableRegion,
            lineIndexes: invalidationPlan.isFullRender ? nil : invalidationPlan.dirtyLineIndexes
        )
        var styledLineCount = 0
        var styledLineIndexes: [Int] = []
        for presentationLine in presentationState.lines {
            let line = presentationLine.line
            let paragraphRange = presentationRange(for: line, in: lineIndex, textLength: textStorage.length)
            resetAttributes(in: textStorage, range: paragraphRange, textColor: textColor)
            styledLineCount += 1
            styledLineIndexes.append(line.index)

            switch presentationLine.state {
            case .source:
                textStorage.addAttributes([
                    .backgroundColor: activeLineBackgroundColor,
                    .font: monospacedFont(size: 15, weight: .regular)
                ], range: paragraphRange)
                styleSourceLineMarkers(in: textStorage, line: line, secondaryTextColor: secondaryTextColor)
            case .rendered:
                styleRenderedLine(
                    in: textStorage,
                    line: line,
                    paragraphRange: paragraphRange,
                    renderPlan: presentationLine.renderPlan,
                    textColor: textColor,
                    backgroundColor: backgroundColor,
                    secondaryTextColor: secondaryTextColor,
                    accentColor: accentColor,
                    usesRenderedControls: usesRenderedControls
                )
            }
        }

        textStorage.endEditing()
        return MarkdownTextStylingResult(
            totalLineCount: presentationState.lineCount,
            styledLineCount: styledLineCount,
            styledLineIndexes: styledLineIndexes,
            renderedTasks: presentationState.renderedTasks,
            editableRegion: presentationState.editableRegion
        )
    }

    private static func resetAttributes(
        in textStorage: NSTextStorage,
        range: NSRange,
        textColor: PlatformColor
    ) {
        guard range.length > 0 else { return }
        textStorage.setAttributes(baseAttributes(textColor: textColor), range: range)
    }

    private static func presentationRange(
        for line: EditorLine,
        in lineIndex: DocumentLineIndex,
        textLength: Int
    ) -> NSRange {
        guard let boundary = lineIndex.boundary(at: line.index) else {
            return line.range
        }

        let upperBound = min(boundary.nextLineLocation, textLength)
        return NSRange(
            location: boundary.contentRange.location,
            length: max(0, upperBound - boundary.contentRange.location)
        )
    }

    private static func styleRenderedLine(
        in textStorage: NSTextStorage,
        line: EditorLine,
        paragraphRange: NSRange,
        renderPlan: HybridMarkdownLineRenderPlan,
        textColor: PlatformColor,
        backgroundColor: PlatformColor,
        secondaryTextColor: PlatformColor,
        accentColor: PlatformColor,
        usesRenderedControls: Bool
    ) {
        guard line.range.length > 0 else { return }

        switch renderPlan.kind {
        case .heading(let level, let markerRange, let textRange):
            hideSyntax(
                in: textStorage,
                range: NSRange(location: markerRange.location, length: textRange.location - markerRange.location)
            )
            textStorage.addAttributes([
                .paragraphStyle: headingParagraphStyle(level: level)
            ], range: paragraphRange)
            textStorage.addAttributes([
                .font: systemFont(size: headingFontSize(level: level), weight: .semibold)
            ], range: textRange)
        case .blockquote(let markerRange, let contentRange):
            textStorage.addAttributes([
                .foregroundColor: accentColor,
                .font: monospacedFont(size: 15, weight: .semibold)
            ], range: markerRange)
            textStorage.addAttributes([
                .foregroundColor: textColor,
                .backgroundColor: accentColor.withAlphaComponent(0.08),
                .paragraphStyle: blockquoteParagraphStyle()
            ], range: paragraphRange)
            textStorage.addAttributes([
                .font: italicSystemFont(size: 16)
            ], range: contentRange)
        case .horizontalRule(let range):
            textStorage.addAttributes([
                .foregroundColor: secondaryTextColor,
                .strikethroughStyle: NSUnderlineStyle.thick.rawValue,
                .paragraphStyle: horizontalRuleParagraphStyle()
            ], range: range)
        case .unorderedList(let markerRange, let contentRange, let nestingLevel):
            styleListLine(
                in: textStorage,
                paragraphRange: paragraphRange,
                markerRange: markerRange,
                contentRange: contentRange,
                nestingLevel: nestingLevel,
                secondaryTextColor: secondaryTextColor
            )
        case .orderedList(let markerRange, let contentRange, let nestingLevel):
            styleListLine(
                in: textStorage,
                paragraphRange: paragraphRange,
                markerRange: markerRange,
                contentRange: contentRange,
                nestingLevel: nestingLevel,
                secondaryTextColor: secondaryTextColor
            )
        case .taskList(let markerRange, let checkboxRange, let contentRange, let checked, let nestingLevel):
            styleTaskListLine(
                in: textStorage,
                paragraphRange: paragraphRange,
                markerRange: markerRange,
                checkboxRange: checkboxRange,
                contentRange: contentRange,
                checked: checked,
                nestingLevel: nestingLevel,
                secondaryTextColor: secondaryTextColor,
                accentColor: accentColor,
                backgroundColor: backgroundColor,
                usesRenderedControls: usesRenderedControls
            )
            if checked {
                textStorage.addAttributes([
                    .strikethroughStyle: NSUnderlineStyle.single.rawValue,
                    .foregroundColor: secondaryTextColor
                ], range: contentRange)
            }
        case .fencedCodeFence(let markerRange, let languageRange):
            textStorage.addAttributes(codeBlockAttributes(accentColor: accentColor), range: paragraphRange)
            if let languageRange {
                hideSyntax(
                    in: textStorage,
                    range: NSRange(location: markerRange.location, length: languageRange.location - markerRange.location)
                )
                textStorage.addAttributes([
                    .foregroundColor: accentColor,
                    .font: monospacedFont(size: 13, weight: .semibold)
                ], range: languageRange)
            } else {
                hideSyntax(in: textStorage, range: line.range)
            }
        case .codeBlockContent(let language):
            textStorage.addAttributes(codeBlockAttributes(accentColor: accentColor), range: paragraphRange)
            styleCodeSyntax(
                in: textStorage,
                line: line,
                language: language,
                textColor: textColor,
                secondaryTextColor: secondaryTextColor,
                accentColor: accentColor
            )
        case .tableRow(_, let separatorRanges, let isDivider):
            textStorage.addAttributes([
                .font: monospacedFont(size: 15, weight: .regular),
                .backgroundColor: accentColor.withAlphaComponent(0.06),
                .paragraphStyle: tableParagraphStyle()
            ], range: paragraphRange)
            for separatorRange in separatorRanges {
                textStorage.addAttributes([.foregroundColor: secondaryTextColor], range: separatorRange)
            }
            if isDivider {
                textStorage.addAttributes([
                    .foregroundColor: secondaryTextColor,
                    .font: monospacedFont(size: 15, weight: .semibold)
                ], range: paragraphRange)
            }
        case .paragraph:
            break
        }

        styleInlineSpans(
            in: textStorage,
            renderPlan: renderPlan,
            secondaryTextColor: secondaryTextColor,
            accentColor: accentColor
        )
    }

    private static func styleInlineSpans(
        in textStorage: NSTextStorage,
        renderPlan: HybridMarkdownLineRenderPlan,
        secondaryTextColor: PlatformColor,
        accentColor: PlatformColor
    ) {
        for span in renderPlan.spans {
            switch span.kind {
            case .bold:
                textStorage.addAttributes([.font: systemFont(size: 16, weight: .semibold)], range: span.range)
            case .italic:
                textStorage.addAttributes([.font: italicSystemFont(size: 16)], range: span.range)
            case .inlineCode:
                textStorage.addAttributes([
                    .font: monospacedFont(size: 15, weight: .regular),
                    .backgroundColor: accentColor.withAlphaComponent(0.12)
                ], range: span.range)
            case .link, .automaticLink:
                textStorage.addAttributes([
                    .foregroundColor: accentColor,
                    .underlineStyle: NSUnderlineStyle.single.rawValue
                ], range: span.range)
            case .markdownDelimiter:
                hideSyntax(in: textStorage, range: span.range)
            }
        }
    }

    private static func styleCodeSyntax(
        in textStorage: NSTextStorage,
        line: EditorLine,
        language: String?,
        textColor: PlatformColor,
        secondaryTextColor: PlatformColor,
        accentColor: PlatformColor
    ) {
        let normalizedLanguage = normalizedCodeLanguage(language)
        guard normalizedLanguage != "text" else { return }

        switch normalizedLanguage {
        case "swift":
            applyCodeRegex("\\b(import|struct|class|enum|protocol|extension|func|let|var|if|else|guard|return|for|while|switch|case|default|in|try|throw|throws|async|await|public|private|internal|static|final|init|self|nil|true|false)\\b", in: textStorage, line: line) { match in
                textStorage.addAttributes([
                    .foregroundColor: codeKeywordColor(accentColor: accentColor),
                    .font: monospacedFont(size: 15, weight: .semibold)
                ], range: match.range)
            }
            applyCodeRegex("\"(?:\\\\.|[^\"\\\\])*\"", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: codeStringColor(accentColor: accentColor)], range: match.range)
            }
            applyCodeRegex("\\b\\d+(?:\\.\\d+)?\\b", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: codeNumberColor(accentColor: accentColor)], range: match.range)
            }
            applyCodeRegex("//.*$", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: secondaryTextColor], range: match.range)
            }
        case "json":
            applyCodeRegex("\"(?:\\\\.|[^\"\\\\])*\"\\s*:", in: textStorage, line: line) { match in
                textStorage.addAttributes([
                    .foregroundColor: codeKeywordColor(accentColor: accentColor),
                    .font: monospacedFont(size: 15, weight: .semibold)
                ], range: match.range)
            }
            applyCodeRegex(":\\s*(\"(?:\\\\.|[^\"\\\\])*\")", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: codeStringColor(accentColor: accentColor)], range: match.range(at: 1))
            }
            applyCodeRegex("\\b(true|false|null)\\b", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: codeKeywordColor(accentColor: accentColor)], range: match.range)
            }
            applyCodeRegex("-?\\b\\d+(?:\\.\\d+)?\\b", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: codeNumberColor(accentColor: accentColor)], range: match.range)
            }
        case "yaml":
            applyCodeRegex("^\\s*[A-Za-z0-9_-]+\\s*:", in: textStorage, line: line) { match in
                textStorage.addAttributes([
                    .foregroundColor: codeKeywordColor(accentColor: accentColor),
                    .font: monospacedFont(size: 15, weight: .semibold)
                ], range: match.range)
            }
            applyCodeRegex("#.*$", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: secondaryTextColor], range: match.range)
            }
            applyCodeRegex("\\b(true|false|null|yes|no)\\b", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: codeNumberColor(accentColor: accentColor)], range: match.range)
            }
        case "markdown":
            applyCodeRegex("^\\s{0,3}#{1,6}\\s+.*$", in: textStorage, line: line) { match in
                textStorage.addAttributes([
                    .foregroundColor: codeKeywordColor(accentColor: accentColor),
                    .font: monospacedFont(size: 15, weight: .semibold)
                ], range: match.range)
            }
            applyCodeRegex("(\\*\\*[^*]+\\*\\*|`[^`]+`|\\[[^\\]]+\\]\\([^)]+\\))", in: textStorage, line: line) { match in
                textStorage.addAttributes([.foregroundColor: accentColor], range: match.range)
            }
        default:
            textStorage.addAttributes([.foregroundColor: textColor], range: line.range)
        }
    }

    private static func normalizedCodeLanguage(_ language: String?) -> String {
        let normalized = language?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
        switch normalized {
        case "swift", "json", "yaml", "yml":
            return normalized == "yml" ? "yaml" : normalized ?? "text"
        case "md", "markdown":
            return "markdown"
        default:
            return "text"
        }
    }

    private static func styleSourceLineMarkers(
        in textStorage: NSTextStorage,
        line: EditorLine,
        secondaryTextColor: PlatformColor
    ) {
        applyRegex("(#{1,6}|\\*\\*|__|\\*|_|`|\\[[ xX]\\]|\\[|\\]|\\(|\\)|\\||>|-{3,}|[-*]|\\d+[.)])", in: textStorage, line: line) { match in
            textStorage.addAttributes([.foregroundColor: secondaryTextColor], range: match.range)
        }
    }

    private static func baseAttributes(textColor: PlatformColor) -> [NSAttributedString.Key: Any] {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineSpacing = 4
        paragraph.paragraphSpacing = 5
        return [
            .font: systemFont(size: 16, weight: .regular),
            .foregroundColor: textColor,
            .paragraphStyle: paragraph
        ]
    }

    private static func applyRegex(
        _ pattern: String,
        in textStorage: NSTextStorage,
        line: EditorLine,
        handler: (NSTextCheckingResult) -> Void
    ) {
        guard line.range.length > 0,
              let regex = try? NSRegularExpression(pattern: pattern)
        else { return }

        regex.matches(in: textStorage.string, range: line.range).forEach(handler)
    }

    private static func applyCodeRegex(
        _ pattern: String,
        in textStorage: NSTextStorage,
        line: EditorLine,
        handler: (NSTextCheckingResult) -> Void
    ) {
        guard line.range.length > 0,
              let regex = try? NSRegularExpression(pattern: pattern, options: [.anchorsMatchLines])
        else { return }

        regex.matches(in: textStorage.string, range: line.range).forEach(handler)
    }

    private static func headingFontSize(level: Int) -> CGFloat {
        switch level {
        case 1: 28
        case 2: 23
        case 3: 20
        default: 17
        }
    }

    private static func headingParagraphStyle(level: Int) -> NSMutableParagraphStyle {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineSpacing = 4
        paragraph.paragraphSpacingBefore = level <= 2 ? 10 : 6
        paragraph.paragraphSpacing = level <= 2 ? 9 : 6
        return paragraph
    }

    private static func blockquoteParagraphStyle() -> NSMutableParagraphStyle {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineSpacing = 4
        paragraph.paragraphSpacing = 6
        paragraph.headIndent = 18
        paragraph.firstLineHeadIndent = 0
        return paragraph
    }

    private static func horizontalRuleParagraphStyle() -> NSMutableParagraphStyle {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineSpacing = 2
        paragraph.paragraphSpacingBefore = 10
        paragraph.paragraphSpacing = 10
        return paragraph
    }

    private static func listParagraphStyle(nestingLevel: Int) -> NSMutableParagraphStyle {
        let paragraph = NSMutableParagraphStyle()
        let indent = CGFloat(20 + nestingLevel * 18)
        paragraph.lineSpacing = 4
        paragraph.paragraphSpacing = 4
        paragraph.firstLineHeadIndent = 0
        paragraph.headIndent = indent
        return paragraph
    }

    private static func tableParagraphStyle() -> NSMutableParagraphStyle {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineSpacing = 3
        paragraph.paragraphSpacing = 2
        return paragraph
    }

    private static func codeBlockParagraphStyle() -> NSMutableParagraphStyle {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineSpacing = 3
        paragraph.paragraphSpacing = 4
        paragraph.paragraphSpacingBefore = 2
        paragraph.firstLineHeadIndent = 14
        paragraph.headIndent = 14
        return paragraph
    }

    private static func codeBlockAttributes(accentColor: PlatformColor) -> [NSAttributedString.Key: Any] {
        [
            .font: monospacedFont(size: 15, weight: .regular),
            .backgroundColor: accentColor.withAlphaComponent(0.08),
            .paragraphStyle: codeBlockParagraphStyle()
        ]
    }

    private static func styleListLine(
        in textStorage: NSTextStorage,
        paragraphRange: NSRange,
        markerRange: NSRange,
        contentRange: NSRange,
        nestingLevel: Int,
        secondaryTextColor: PlatformColor
    ) {
        textStorage.addAttributes([
            .paragraphStyle: listParagraphStyle(nestingLevel: nestingLevel)
        ], range: paragraphRange)
        textStorage.addAttributes([
            .foregroundColor: secondaryTextColor,
            .font: monospacedFont(size: 15, weight: .semibold)
        ], range: markerRange)
        textStorage.addAttributes([
            .font: systemFont(size: 16, weight: .regular)
        ], range: contentRange)
    }

    private static func styleTaskListLine(
        in textStorage: NSTextStorage,
        paragraphRange: NSRange,
        markerRange: NSRange,
        checkboxRange: NSRange,
        contentRange: NSRange,
        checked: Bool,
        nestingLevel: Int,
        secondaryTextColor: PlatformColor,
        accentColor: PlatformColor,
        backgroundColor: PlatformColor,
        usesRenderedControls: Bool
    ) {
        textStorage.addAttributes([
            .paragraphStyle: listParagraphStyle(nestingLevel: nestingLevel)
        ], range: paragraphRange)
        hideSyntax(
            in: textStorage,
            range: NSRange(location: markerRange.location, length: checkboxRange.location - markerRange.location)
        )
        textStorage.addAttributes([
            .foregroundColor: checked ? accentColor : secondaryTextColor,
            .font: monospacedFont(size: 15, weight: .semibold),
            .backgroundColor: checked ? accentColor.withAlphaComponent(0.16) : backgroundColor
        ], range: checkboxRange)
        if usesRenderedControls {
            hideSyntaxPreservingLayout(in: textStorage, range: checkboxRange, backgroundColor: backgroundColor)
        }
        textStorage.addAttributes([
            .font: systemFont(size: 16, weight: .regular)
        ], range: contentRange)
    }

    private static func hideSyntax(in textStorage: NSTextStorage, range: NSRange) {
        guard range.length > 0 else { return }
        textStorage.addAttributes([
            .foregroundColor: clearColor(),
            .font: monospacedFont(size: 0.1, weight: .regular)
        ], range: range)
    }

    private static func hideSyntaxPreservingLayout(
        in textStorage: NSTextStorage,
        range: NSRange,
        backgroundColor: PlatformColor
    ) {
        guard range.length > 0 else { return }
        textStorage.addAttributes([
            .foregroundColor: clearColor(),
            .backgroundColor: backgroundColor,
            .font: monospacedFont(size: 10, weight: .regular)
        ], range: range)
    }

    #if os(macOS)
    private static func systemFont(size: CGFloat, weight: NSFont.Weight) -> NSFont {
        NSFont.systemFont(ofSize: size, weight: weight)
    }

    private static func italicSystemFont(size: CGFloat) -> NSFont {
        NSFontManager.shared.convert(NSFont.systemFont(ofSize: size), toHaveTrait: .italicFontMask)
    }

    private static func monospacedFont(size: CGFloat, weight: NSFont.Weight) -> NSFont {
        NSFont.monospacedSystemFont(ofSize: size, weight: weight)
    }

    private static func clearColor() -> NSColor {
        .clear
    }

    private static func codeKeywordColor(accentColor: NSColor) -> NSColor {
        .systemPurple
    }

    private static func codeStringColor(accentColor: NSColor) -> NSColor {
        .systemRed
    }

    private static func codeNumberColor(accentColor: NSColor) -> NSColor {
        .systemOrange
    }
    #elseif os(iOS)
    private static func systemFont(size: CGFloat, weight: UIFont.Weight) -> UIFont {
        UIFont.systemFont(ofSize: size, weight: weight)
    }

    private static func italicSystemFont(size: CGFloat) -> UIFont {
        UIFont.italicSystemFont(ofSize: size)
    }

    private static func monospacedFont(size: CGFloat, weight: UIFont.Weight) -> UIFont {
        UIFont.monospacedSystemFont(ofSize: size, weight: weight)
    }

    private static func clearColor() -> UIColor {
        .clear
    }

    private static func codeKeywordColor(accentColor: UIColor) -> UIColor {
        .systemPurple
    }

    private static func codeStringColor(accentColor: UIColor) -> UIColor {
        .systemRed
    }

    private static func codeNumberColor(accentColor: UIColor) -> UIColor {
        .systemOrange
    }
    #endif
}

private extension NSRange {
    var upperBound: Int {
        location + length
    }
}

private var platformTextBackground: Color {
    #if os(macOS)
    Color(nsColor: .textBackgroundColor)
    #else
    Color(uiColor: .systemBackground)
    #endif
}
