import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/lib/common'
// 按需导入 common 包不包含的语言
import 'highlight.js/lib/languages/powershell'
import 'highlight.js/lib/languages/dos'
import 'highlight.js/lib/languages/autohotkey'
import 'highlight.js/lib/languages/latex'
import 'highlight.js/lib/languages/dockerfile'
import 'highlight.js/lib/languages/cmake'
import 'highlight.js/lib/languages/scala'
import 'highlight.js/lib/languages/dart'
import { getHljsLanguage } from './languageMap'

let mermaidInstance: typeof import('mermaid').default | null = null
let mermaidTheme: string | null = null

// 检测当前是否为暗色主题
function isDarkTheme(): boolean {
  if (typeof document === 'undefined') return false
  return document.body.getAttribute('arco-theme')?.includes('dark') ?? false
}

async function loadMermaid() {
  const currentTheme = isDarkTheme() ? 'dark' : 'default'

  if (mermaidInstance && mermaidTheme === currentTheme) {
    return mermaidInstance
  }

  if (!mermaidInstance) {
    const m = await import('mermaid')
    mermaidInstance = m.default
  }
  mermaidInstance.initialize({
    startOnLoad: false,
    theme: currentTheme,
    securityLevel: 'strict',
    themeVariables: Object.assign({
      primaryColor: '#165DFF',
      primaryTextColor: '#ffffff',
      primaryBorderColor: '#4080FF'
    }, currentTheme === 'dark' ? {
      lineColor: '#4E5969',
      secondaryColor: '#0E42D2',
      tertiaryColor: '#0FC6C2',
      mainBkg: '#17171A',
      nodeBorder: '#165DFF',
      clusterBkg: '#232324',
      titleColor: '#FFFFFF',
      edgeLabelBackground: '#232324'
    } : {
      lineColor: '#86909C',
      secondaryColor: '#E8F3FF',
      tertiaryColor: '#722ED1',
      mainBkg: '#F2F3F5',
      nodeBorder: '#165DFF',
      clusterBkg: '#F7F8FA',
      titleColor: '#1D2129',
      edgeLabelBackground: '#F2F3F5'
    })
  })
  mermaidTheme = currentTheme
  return mermaidInstance
}

const renderer = new marked.Renderer()

renderer.code = function(token: any) {
  if (token.lang === 'mermaid') {
    return `<pre class="mermaid">${token.text}</pre>`
  }

  const lang = getHljsLanguage(token.lang)

  let highlighted: string
  try {
    highlighted = hljs.highlight(token.text, { language: lang }).value
  } catch {
    highlighted = token.text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
  }
  return `<pre><code class="hljs language-${lang}" data-theme="auto">${highlighted}</code></pre>`
}

renderer.heading = function(token: any) {
  const raw = token.raw || ''
  const depth = token.depth || 1
  const text = token.text || ''

  const id = raw
    .toLowerCase()
    .replace(/[^\u4e00-\u9fa5a-z0-9\s-]/g, '')
    .trim()
    .replace(/\s+/g, '-')
    .replace(/-+/g, '-')
    .replace(/^-+|-+$/g, '') || `heading-${Math.random().toString(36).slice(2, 11)}`

  return `<h${depth} id="${id}" class="heading">
    ${text}<a href="#${id}" class="heading-anchor" aria-hidden="true" title="跳转到此标题">#</a>
  </h${depth}>`
}

// ========== 图片相对路径转换支持 ==========
// 当前 Markdown 文件所在目录（由调用方在渲染前设置）
let _currentFileDir: string = ''
// 文件服务器 Base URL（由调用方在渲染前设置）
let _fileServerBase: string = 'http://localhost:2652/localfs'

/**
 * 设置当前 Markdown 文件所在目录（用于图片相对路径→文件服务器 URL 转换）
 * @param dir 文件所在目录的绝对路径，如 "D:/docs" 或 "/"（根目录）
 */
export function setCurrentFileDir(dir: string): void {
  _currentFileDir = dir
}

/** 获取当前设置的文件目录 */
export function getCurrentFileDir(): string {
  return _currentFileDir
}

/**
 * 设置文件服务器 Base URL（用于图片相对路径转换）
 * @param base 完整的 base URL 前缀，如 "http://localhost:2652/localfs" 或 "https://host:port/api/v1/proxy/localfs"
 */
export function setFileServerBase(base: string): void {
  _fileServerBase = base
}

/**
 * 将相对路径图片 src 解析为文件服务器 URL
 * - 绝对路径（Windows: D:/...、Unix: /usr/...）、网络URL、data URI → 不转换
 * - 相对路径 → 基于当前文件目录解析为绝对路径，再编码为文件服务器 URL
 */
