import type { Style8DSamplePost } from './styleProfile'

export type EvidenceSegment =
  | { type: 'text'; value: string }
  | { type: 'link'; value: string; href: string }
  | { type: 'postRef'; value: string; postRef: number }

export interface ParsedEvidence {
  displayText: string
  permalink?: string
  postRef?: number
  segments: EvidenceSegment[]
}

const URL_RE = /https?:\/\/[^\s<>"')\]]+/g
const POST_REF_RE = /^\[(\d{1,2})\]\s*/

function normalizeForMatch(value: string): string {
  return value
    .replace(/["""''「」『』]/g, '')
    .replace(/\s+/g, '')
    .toLowerCase()
}

function stripQuoteWrapper(value: string): string {
  return value.replace(/^["""''「」『』]+|["""''「」『』]+$/g, '').trim()
}

function parsePostRef(raw: string): { postRef?: number; rest: string } {
  const match = raw.match(POST_REF_RE)
  if (!match) return { rest: raw.trim() }
  return { postRef: Number.parseInt(match[1], 10), rest: raw.slice(match[0].length).trim() }
}

function findMatchingPost(text: string, samplePosts: Style8DSamplePost[]): Style8DSamplePost | undefined {
  const cleaned = stripQuoteWrapper(text)
  const norm = normalizeForMatch(cleaned)
  if (norm.length < 6) return undefined

  let best: { post?: Style8DSamplePost; score: number } = { score: 0 }
  for (const post of samplePosts) {
    const postNorm = normalizeForMatch(post.text)
    if (!postNorm) continue
    if (postNorm.includes(norm) || norm.includes(postNorm.slice(0, Math.min(48, postNorm.length)))) {
      const score = Math.min(norm.length, postNorm.length)
      if (score > best.score) best = { post, score }
    }
  }
  return best.post
}

export function linkifyEvidenceText(text: string): EvidenceSegment[] {
  const segments: EvidenceSegment[] = []
  let last = 0
  for (const match of text.matchAll(URL_RE)) {
    const index = match.index ?? 0
    if (index > last) {
      segments.push({ type: 'text', value: text.slice(last, index) })
    }
    const href = match[0]
    segments.push({ type: 'link', value: href, href })
    last = index + href.length
  }
  if (last < text.length) {
    segments.push({ type: 'text', value: text.slice(last) })
  }
  return segments.length ? segments : [{ type: 'text', value: text }]
}

export function parseEvidenceItem(item: string, samplePosts: Style8DSamplePost[] = []): ParsedEvidence {
  const trimmed = item.trim()
  const { postRef, rest } = parsePostRef(trimmed)
  const displayText = stripQuoteWrapper(rest) || trimmed

  let permalink: string | undefined
  if (postRef && samplePosts[postRef - 1]?.permalink) {
    permalink = samplePosts[postRef - 1].permalink
  } else {
    const matched = findMatchingPost(rest, samplePosts)
    if (matched?.permalink) permalink = matched.permalink
  }

  const segments: EvidenceSegment[] = []
  if (postRef) {
    segments.push({ type: 'postRef', value: `[${postRef}]`, postRef })
    if (displayText) segments.push({ type: 'text', value: ' ' })
  }
  segments.push(...linkifyEvidenceText(displayText))

  return { displayText, permalink, postRef, segments }
}