import SwiftUI
import Foundation



/// MARK: - Types

private enum SyntaxRegexCache {
    static var storage: [String: NSRegularExpression] = [:]
    static let lock = NSLock()
}

// Reuse compiled regex objects across highlight passes to reduce CPU churn while typing/scrolling.
func cachedSyntaxRegex(pattern: String, options: NSRegularExpression.Options = []) -> NSRegularExpression? {
    let key = "\(options.rawValue)|\(pattern)"
    SyntaxRegexCache.lock.lock()
    defer { SyntaxRegexCache.lock.unlock() }
    if let cached = SyntaxRegexCache.storage[key] {
        return cached
    }
    guard let compiled = try? NSRegularExpression(pattern: pattern, options: options) else {
        return nil
    }
    SyntaxRegexCache.storage[key] = compiled
    return compiled
}

struct SyntaxColors {
    let keyword: Color
    let string: Color
    let number: Color
    let comment: Color
    let attribute: Color
    let variable: Color
    let def: Color
    let property: Color
    let meta: Color
    let tag: Color
    let atom: Color
    let builtin: Color
    let type: Color

    static func fromVibrantLightTheme(colorScheme: ColorScheme) -> SyntaxColors {
        let baseColors: [String: (light: Color, dark: Color)] = [
            "keyword": (light: Color(red: 251/255, green: 0/255, blue: 186/255), dark: Color(red: 251/255, green: 0/255, blue: 186/255)),
            "string": (light: Color(red: 190/255, green: 0/255, blue: 255/255), dark: Color(red: 190/255, green: 0/255, blue: 255/255)),
            "number": (light: Color(red: 28/255, green: 0/255, blue: 207/255), dark: Color(red: 28/255, green: 0/255, blue: 207/255)),
            "comment": (light: Color(red: 93/255, green: 108/255, blue: 121/255), dark: Color(red: 150/255, green: 160/255, blue: 170/255)),
            "attribute": (light: Color(red: 57/255, green: 0/255, blue: 255/255), dark: Color(red: 57/255, green: 0/255, blue: 255/255)),
            "variable": (light: Color(red: 19/255, green: 0/255, blue: 255/255), dark: Color(red: 19/255, green: 0/255, blue: 255/255)),
            "def": (light: Color(red: 29/255, green: 196/255, blue: 83/255), dark: Color(red: 29/255, green: 196/255, blue: 83/255)),
            "property": (light: Color(red: 29/255, green: 196/255, blue: 83/255), dark: Color(red: 29/255, green: 0/255, blue: 160/255)),
            "meta": (light: Color(red: 255/255, green: 16/255, blue: 0/255), dark: Color(red: 255/255, green: 16/255, blue: 0/255)),
            "tag": (light: Color(red: 170/255, green: 0/255, blue: 160/255), dark: Color(red: 170/255, green: 0/255, blue: 160/255)),
            "atom": (light: Color(red: 28/255, green: 0/255, blue: 207/255), dark: Color(red: 28/255, green: 0/255, blue: 207/255)),
            "builtin": (light: Color(red: 255/255, green: 130/255, blue: 0/255), dark: Color(red: 255/255, green: 130/255, blue: 0/255)),
            "type": (light: Color(red: 170/255, green: 0/255, blue: 160/255), dark: Color(red: 170/255, green: 0/255, blue: 160/255))
        ]

        return SyntaxColors(
            keyword: colorScheme == .dark ? baseColors["keyword"]!.dark : baseColors["keyword"]!.light,
            string: colorScheme == .dark ? baseColors["string"]!.dark : baseColors["string"]!.light,
            number: colorScheme == .dark ? baseColors["number"]!.dark : baseColors["number"]!.light,
            comment: colorScheme == .dark ? baseColors["comment"]!.dark : baseColors["comment"]!.light,
            attribute: colorScheme == .dark ? baseColors["attribute"]!.dark : baseColors["attribute"]!.light,
            variable: colorScheme == .dark ? baseColors["variable"]!.dark : baseColors["variable"]!.light,
            def: colorScheme == .dark ? baseColors["def"]!.dark : baseColors["def"]!.light,
            property: colorScheme == .dark ? baseColors["property"]!.dark : baseColors["property"]!.light,
            meta: colorScheme == .dark ? baseColors["meta"]!.dark : baseColors["meta"]!.light,
            tag: colorScheme == .dark ? baseColors["tag"]!.dark : baseColors["tag"]!.light,
            atom: colorScheme == .dark ? baseColors["atom"]!.dark : baseColors["atom"]!.light,
            builtin: colorScheme == .dark ? baseColors["builtin"]!.dark : baseColors["builtin"]!.light,
            type: colorScheme == .dark ? baseColors["type"]!.dark : baseColors["type"]!.light
        )
    }
}

