/**
 * 读取服务器上的代码文件内容
 * 由于是静态站点，我们通过 fetch 请求加载 .c 文件
 */
export async function loadCodeFile(path) {
  try {
    const response = await fetch(`/${path}`)
    if (!response.ok) {
      throw new Error(`Failed to load ${path}: ${response.status}`)
    }
    return await response.text()
  } catch (error) {
    console.error('加载代码文件失败:', error)
    return `// 无法加载文件: ${path}\n// 请确保文件存在且路径正确`
  }
}

/**
 * C语言关键字高亮（基于 Token 的稳健实现）
 * 逐字符解析，避免正则误匹配已插入的 HTML 标签
 */
export function highlightC(code) {
  const keywords = new Set([
    'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
    'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if',
    'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof', 'static',
    'struct', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while',
    'include', 'define', 'ifdef', 'ifndef', 'endif', 'main', 'printf', 'scanf'
  ])

  let result = ''
  let i = 0
  const len = code.length

  while (i < len) {
    // 预处理指令（行首 #）
    if (code[i] === '#' && (i === 0 || code[i - 1] === '\n')) {
      let end = i + 1
      while (end < len && code[end] !== '\n') end++
      const line = code.slice(i, end)
      result += '<span class="hl-preprocessor">' + escapeHtml(line) + '</span>'
      i = end
      continue
    }

    // 单行注释 //
    if (code[i] === '/' && i + 1 < len && code[i + 1] === '/') {
      let end = i + 2
      while (end < len && code[end] !== '\n') end++
      result += '<span class="hl-comment">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 多行注释 /* */
    if (code[i] === '/' && i + 1 < len && code[i + 1] === '*') {
      let end = i + 2
      while (end + 1 < len && !(code[end] === '*' && code[end + 1] === '/')) end++
      if (end + 1 < len) end += 2
      result += '<span class="hl-comment">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 双引号字符串 "..."
    if (code[i] === '"') {
      let end = i + 1
      while (end < len && code[end] !== '"') {
        if (code[end] === '\\') end++ // 跳过转义字符
        end++
      }
      if (end < len) end++ // 包含结束引号
      result += '<span class="hl-string">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 单引号字符 '...'
    if (code[i] === "'") {
      let end = i + 1
      while (end < len && code[end] !== "'") {
        if (code[end] === '\\') end++
        end++
      }
      if (end < len) end++
      result += '<span class="hl-string">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 数字（整数/浮点数）
    if (isDigit(code[i]) || (code[i] === '.' && i + 1 < len && isDigit(code[i + 1]))) {
      let start = i
      if (code[i] === '0' && i + 1 < len && (code[i + 1] === 'x' || code[i + 1] === 'X')) {
        // 十六进制
        i += 2
        while (i < len && isHexDigit(code[i])) i++
      } else {
        while (i < len && isDigit(code[i])) i++
        if (i < len && code[i] === '.') {
          i++
          while (i < len && isDigit(code[i])) i++
        }
        if (i < len && (code[i] === 'e' || code[i] === 'E')) {
          i++
          if (i < len && (code[i] === '+' || code[i] === '-')) i++
          while (i < len && isDigit(code[i])) i++
        }
      }
      // 确保不是标识符的一部分
      if (i < len && isWordChar(code[i])) {
        // 回退，按普通文本处理
        i = start
        result += escapeHtml(code[i])
        i++
      } else {
        result += '<span class="hl-number">' + escapeHtml(code.slice(start, i)) + '</span>'
      }
      continue
    }

    // 标识符/关键字
    if (isWordStart(code[i])) {
      let start = i
      while (i < len && isWordChar(code[i])) i++
      const word = code.slice(start, i)
      if (keywords.has(word)) {
        result += '<span class="hl-keyword">' + escapeHtml(word) + '</span>'
      } else {
        result += escapeHtml(word)
      }
      continue
    }

    // 其他字符
    result += escapeHtml(code[i])
    i++
  }

  return result
}

/**
 * Python 语法高亮
 */
export function highlightPython(code) {
  const keywords = new Set([
    'False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await',
    'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except',
    'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is',
    'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return',
    'try', 'while', 'with', 'yield', 'print', 'range', 'len', 'int',
    'float', 'str', 'list', 'dict', 'set', 'tuple', 'bool', 'input',
    'enumerate', 'zip', 'map', 'filter', 'sorted', 'reversed', 'open',
    'self', 'cls', 'super', 'property', 'staticmethod', 'classmethod',
    'TypeVar', 'Optional', 'List', 'Dict', 'Tuple', 'Any', 'Union'
  ])

  const builtins = new Set([
    'print', 'range', 'len', 'int', 'float', 'str', 'list', 'dict',
    'set', 'tuple', 'bool', 'input', 'enumerate', 'zip', 'map',
    'filter', 'sorted', 'reversed', 'open', 'type', 'isinstance',
    'hasattr', 'getattr', 'setattr', 'abs', 'max', 'min', 'sum',
    'all', 'any', 'ord', 'chr', 'repr', 'format', 'id', 'hash'
  ])

  let result = ''
  let i = 0
  const len = code.length

  while (i < len) {
    // 单行注释 #
    if (code[i] === '#') {
      let end = i + 1
      while (end < len && code[end] !== '\n') end++
      result += '<span class="hl-comment">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 多行注释/文档字符串 """...""" 或 '''...'''
    if ((code[i] === '"' && i + 2 < len && code[i + 1] === '"' && code[i + 2] === '"') ||
        (code[i] === "'" && i + 2 < len && code[i + 1] === "'" && code[i + 2] === "'")) {
      const quote = code.slice(i, i + 3)
      let end = i + 3
      while (end + 2 < len && code.slice(end, end + 3) !== quote) {
        if (code[end] === '\\') end++
        end++
      }
      if (end + 2 < len) end += 3
      result += '<span class="hl-comment">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 双引号字符串 "..."
    if (code[i] === '"') {
      let end = i + 1
      while (end < len && code[end] !== '"') {
        if (code[end] === '\\') end++
        end++
      }
      if (end < len) end++
      result += '<span class="hl-string">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 单引号字符串 '...'
    if (code[i] === "'") {
      let end = i + 1
      while (end < len && code[end] !== "'") {
        if (code[end] === '\\') end++
        end++
      }
      if (end < len) end++
      result += '<span class="hl-string">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // f-string f"..."
    if (code[i] === 'f' && i + 1 < len && code[i + 1] === '"') {
      let end = i + 2
      const stack = []
      while (end < len && code[end] !== '"') {
        if (code[end] === '{') stack.push(end)
        else if (code[end] === '}' && stack.length) stack.pop()
        if (code[end] === '\\') end++
        end++
      }
      if (end < len) end++
      result += '<span class="hl-string">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 数字
    if (isDigit(code[i]) || (code[i] === '.' && i + 1 < len && isDigit(code[i + 1]))) {
      let start = i
      while (i < len && (isDigit(code[i]) || code[i] === '.' || code[i] === 'e' || code[i] === 'E' ||
             code[i] === 'x' || code[i] === 'X' || code[i] === 'o' || code[i] === 'O' ||
             code[i] === 'b' || code[i] === 'B' || code[i] === '+' || code[i] === '-' ||
             (code[i] >= 'a' && code[i] <= 'f') || (code[i] >= 'A' && code[i] <= 'F'))) {
        // 简单数字检测，遇到非数字字符停止
        if (isWordChar(code[i]) && !isDigit(code[i]) &&
            !(code[i] >= 'a' && code[i] <= 'f') && !(code[i] >= 'A' && code[i] <= 'F') &&
            code[i] !== 'x' && code[i] !== 'X' && code[i] !== 'o' && code[i] !== 'O' &&
            code[i] !== 'b' && code[i] !== 'B' && code[i] !== 'e' && code[i] !== 'E' &&
            code[i] !== '.' && code[i] !== '+' && code[i] !== '-') break
        i++
      }
      result += '<span class="hl-number">' + escapeHtml(code.slice(start, i)) + '</span>'
      continue
    }

    // @decorator
    if (code[i] === '@' && i + 1 < len && isWordStart(code[i + 1])) {
      let end = i + 1
      while (end < len && isWordChar(code[end])) end++
      result += '<span class="hl-preprocessor">' + escapeHtml(code.slice(i, end)) + '</span>'
      i = end
      continue
    }

    // 标识符/关键字
    if (isWordStart(code[i])) {
      let start = i
      while (i < len && isWordChar(code[i])) i++
      const word = code.slice(start, i)
      if (keywords.has(word)) {
        result += '<span class="hl-keyword">' + escapeHtml(word) + '</span>'
      } else if (builtins.has(word)) {
        result += '<span class="hl-preprocessor">' + escapeHtml(word) + '</span>'
      } else {
        result += escapeHtml(word)
      }
      continue
    }

    // 其他字符
    result += escapeHtml(code[i])
    i++
  }

  return result
}

function escapeHtml(str) {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
}

function isDigit(c) {
  return c >= '0' && c <= '9'
}

function isHexDigit(c) {
  return isDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
}

function isWordStart(c) {
  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c === '_'
}

function isWordChar(c) {
  return isWordStart(c) || isDigit(c)
}
