import { isSessionCachedImagePath } from '../shared/session-blob'
import {
  getCommitIdFromMention,
  renderCommitMarkdownLink,
} from './commit-mentions'

export function stripLeadingFocusFilesBlock(text: unknown): string {
  const normalized = String(text ?? '').replace(/\r/g, '')
  if (!normalized)
    return ''

  const lines = normalized.split('\n')
  const header = String(lines[0] ?? '').trim()
  if (header !== '[focus_files]' && header !== '[user_focus_files]') {
    const stripInlinePrefix = (raw: string): string | null => {
      const s = String(raw ?? '')
      if (!s)
        return null

      let idx = 0
      let matched = 0

      while (idx < s.length) {
        // Allow spaces between consecutive links.
        while (
          idx < s.length
          && (s[idx] === ' ' || s[idx] === '\t' || s[idx] === '\n')
        ) {
          idx++
        }

        const m = s.slice(idx).match(/^\[([^\]]*)\]\(((?:\\\)|[^)])+)\)/)
        if (!m)
          break

        let path = String(m[2] ?? '').trim()
        if (path.startsWith('<') && path.endsWith('>'))
          path = path.slice(1, -1)
        path = path.replace(/\\\)/g, ')').trim()

        const isAbs = path.startsWith('/') || /^[A-Z]:[\\/]/i.test(path)
        if (!isAbs)
          break

        matched++
        idx += m[0].length
      }

      if (!matched)
        return null

      let rest = s.slice(idx)
      rest = rest.replace(/^[ \t]+/g, '')
      if (rest.startsWith('\n\n'))
        rest = rest.slice(2)
      else if (rest.startsWith('\n'))
        rest = rest.slice(1)
      else if (rest.startsWith(' '))
        rest = rest.slice(1)
      return rest
    }

    const inlineStripped = stripInlinePrefix(normalized)
    if (inlineStripped !== null)
      return inlineStripped

    // Also strip the ACP "focus files prefix" format:
    // one markdown link per line, with absolute paths, followed by a blank line (or EOF).
    //
    // Example:
    // [foo.ts](/abs/foo.ts)
    //
    // hello
    let i = 0
    let matched = 0
    for (; i < lines.length; i++) {
      const line = String(lines[i] ?? '')
      if (!line.trim())
        break

      const m = line.match(/^\s*\[[^\]]*\]\((.+)\)\s*$/)
      if (!m)
        break

      let path = String(m[1] ?? '').trim()
      if (path.startsWith('<') && path.endsWith('>'))
        path = path.slice(1, -1)
      path = path.replace(/\\\)/g, ')').trim()

      const isAbs = path.startsWith('/') || /^[A-Z]:[\\/]/i.test(path)
      if (!isAbs)
        break

      matched++
    }

    if (!matched)
      return normalized

    while (i < lines.length && !String(lines[i] ?? '').trim()) i++

    return lines.slice(i).join('\n')
  }

  let i = 1
  for (; i < lines.length; i++) {
    const line = String(lines[i] ?? '')

    // A blank line terminates the block.
    if (!line.trim()) {
      i++
      break
    }

    // Match both `- [name](path)` and `- [name](<path>)`.
    const m = line.match(/^\s*-\s*\[[^\]]*\]\((.+)\)\s*$/)
    if (!m)
      break
  }

  while (i < lines.length && !String(lines[i] ?? '').trim()) i++

  return lines.slice(i).join('\n')
}

function escapeMarkdownLinkName(name: string): string {
  return name.replace(/\[/g, '\\[').replace(/\]/g, '\\]')
}

function escapeMarkdownLinkPath(path: string): string {
  return path.replace(/\)/g, '\\)')
}

function basenameFromPath(path: string): string {
  return path.split(/[/\\]/).filter(Boolean).pop() ?? path
}

export function focusFileDisplayLabel(absPath: string, index: number): string {
  const commitId = getCommitIdFromMention(absPath)
  if (commitId)
    return commitId
  if (isSessionCachedImagePath(absPath) && Number.isFinite(index) && index >= 0)
    return `Image #${index + 1}`
  return basenameFromPath(absPath)
}

export function renderFocusFilesMarkdownLinks(
  files: readonly string[] | undefined,
): string {
  const focusFiles = (files ?? []).map(f => String(f ?? '')).filter(Boolean)
  if (!focusFiles.length)
    return ''

  const links = focusFiles.map((f, idx) => {
    const p = String(f ?? '')
    const commitId = getCommitIdFromMention(p)
    if (commitId)
      return renderCommitMarkdownLink(commitId)
    const label = focusFileDisplayLabel(p, idx)
    const escapedName = escapeMarkdownLinkName(label)
    const escapedPath = escapeMarkdownLinkPath(p)
    return `[${escapedName}](${escapedPath})`
  })
  return links.join('\n')
}

export function renderFocusFilesMarkdownBlock(
  files: readonly string[] | undefined,
): string {
  const links = renderFocusFilesMarkdownLinks(files)
  if (!links)
    return ''
  return links
}