enum SyntaxPatternProfile {
    case full
    case htmlFast
    case csvFast
    case jsonFast
}

struct SyntaxEmphasisPatterns {
    let keyword: [String]
    let comment: [String]
    let link: [String]
    let markdownHeading: [String]
}

private func canonicalSyntaxLanguage(_ language: String) -> String {
    let normalized = language
        .trimmingCharacters(in: .whitespacesAndNewlines)
        .lowercased()
    switch normalized {
    case "py", "python3":
        return "python"
    case "js", "mjs", "cjs":
        return "javascript"
    case "ts", "tsx":
        return "typescript"
    case "ee", "expression-engine", "expression_engine":
        return "expressionengine"
    case "latex", "bibtex":
        return "tex"
    default:
        return normalized
    }
}

func syntaxEmphasisPatterns(
    for language: String,
    profile: SyntaxPatternProfile = .full
) -> SyntaxEmphasisPatterns {
    switch canonicalSyntaxLanguage(language) {
    case "swift":
        return SyntaxEmphasisPatterns(
            keyword: [
                "\\b(func|struct|class|enum|protocol|extension|actor|if|else|for|while|switch|case|default|guard|defer|throw|try|catch|return|init|deinit|import|typealias|associatedtype|where|public|private|fileprivate|internal|open|static|mutating|nonmutating|inout|async|await|throws|rethrows)\\b",
                "(?m)^#(if|elseif|else|endif|warning|error|available)\\b.*$"
            ],
            comment: [
                "//.*",
                "/\\*([^*]|(\\*+[^*/]))*\\*+/",
                "(?m)^(///).*$",
                "/\\*\\*([\\s\\S]*?)\\*+/"
            ],
            link: [
                "https?://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+",
                "file://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+"
            ],
            markdownHeading: []
        )
    case "python":
        return SyntaxEmphasisPatterns(
            keyword: ["\\b(def|class|if|else|elif|for|while|try|except|with|as|import|from|return|yield|async|await)\\b"],
            comment: ["#.*"],
            link: [],
            markdownHeading: []
        )
    case "javascript":
        return SyntaxEmphasisPatterns(
            keyword: ["\\b(function|var|let|const|if|else|for|while|do|try|catch|finally|return|class|extends|new|import|export|async|await)\\b"],
            comment: ["//.*|/\\*([^*]|(\\*+[^*/]))*\\*+/"],
            link: [],
            markdownHeading: []
        )
    case "php":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(function|class|interface|trait|namespace|use|public|private|protected|static|final|abstract|if|else|elseif|for|foreach|while|do|switch|case|default|return|try|catch|throw|new|echo)\b"#],
            comment: [#"//.*|#.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "expressionengine":
        return SyntaxEmphasisPatterns(
            keyword: [#"\{if(?::elseif)?\b[^}]*\}|\{\/if\}|\{:else\}"#],
            comment: [#"\{!--[\s\S]*?--\}"#],
            link: [],
            markdownHeading: []
        )
    case "html":
        return SyntaxEmphasisPatterns(
            keyword: [],
            comment: profile == .htmlFast ? [] : [],
            link: [],
            markdownHeading: []
        )
    case "css":
        return SyntaxEmphasisPatterns(keyword: [], comment: [], link: [], markdownHeading: [])
    case "c", "cpp":
        return SyntaxEmphasisPatterns(
            keyword: ["\\b(int|float|double|char|void|if|else|for|while|do|switch|case|return)\\b"],
            comment: ["//.*|/\\*([^*]|(\\*+[^*/]))*\\*+/"],
            link: [],
            markdownHeading: []
        )
    case "json":
        return SyntaxEmphasisPatterns(keyword: [#"\b(true|false|null)\b"#], comment: [], link: [], markdownHeading: [])
    case "markdown":
        return SyntaxEmphasisPatterns(
            keyword: [
                #"(?m)^```[A-Za-z0-9_-]*\s*$|(?m)^~~~[A-Za-z0-9_-]*\s*$"#,
                #"(?m)^\s*[-*+]\s+.*$|(?m)^\s*\d+\.\s+.*$"#
            ],
            comment: [#"(?m)^>\s+.*$"#],
            link: [
                #"\[[^\]]+\]\([^)]+\)"#,
                #"https?://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+"#
            ],
            markdownHeading: [
                #"(?m)^\s{0,3}#{1,6}\s+.*$"#,
                #"(?m)^\s{0,3}(=+|-+)\s*$"#
            ]
        )
    case "tex":
        return SyntaxEmphasisPatterns(
            keyword: [#"\\[A-Za-z@]+(\*?)"#],
            comment: [#"(?m)%.*$"#],
            link: [],
            markdownHeading: []
        )
    case "bash":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(if|then|else|elif|fi|for|while|do|done|case|esac|function|in|select|until|time)\b"#],
            comment: [#"#.*"#],
            link: [],
            markdownHeading: []
        )
    case "zsh":
        return SyntaxEmphasisPatterns(
            keyword: ["\\b(if|then|else|elif|fi|for|while|do|done|case|esac|function|in|autoload|typeset|setopt|unsetopt)\\b"],
            comment: ["#.*"],
            link: [],
            markdownHeading: []
        )
    case "powershell":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(function|param|if|else|elseif|foreach|for|while|switch|break|continue|return|try|catch|finally)\b"#],
            comment: [#"#.*"#],
            link: [],
            markdownHeading: []
        )
    case "java":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(class|interface|enum|public|private|protected|static|final|void|int|double|float|boolean|new|return|if|else|for|while|switch|case)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "kotlin":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(class|object|fun|val|var|when|if|else|for|while|return|import|package|interface)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "go":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(package|import|func|var|const|type|struct|interface|if|else|for|switch|case|return|go|defer)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "ruby":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(def|class|module|if|else|elsif|end|do|while|until|case|when|begin|rescue|ensure|return)\b"#],
            comment: [#"#.*"#],
            link: [],
            markdownHeading: []
        )
    case "rust":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(fn|let|mut|struct|enum|impl|trait|pub|use|mod|if|else|match|loop|while|for|return)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "typescript":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(function|class|interface|type|enum|const|let|var|if|else|for|while|do|try|catch|return|extends|implements)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "objective-c":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(if|else|for|while|switch|case|return)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "sql":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(SELECT|INSERT|UPDATE|DELETE|CREATE|TABLE|FROM|WHERE|JOIN|LEFT|RIGHT|INNER|OUTER|GROUP|BY|ORDER|LIMIT|VALUES|INTO)\b"#],
            comment: [#"--.*"#],
            link: [],
            markdownHeading: []
        )
    case "xml":
        return SyntaxEmphasisPatterns(keyword: [], comment: [], link: [], markdownHeading: [])
    case "yaml":
        return SyntaxEmphasisPatterns(
            keyword: [#"(?m)^\s*-\s+.*$"#, #"\b(true|false|null|yes|no|on|off)\b"#],
            comment: [#"(?m)^\s*#.*$"#],
            link: [],
            markdownHeading: []
        )
    case "toml":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(true|false)\b"#],
            comment: [#"(?m)#.*$"#],
            link: [],
            markdownHeading: []
        )
    case "csv":
        return SyntaxEmphasisPatterns(keyword: [], comment: [], link: [], markdownHeading: [])
    case "ini":
        return SyntaxEmphasisPatterns(keyword: [], comment: ["^;.*$"], link: [], markdownHeading: [])
    case "vim":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(set|let|if|endif|for|endfor|while|endwhile|function|endfunction|command|autocmd|syntax|highlight|nnoremap|inoremap|vnoremap|map|nmap|imap|vmap)\b"#],
            comment: [#"^\s*\".*$"#],
            link: [],
            markdownHeading: []
        )
    case "log":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(ERROR|ERR|FATAL|WARN|WARNING|INFO|DEBUG|TRACE)\b"#],
            comment: [],
            link: [#"https?://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+"#],
            markdownHeading: []
        )
    case "ipynb":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(true|false|null)\b"#],
            comment: [],
            link: [],
            markdownHeading: []
        )
    case "csharp":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(class|interface|enum|struct|namespace|using|public|private|protected|internal|static|readonly|sealed|abstract|virtual|override|async|await|new|return|if|else|for|foreach|while|do|switch|case|break|continue|try|catch|finally|throw)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "cobol":
        return SyntaxEmphasisPatterns(
            keyword: [#"(?i)\b(identification|environment|data|procedure|division|section|program-id|author|installati?on|date-written|date-compiled|working-storage|linkage|file-control|input-output|select|assign|fd|01|77|88|level|pic|picture|value|values|move|add|subtract|multiply|divide|compute|if|else|end-if|evaluate|when|perform|until|varying|go|to|goback|stop|run|call|accept|display|open|close|read|write|rewrite|delete|string|unstring|initialize|set|inspect)\b"#],
            comment: [#"(?m)^\s*\*.*$|(?m)^\s*\*>.*$"#],
            link: [],
            markdownHeading: []
        )
    case "dotenv":
        return SyntaxEmphasisPatterns(keyword: [], comment: [#"(?m)#.*$"#], link: [], markdownHeading: [])
    case "proto":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(syntax|package|import|option|message|enum|service|rpc|returns|repeated|map|oneof|reserved|required|optional)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#],
            link: [],
            markdownHeading: []
        )
    case "graphql":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(type|interface|enum|union|input|scalar|schema|extend|implements|directive|on|query|mutation|subscription|fragment)\b"#],
            comment: [#"(?m)#.*$"#],
            link: [],
            markdownHeading: []
        )
    case "rst":
        return SyntaxEmphasisPatterns(
            keyword: [#"(?m)^\s*([=\-`:'\"~^_*+<>#]{3,})\s*$"#],
            comment: [#"(?m)#.*$"#],
            link: [],
            markdownHeading: []
        )
    case "nginx":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(http|server|location|upstream|map|if|set|return|rewrite|proxy_pass|listen|server_name|root|index|try_files|include|error_page|access_log|error_log|gzip|ssl|add_header)\b"#],
            comment: [#"(?m)#.*$"#],
            link: [],
            markdownHeading: []
        )
    case "standard":
        return SyntaxEmphasisPatterns(
            keyword: [#"\b(if|else|for|while|do|switch|case|return|class|struct|enum|func|function|var|let|const|import|from|using|namespace|public|private|protected|static|void|new|try|catch|finally|throw)\b"#],
            comment: [#"//.*|/\*([^*]|(\*+[^*/]))*\*+/|#.*"#],
            link: [#"https?://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+"#],
            markdownHeading: []
        )
    case "plain":
        return SyntaxEmphasisPatterns(keyword: [], comment: [], link: [], markdownHeading: [])
    default:
        return SyntaxEmphasisPatterns(keyword: [], comment: [], link: [], markdownHeading: [])
    }
}

// Regex patterns per language mapped to colors. Keep light-weight for performance.
func getSyntaxPatterns(
    for language: String,
    colors: SyntaxColors,
    profile: SyntaxPatternProfile = .full
) -> [String: Color] {
    let canonical = canonicalSyntaxLanguage(language)
    switch canonical {
    case "swift":
        return [
            // Keywords (extended to include `import`)
            "\\b(func|struct|class|enum|protocol|extension|actor|if|else|for|while|switch|case|default|guard|defer|throw|try|catch|return|init|deinit|import|typealias|associatedtype|where|public|private|fileprivate|internal|open|static|mutating|nonmutating|inout|async|await|throws|rethrows)\\b": colors.keyword,

            // Strings and Characters
            "\"[^\"]*\"": colors.string,
            "'[^'\\](?:\\.[^'\\])*'": colors.string,

            // Numbers
            "\\b([0-9]+(\\.[0-9]+)?)\\b": colors.number,
            "\\b0x[0-9A-Fa-f]+\\b": colors.number,
            "\\b0b[01]+\\b": colors.number,

            // Comments (single and multi-line)
            "//.*": colors.comment,
            "/\\*([^*]|(\\*+[^*/]))*\\*+/": colors.comment,

            // Documentation markup (triple slash and doc blocks)
            "(?m)^(///).*$": colors.comment,
            "/\\*\\*([\\s\\S]*?)\\*+/": colors.comment,
            // Documentation keywords inside docs (e.g., - Parameter:, - Returns:)
            "(?m)\\-\\s*(Parameter|Parameters|Returns|Throws|Note|Warning|See\\salso)\\s*:": colors.meta,

            // Marks / TODO / FIXME
            "(?m)//\\s*(MARK|TODO|FIXME)\\s*:.*$": colors.meta,

            // URLs
            "https?://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+": colors.atom,
            "file://[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+": colors.atom,

            // Preprocessor statements (conditionals and directives)
            "(?m)^#(if|elseif|else|endif|warning|error|available)\\b.*$": colors.keyword,

            // Attributes like @available, @MainActor, etc.
            "@\\w+": colors.attribute,

            // Variable declarations
            "\\b(var|let)\\b": colors.variable,
            "\\b(self|super)\\b": colors.variable,

            // Common Swift types
            "\\b(String|Int|Double|Bool|Float|UInt|Int64|CGFloat|Any|AnyObject|Void|Never|Self)\\b": colors.type,
            "\\b(true|false|nil)\\b": colors.atom,

            // Function and type names
            "\\bfunc\\s+([A-Za-z_][A-Za-z0-9_]*)": colors.def,
            "\\b(class|struct|enum|protocol|actor)\\s+([A-Za-z_][A-Za-z0-9_]*)": colors.type,

            // Regex literals and components (Swift /…/)
            "/[^/\\n]*/": colors.builtin, // whole regex literal
            "\\(\\?<([A-Za-z_][A-Za-z0-9_]*)>": colors.def, // named capture start (?<name>
            "\\[[^\\]]*\\]": colors.property, // character classes
            "[|*+?]": colors.meta, // regex operators

            // Common SwiftUI property names like `body`
            "\\bbody\\b": colors.property,
            // Project-specific identifier you mentioned: `viewModel`
            "\\bviewModel\\b": colors.property
        ]
    case "python":
        return [
            "\\b(def|class|if|else|elif|for|while|try|except|with|as|import|from|return|yield|async|await)\\b": colors.keyword,
            "\\b(int|str|float|bool|list|dict|set|tuple|None|True|False)\\b": colors.type,
            "@\\w+": colors.attribute,
            "\"[^\"]*\"|'[^']*'": colors.string,
            "\\b([0-9]+(\\.[0-9]+)?)\\b": colors.number,
            "#.*": colors.comment
        ]
    case "javascript":
        return [
            "\\b(function|var|let|const|if|else|for|while|do|try|catch|finally|return|class|extends|new|import|export|async|await)\\b": colors.keyword,
            "\\b(Number|String|Boolean|Object|Array|Map|Set|Promise|Date)\\b": colors.type,
            "\\b(true|false|null|undefined)\\b": colors.atom,
            "\"[^\"]*\"|'[^']*'|\\`[^\\`]*\\`": colors.string,
            "\\b([0-9]+(\\.[0-9]+)?)\\b": colors.number,
            "//.*|/\\*([^*]|(\\*+[^*/]))*\\*+/": colors.comment
        ]
    case "php":
        return [
            #"\b(function|class|interface|trait|namespace|use|public|private|protected|static|final|abstract|if|else|elseif|for|foreach|while|do|switch|case|default|return|try|catch|throw|new|echo)\b"#: colors.keyword,
            #"\$[A-Za-z_][A-Za-z0-9_]*|\$\{[^}]+\}"#: colors.variable,
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #"//.*|#.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment,
            #"<\?php|\?>"#: colors.meta
        ]
    case "expressionengine":
        return [
            #"\{!--[\s\S]*?--\}"#: colors.comment,
            #"\{/?exp:[A-Za-z0-9_:-]+[^}]*\}"#: colors.tag,
            #"\{if(?::elseif)?\b[^}]*\}|\{\/if\}|\{:else\}"#: colors.keyword,
            #"\{[A-Za-z_][A-Za-z0-9_:-]*\}"#: colors.variable,
            #"[A-Za-z_][A-Za-z0-9_:-]*\s*="#: colors.property,
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "html":
        if profile == .htmlFast {
            return [
                // Fast path for very large HTML: focus on structural readability.
                "<[/!A-Za-z][^>]*>": colors.tag,
                "\\b[a-zA-Z_:][-a-zA-Z0-9_:.]*(?=\\s*=)": colors.property
            ]
        }
        return [
            "<[^>]+>": colors.tag,
            "\\b[a-zA-Z-]+(?=\\=)": colors.property,
            "\"[^\"]*\"|'[^']*'": colors.string
        ]
    case "css":
        return [
            "\\b([a-zA-Z-]+)\\s*:": colors.property,
            "#[0-9A-Fa-f]{3,6}\\b": colors.number,
            "\"[^\"]*\"|'[^']*'": colors.string
        ]
    case "c", "cpp":
        return [
            "\\b(int|float|double|char|void|if|else|for|while|do|switch|case|return)\\b": colors.keyword,
            "\\b(int|float|double|char)\\b": colors.type,
            "\"[^\"]*\"": colors.string,
            "\\b([0-9]+(\\.[0-9]+)?)\\b": colors.number,
            "//.*|/\\*([^*]|(\\*+[^*/]))*\\*+/": colors.comment
        ]
    case "json":
        return [
            #"\"[^\"]+\"\s*:"#: colors.property,
            #"\"([^\"\\]|\\.)*\""#: colors.string,
            #"\b(-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?)\b"#: colors.number,
            #"\b(true|false|null)\b"#: colors.keyword,
            #"[{}\[\],:]"#: colors.meta
        ]
    case "markdown":
        return [
            #"(?m)^\s{0,3}#{1,6}\s+.*$"#: colors.meta,
            #"(?m)^\s{0,3}(=+|-+)\s*$"#: colors.meta,
            #"(?s)```.*?```|~~~.*?~~~|`{1,3}[^`\n]+`{1,3}"#: colors.string,
            #"(?m)^```[A-Za-z0-9_-]*\s*$|(?m)^~~~[A-Za-z0-9_-]*\s*$"#: colors.keyword,
            #"(?m)^\s*[-*+]\s+.*$|(?m)^\s*\d+\.\s+.*$"#: colors.keyword,
            #"\*\*[^*\n]+\*\*|__[^_\n]+__"#: colors.def,
            #"(?<![\w_])_(?!_)[^_\n]+_(?![\w_])|(?<![\w*])\*(?!\*)[^*\n]+\*(?![\w*])"#: colors.def,
            #"\[[^\]]+\]\([^)]+\)"#: colors.string,
            #"(?m)^>\s+.*$"#: colors.comment
        ]
    case "tex":
        return [
            #"\\[A-Za-z@]+(\*?)"#: colors.keyword,
            #"\\begin\{[^}]+\}|\\end\{[^}]+\}"#: colors.meta,
            #"\{[^{}\n]*\}"#: colors.property,
            #"\[[^\]\n]*\]"#: colors.attribute,
            #"\$[^$\n]+\$|\$\$[\s\S]*?\$\$"#: colors.string,
            #"(?m)%.*$"#: colors.comment,
            #"\b[0-9]+(\.[0-9]+)?\b"#: colors.number
        ]
    case "bash":
        return [
            // Keywords and flow control
            #"\b(if|then|else|elif|fi|for|while|do|done|case|esac|function|in|select|until|time)\b"#: colors.keyword,
            // Variables and parameter expansions
            #"\$[A-Za-z_][A-Za-z0-9_]*|\${[^}]+}"#: colors.variable,
            // Command substitution and arithmetic
            #"\$\([^)]*\)|`[^`]*`|\$\(\([^)]*\)\)"#: colors.builtin,
            // Strings
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            // Numbers
            #"\b[0-9]+\b"#: colors.number,
            // Comments
            #"#.*"#: colors.comment,
            // Here-doc markers and redirections/pipes
            #"<<-?\s*[A-Za-z_][A-Za-z0-9_]*"#: colors.meta,
            #"\|\||\|\s|>>?|<<?|2>\&1|2>>?"#: colors.meta
        ]
    case "zsh":
        return [
            "\\b(if|then|else|elif|fi|for|while|do|done|case|esac|function|in|autoload|typeset|setopt|unsetopt)\\b": colors.keyword,
            "\\$[A-Za-z_][A-Za-z0-9_]*|\\${[^}]+}": colors.variable,
            "\\b[0-9]+\\b": colors.number,
            "\\\"[^\\\"]*\\\"|'[^']*'": colors.string,
            "#.*": colors.comment
        ]
    case "powershell":
        return [
            // Keywords and statements
            #"\b(function|param|if|else|elseif|foreach|for|while|switch|break|continue|return|try|catch|finally)\b"#: colors.keyword,
            // Cmdlets (Get-*, Set-*, Write-*, etc.)
            #"\b(Get|Set|New|Remove|Add|Clear|Write|Read|Start|Stop|Enable|Disable|Invoke|Test|Out|Select|Where|ForEach)-[A-Za-z][A-Za-z0-9]*\b"#: colors.builtin,
            // Variables
            #"\$[A-Za-z_][A-Za-z0-9_:]*"#: colors.variable,
            // Strings (single, double)
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            // Numbers
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            // Comments
            #"#.*"#: colors.comment
        ]
    case "java":
        return [
            #"\b(class|interface|enum|public|private|protected|static|final|void|int|double|float|boolean|new|return|if|else|for|while|switch|case)\b"#: colors.keyword,
            #"\"[^\"]*\""#: colors.string,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "kotlin":
        return [
            #"\b(class|object|fun|val|var|when|if|else|for|while|return|import|package|interface)\b"#: colors.keyword,
            #"\"[^\"]*\"|`[^`]*`"#: colors.string,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "go":
        return [
            #"\b(package|import|func|var|const|type|struct|interface|if|else|for|switch|case|return|go|defer)\b"#: colors.keyword,
            #"\"[^\"]*\"|`[^`]*`"#: colors.string,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "ruby":
        return [
            #"\b(def|class|module|if|else|elsif|end|do|while|until|case|when|begin|rescue|ensure|return)\b"#: colors.keyword,
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            #"#.*"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "rust":
        return [
            #"\b(fn|let|mut|struct|enum|impl|trait|pub|use|mod|if|else|match|loop|while|for|return)\b"#: colors.keyword,
            #"\"[^\"]*\""#: colors.string,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "typescript":
        return [
            #"\b(function|class|interface|type|enum|const|let|var|if|else|for|while|do|try|catch|return|extends|implements)\b"#: colors.keyword,
            #"\"[^\"]*\"|'[^']*'|`[^`]*`"#: colors.string,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "objective-c":
        return [
            #"@\w+"#: colors.attribute,
            #"\b(if|else|for|while|switch|case|return)\b"#: colors.keyword,
            #"\"[^\"]*\""#: colors.string,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "sql":
        return [
            #"\b(SELECT|INSERT|UPDATE|DELETE|CREATE|TABLE|FROM|WHERE|JOIN|LEFT|RIGHT|INNER|OUTER|GROUP|BY|ORDER|LIMIT|VALUES|INTO)\b"#: colors.keyword,
            #"'[^']*'|\"[^\"]*\""#: colors.string,
            #"--.*"#: colors.comment,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number
        ]
    case "xml":
        return [
            #"<[^>]+>"#: colors.tag,
            #"\"[^\"]*\""#: colors.string
        ]
    case "yaml":
        return [
            #"(?m)^\s*#.*$"#: colors.comment,
            #"(?m)^\s*-\s+.*$"#: colors.keyword,
            #"(?m)^\s*[A-Za-z0-9_.-]+\s*:"#: colors.property,
            #"\"([^\"\\]|\\.)*\"|'[^']*'"#: colors.string,
            #"\b(true|false|null|yes|no|on|off)\b"#: colors.keyword,
            #"\b-?[0-9]+(\.[0-9]+)?\b"#: colors.number,
            #"(?m)^---$|(?m)^\.\.\.$"#: colors.meta,
            #"&[A-Za-z0-9_-]+|\\*[A-Za-z0-9_-]+"#: colors.variable,
            #"!<[^>]+>|![A-Za-z0-9_./:-]+"#: colors.attribute
        ]
    case "toml":
        return [
            #"^\s*\[\[?[^\]]+\]?\]\s*$"#: colors.meta,
            #"^\s*[A-Za-z0-9_.-]+\s*="#: colors.property,
            #"\"([^\"\\]|\\.)*\"|'[^']*'"#: colors.string,
            #"\b(-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?)\b"#: colors.number,
            #"\b(true|false)\b"#: colors.keyword,
            #"(?m)#.*$"#: colors.comment
        ]
    case "csv":
        if profile == .csvFast {
            return [
                // Fast CSV profile for large datasets: keep only separators/headers/quoted chunks.
                #"(?m)^[^\n,]+(,\s*[^\n,]+)*$"#: colors.meta,
                #"\"([^\"\n]|\"\")*\""#: colors.string,
                #","#: colors.property
            ]
        }
        return [
            #"\A([^\n,]+)(,\s*[^\n,]+)*"#: colors.meta,
            #"\"([^\"\n]|\"\")*\""#: colors.string,
            #"\b(-?[0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #","#: colors.property
        ]
    case "ini":
        return [
            #"^\[[^\]]+\]"#: colors.meta,
            #"^;.*$"#: colors.comment,
            #"^\w+\s*=\s*.*$"#: colors.property
        ]
    case "vim":
        return [
            #"\b(set|let|if|endif|for|endfor|while|endwhile|function|endfunction|command|autocmd|syntax|highlight|nnoremap|inoremap|vnoremap|map|nmap|imap|vmap)\b"#: colors.keyword,
            #"\$[A-Za-z_][A-Za-z0-9_]*|[gbwtslv]:[A-Za-z_][A-Za-z0-9_]*"#: colors.variable,
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            #"^\s*\".*$"#: colors.comment,
            #"\b[0-9]+\b"#: colors.number
        ]
    case "log":
        return [
            #"\b(ERROR|ERR|FATAL|WARN|WARNING|INFO|DEBUG|TRACE)\b"#: colors.keyword,
            #"\b[0-9]{4}-[0-9]{2}-[0-9]{2}[ T][0-9:.+-Z]+\b"#: colors.meta,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #"(Exception|Traceback|Caused by:).*"#: colors.attribute
        ]
    case "ipynb":
        return [
            #"\"(cells|metadata|source|outputs|execution_count|cell_type|kernelspec|language_info)\"\s*:"#: colors.property,
            #"\"([^\"\\]|\\.)*\""#: colors.string,
            #"\b(-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?)\b"#: colors.number,
            #"\b(true|false|null)\b"#: colors.keyword,
            #"[{}\[\],:]"#: colors.meta
        ]
    case "csharp":
        return [
            #"\b(class|interface|enum|struct|namespace|using|public|private|protected|internal|static|readonly|sealed|abstract|virtual|override|async|await|new|return|if|else|for|foreach|while|do|switch|case|break|continue|try|catch|finally|throw)\b"#: colors.keyword,
            #"\b(string|int|double|float|bool|decimal|char|void|object|var|List<[^>]+>|Dictionary<[^>]+>)\b"#: colors.type,
            #"\"[^\"]*\""#: colors.string,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment
        ]
    case "cobol":
        return [
            #"(?i)\b(identification|environment|data|procedure|division|section|program-id|author|installati?on|date-written|date-compiled|working-storage|linkage|file-control|input-output|select|assign|fd|01|77|88|level|pic|picture|value|values|move|add|subtract|multiply|divide|compute|if|else|end-if|evaluate|when|perform|until|varying|go|to|goback|stop|run|call|accept|display|open|close|read|write|rewrite|delete|string|unstring|initialize|set|inspect)\b"#: colors.keyword,
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #"(?m)^\s*\*.*$|(?m)^\s*\*>.*$"#: colors.comment
        ]
    case "dotenv":
        return [
            #"(?m)^\s*[A-Z_][A-Z0-9_]*\s*="#: colors.property,
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            #"(?m)#.*$"#: colors.comment
        ]
    case "proto":
        return [
            #"\b(syntax|package|import|option|message|enum|service|rpc|returns|repeated|map|oneof|reserved|required|optional)\b"#: colors.keyword,
            #"\b(int32|int64|uint32|uint64|sint32|sint64|fixed32|fixed64|sfixed32|sfixed64|bool|string|bytes|double|float)\b"#: colors.type,
            #"\"[^\"]*\""#: colors.string,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/"#: colors.comment
        ]
    case "graphql":
        return [
            #"\b(type|interface|enum|union|input|scalar|schema|extend|implements|directive|on|query|mutation|subscription|fragment)\b"#: colors.keyword,
            #"\b([A-Z][A-Za-z0-9_]*)\b"#: colors.type,
            #"\"[^\"]*\""#: colors.string,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #"(?m)#.*$"#: colors.comment
        ]
    case "rst":
        return [
            #"(?m)^\s*([=\-`:'\"~^_*+<>#]{3,})\s*$"#: colors.keyword,
            #"(?m)^\s*\.\.\s+[A-Za-z-]+::.*$"#: colors.meta,
            #"(?m)^:?[A-Za-z-]+:\s+.*$"#: colors.property,
            #"\*\*[^*]+\*\*"#: colors.def,
            #"(?m)#.*$"#: colors.comment
        ]
    case "nginx":
        return [
            #"\b(http|server|location|upstream|map|if|set|return|rewrite|proxy_pass|listen|server_name|root|index|try_files|include|error_page|access_log|error_log|gzip|ssl|add_header)\b"#: colors.keyword,
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            #"\"[^\"]*\"|'[^']*'"#: colors.string,
            #"(?m)#.*$"#: colors.comment,
            #"[{};]"#: colors.meta
        ]
    case "standard":
        return [
            // Strings (double/single/backtick)
            #"\"[^\"]*\"|'[^']*'|`[^`]*`"#: colors.string,
            // Numbers
            #"\b([0-9]+(\.[0-9]+)?)\b"#: colors.number,
            // Line and block comments for C-like and hash comments
            #"//.*|/\*([^*]|(\*+[^*/]))*\*+/|#.*"#: colors.comment,
            // Common keywords from several languages
            #"\b(if|else|for|while|do|switch|case|return|class|struct|enum|func|function|var|let|const|import|from|using|namespace|public|private|protected|static|void|new|try|catch|finally|throw)\b"#: colors.keyword
        ]
    case "plain":
        return [:]
    default:
        return [:]
    }
}

// Simple sheet to edit and persist API tokens for external AI providers.
