/**
 * Grammar definition for JavaScript syntax highlighting.
 * Handles keywords, operators, strings, template literals, numbers,
 * regex literals, comments, functions, classes, and other JS constructs.
 */
export const javascriptGrammar = {
  'comment': [
    {
      pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
      lookbehind: true,
      greedy: true,
    },
    {
      pattern: /(^|[^\\:])\/\/.*/,
      lookbehind: true,
      greedy: true,
    },
  ],
  'string': [
    {
      pattern: /(["'])(?:\\[\s\S]|(?!\1)[^\\\r\n])*\1/,
      greedy: true,
    },
  ],
  'template-string': {
    pattern: /`(?:\\[\s\S]|[^\\`])*`/,
    greedy: true,
    inside: {
      'template-punctuation': {
        pattern: /^`|`$/,
      },
      'interpolation': {
        pattern: /\$\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}/,
        inside: {
          'interpolation-punctuation': {
            pattern: /^\$\{|\}$/,
          },
        },
      },
      'string': {
        pattern: /[\s\S]+/,
      },
    },
  },
  'regex': {
    pattern: 
    // eslint-disable-next-line no-useless-escape
    /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[.\r\n,;:})\]]|\/\/))/,
    lookbehind: true,
    greedy: true,
    inside: {
      'regex-source': {
        pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
        lookbehind: true,
      },
      'regex-delimiter': {
        pattern: /^\/|\/$/,
      },
      'regex-flags': {
        pattern: /^[a-z]+$/,
      },
    },
  },
  'class-name': [
    {
      pattern: /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,
      lookbehind: true,
      inside: {
        punctuation: { pattern: /[.\\]/ },
      },
    },
  ],
  'keyword': [
    {
      pattern: /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
    },
  ],
  'boolean': {
    pattern: /\b(?:false|true)\b/,
  },
  'number': {
    pattern: /\b(?:(?:0[xX][\dA-Fa-f](?:_[\dA-Fa-f])*|0[bB][01](?:_[01])*|0[oO][0-7](?:_[0-7])*)n?|(?:\d(?:_\d)*\.?\d*|\.\d+)(?:[Ee][+-]?\d(?:_\d)*)?n?|NaN|Infinity)\b/,
  },
  'function': {
    pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
  },
  'operator': {
    pattern: /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%|&^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/,
  },
  'punctuation': {
    pattern: /[{}[\];(),.:]/,
  },
  'constant': {
    pattern: /\b[A-Z](?:[A-Z_]|\dx)*\b/,
  },
};
