import hljs from 'highlight.js/lib/common'

if (typeof window !== 'undefined') {
  const theme =
    document.documentElement.dataset.theme ||
    (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
  if (theme === 'dark') {
    import('highlight.js/styles/atom-one-dark.css')
  } else {
    import('highlight.js/styles/atom-one-light.css')
  }
}
import MarkdownIt from 'markdown-it'
import { toast } from '../main'
import { tiebaEmoji } from './tiebaEmoji'

function mentionPlugin(md) {
  const mentionReg = /^@\[([^\]]+)\]/
  function mention(state, silent) {
    const pos = state.pos
    if (state.src.charCodeAt(pos) !== 0x40) return false
    const match = mentionReg.exec(state.src.slice(pos))
    if (!match) return false
    if (!silent) {
      const tokenOpen = state.push('link_open', 'a', 1)
      tokenOpen.attrs = [
        ['href', `/users/${match[1]}`],
        ['target', '_blank'],
        ['class', 'mention-link'],
      ]
      const text = state.push('text', '', 0)
      text.content = `@${match[1]}`
      state.push('link_close', 'a', -1)
    }
    state.pos += match[0].length
    return true
  }
  md.inline.ruler.before('emphasis', 'mention', mention)
}

function tiebaEmojiPlugin(md) {
  md.renderer.rules['tieba-emoji'] = (tokens, idx) => {
    const name = tokens[idx].content
    const file = tiebaEmoji[name]
    return `<img class="emoji" src="${file}" alt="${name}">`
  }
  md.inline.ruler.before('emphasis', 'tieba-emoji', (state, silent) => {
    const pos = state.pos
    if (state.src.charCodeAt(pos) !== 0x3a) return false
    const match = state.src.slice(pos).match(/^:tieba(\d+):/)
    if (!match) return false
    const key = `tieba${match[1]}`
    if (!tiebaEmoji[key]) return false
    if (!silent) {
      const token = state.push('tieba-emoji', '', 0)
      token.content = key
    }
    state.pos += match[0].length
    return true
  })
}

// 链接在新窗口打开
function linkPlugin(md) {
  const defaultRender =
    md.renderer.rules.link_open ||
    function (tokens, idx, options, env, self) {
      return self.renderToken(tokens, idx, options)
    }

  md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
    const token = tokens[idx]
    const hrefIndex = token.attrIndex('href')

    if (hrefIndex >= 0) {
      const href = token.attrs[hrefIndex][1]
      // 如果是外部链接，添加 target="_blank" 和 rel="noopener noreferrer"
      if (href.startsWith('http://') || href.startsWith('https://')) {
        token.attrPush(['target', '_blank'])
        token.attrPush(['rel', 'noopener noreferrer'])
      }
    }

    return defaultRender(tokens, idx, options, env, self)
  }
}

const md = new MarkdownIt({
  html: false,
  linkify: true,
  breaks: true,
  highlight: (str, lang) => {
    let code = ''
    if (lang && hljs.getLanguage(lang)) {
      code = hljs.highlight(str, { language: lang, ignoreIllegals: true }).value
    } else {
      code = hljs.highlightAuto(str).value
    }
    const lineNumbers = code
      .trim()
      .split('\n')
      .map(() => `<div class="line-number"></div>`)
    return `<pre class="code-block"><button class="copy-code-btn">Copy</button><div class="line-numbers">${lineNumbers.join('')}</div><code class="hljs language-${lang || ''}">${code.trim()}</code></pre>`
  },
})

md.use(mentionPlugin)
md.use(tiebaEmojiPlugin)
md.use(linkPlugin) // 添加链接插件

export function renderMarkdown(text) {
  return md.render(text || '')
}

export function handleMarkdownClick(e) {
  if (e.target.classList.contains('copy-code-btn')) {
    const pre = e.target.closest('pre')
    const codeEl = pre && pre.querySelector('code')
    if (codeEl) {
      navigator.clipboard.writeText(codeEl.innerText).then(() => {
        toast.success('已复制')
      })
    }
  }
}

export function stripMarkdown(text) {
  const html = md.render(text || '')

  // 统一使用正则表达式方法，确保服务端和客户端行为一致
  let plainText = html.replace(/<[^>]+>/g, '')

  // 标准化空白字符处理
  plainText = plainText
    .replace(/\r\n/g, '\n') // Windows换行符转为Unix格式
    .replace(/\r/g, '\n') // 旧Mac换行符转为Unix格式
    .replace(/[ \t]+/g, ' ') // 合并空格和制表符为单个空格
    .replace(/\n{3,}/g, '\n\n') // 最多保留两个连续换行（一个空行）
    .trim()

  return plainText
}

export function stripMarkdownLength(text, length) {
  const plain = stripMarkdown(text)
  if (!length || plain.length <= length) {
    return plain
  }
  // 截断并加省略号
  return plain.slice(0, length) + '...'
}