function resolveImageUrl(src: string, fileServerBase: string): string {
  if (!src) return src
  // 不转换：绝对路径（Windows 盘符）、网络协议、锚点、data URI
  if (/^(?:[a-zA-Z]:[/\\]|\/(?:[^/]|$)|https?:|ftp:|data:|#)/i.test(src)) return src

  // 解析相对路径（处理 ../ 和 ./）
  const dir = _currentFileDir || '/'
  const sep = dir.includes('\\') ? '\\' : '/'
  let resolved = normalizeRelativePath(dir, src, sep)

  // 编码路径（保留 / 分隔符）
  const encoded = encodeURIComponent(resolved).replace(/%2F/gi, '/').replace(/%5C/gi, '\\')
  return `${fileServerBase}/${encoded}`
}

/**
 * 规范化相对路径，处理 .. 和 . 段
 */
function normalizeRelativePath(base: string, relative: string, sep: string): string {
  // 确保基础路径不以分隔符结尾
  let baseNormalized = base.replace(/[\\/]+$/, '')
  if (!baseNormalized) baseNormalized = sep === '/' ? '/' : 'C:\\'

  const baseParts = baseNormalized.split(sep).filter(Boolean)
  const relParts = relative.split(/[\\/]/).filter(Boolean)

  for (const part of relParts) {
    if (part === '..') {
      baseParts.pop() // 向上一级
    } else if (part !== '.') {
      baseParts.push(part)
    }
  }

  // 重建路径：Windows 绝对路径保留盘符前缀
  if (/^[a-zA-Z]:$/i.test(baseNormalized.split(sep)[0] || '')) {
    return baseParts.join(sep)
  }
  // Unix 风格：以 / 开头
  return sep + baseParts.join(sep)
}

// 判断是否为本地文件链接（相对路径或本地绝对路径）
const isLocalFileLink = (href: string): boolean => {
  if (!href) return false
  if (/^(https?|ftp|mailto|tel|data):/i.test(href)) return false
  if (href.startsWith('#')) return false
  return true
}

// 自定义图片渲染器 - 转换相对路径为文件服务器 URL
renderer.image = function(token: any) {
  const src = token.href || ''
  const title = token.title || ''
  const alt = token.text || ''
  const titleAttr = title ? ` title="${title}"` : ''

  // 判断是否需要转换（仅处理相对路径，且当前目录已设置）
  if (_currentFileDir && !/^(?:[a-zA-Z]:[/\\]|\/(?:[^/]|$)|https?:|ftp:|data:|#)/i.test(src)) {
    const resolvedSrc = resolveImageUrl(src, _fileServerBase)
    return `<img src="${resolvedSrc}" alt="${alt}"${titleAttr}>`
  }

  // 默认渲染（绝对路径 / 网络 URL / data URI / 未设置目录时原样输出）
  return `<img src="${src}" alt="${alt}"${titleAttr}>`
}

// 自定义链接渲染器 - 支持本地文件链接
renderer.link = function(token: any) {
  const href = token.href || ''
  const text = this.parser.parseInline(token.tokens) || token.text || ''
  const title = token.title || ''
  const titleAttr = title ? ` title="${title}"` : ''

  if (href.startsWith('#')) {
    return `<a href="${href}${titleAttr}">${text}</a>`
  }

  if (isLocalFileLink(href)) {
    return `<a href="javascript:void(0)" data-local-link="${href}" class="local-file-link"${titleAttr}>${text}</a>`
  }

  return `<a href="${href}" target="_blank" rel="noopener noreferrer"${titleAttr}>${text}</a>`
}

marked.use({ renderer, breaks: true, gfm: true, async: false })

export { marked }

export async function renderMermaidDiagrams() {
  const mermaid = await loadMermaid()
  if (mermaid) {
    // 渲染前保存原始源码（textContent 在 SVG 渲染后会变成 CSS 垃圾）
    document.querySelectorAll('.mermaid:not([data-mermaid-src])').forEach(pre => {
      ;(pre as HTMLElement).setAttribute('data-mermaid-src', pre.textContent || '')
    })
    await mermaid.run()
  }
}

/** 清除已渲染内容并重新渲染（用于主题切换后刷新） */
export async function rerenderMermaidDiagrams(container?: HTMLElement | null) {
  // 强制重新加载（清除缓存，让下次 loadMermaid 重新初始化新主题）
  mermaidInstance = null
  mermaidTheme = null

  const target = container || document
  target.querySelectorAll('.mermaid').forEach(pre => {
    const el = pre as HTMLElement
    if (el.getAttribute('data-processed')) {
      // 从保存的原始源码恢复，而非 textContent（SVG 的 textContent 是 CSS 垃圾）
      el.innerHTML = el.getAttribute('data-mermaid-src') || ''
      el.removeAttribute('data-processed')
    }
  })
  await renderMermaidDiagrams()
}
