import type { TimelineSection } from "./timeline-types"

interface LLMExportInput {
  traceId: string
  functionName: string | null
  filePath: string | null
  originalCode: string | null
  sections: TimelineSection[]
  errors: Array<{
    error_type: string | null
    severity: string | null
    error_message: string | null
    context: {
      test_name?: string
      failure_reason?: string
      test_output?: string
      expected?: string
      actual?: string
    } | null
    created_at: Date
  }>
  totalDuration: number
}

function formatDuration(ms: number): string {
  if (ms < 1000) return `${Math.round(ms)}ms`
  return `${(ms / 1000).toFixed(1)}s`
}

function formatCost(cost: number | null | undefined): string {
  if (cost == null || cost === 0) return "$0.00"
  if (cost < 0.01) return `$${cost.toFixed(4)}`
  return `$${cost.toFixed(2)}`
}

export function formatTimelineForLLM(input: LLMExportInput): string {
  const { traceId, functionName, filePath, originalCode, sections, errors, totalDuration } = input
  const lines: string[] = []

  lines.push(`# Optimization Trace: ${traceId}`)
  if (functionName) lines.push(`## Function: ${functionName}`)
  if (filePath) lines.push(`File: ${filePath}`)
  lines.push("")

  if (originalCode) {
    lines.push("### Original Code")
    lines.push("```python")
    lines.push(originalCode)
    lines.push("```")
    lines.push("")
  }

  lines.push("---")
  lines.push("## Timeline")
  lines.push("")

  let sectionNum = 0
  for (const section of sections) {
    sectionNum++
    lines.push(`### ${sectionNum}. ${section.title}`)

    const meta: string[] = []
    if (section.model) meta.push(`Model: ${section.model}`)
    if (section.cost != null) meta.push(`Cost: ${formatCost(section.cost)}`)
    if (section.tokens != null) meta.push(`Tokens: ${section.tokens}`)
    if (section.duration != null) meta.push(`Duration: ${formatDuration(section.duration)}`)
    meta.push(`Status: ${section.status}`)
    if (meta.length > 0) lines.push(meta.join(" | "))
    lines.push("")

    const content = section.content

    if (content.type === "tests") {
      if (content.testFramework) {
        lines.push(`Test framework: ${content.testFramework}`)
        lines.push("")
      }
      for (const group of content.testGroups) {
        if (group.generated) {
          lines.push(`#### Generated Test ${group.index}`)
          lines.push("```python")
          lines.push(group.generated.code)
          lines.push("```")
          lines.push("")
        }
      }
    } else if (content.type === "candidate" || content.type === "refinement") {
      if (content.rank != null) {
        lines.push(`Rank: #${content.rank}${content.isBest ? " (Best)" : ""}`)
        lines.push("")
      }
      if (content.explanation) {
        lines.push("#### Explanation")
        lines.push(content.explanation)
        lines.push("")
      }
      lines.push("#### Optimized Code")
      lines.push("```python")
      lines.push(content.code)
      lines.push("```")
      lines.push("")
    } else if (content.type === "ranking") {
      if (content.explanation) {
        lines.push("#### Ranking Explanation")
        lines.push(content.explanation)
        lines.push("")
      }
      for (const r of content.rankings) {
        lines.push(`${r.rank}. ${r.label}${r.isBest ? " (Best)" : ""}`)
      }
      if (content.usedForPr) {
        lines.push("")
        lines.push("*Used for pull request*")
      }
      lines.push("")
    } else if (content.type === "summary") {
      lines.push(`- Total Cost: ${formatCost(content.metrics.totalCost)}`)
      lines.push(`- Total Tokens: ${content.metrics.totalTokens}`)
      lines.push(`- Total Duration: ${formatDuration(content.metrics.totalDuration)}`)
      lines.push(`- Candidates: ${content.metrics.candidatesCount}`)
      lines.push("")
    }

    if (section.debugData) {
      lines.push(`#### Debug: LLM Call ID: ${section.debugData.callId}`)
      lines.push("")
    }
  }

  if (errors.length > 0) {
    lines.push("---")
    lines.push("## Errors")
    lines.push("")
    for (const error of errors) {
      lines.push(`### ${error.error_type || "Error"}${error.severity ? ` (${error.severity})` : ""}`)
      if (error.error_message) lines.push(error.error_message)
      if (error.context) {
        const ctx = error.context
        if (ctx.test_name) lines.push(`Test: ${ctx.test_name}`)
        if (ctx.failure_reason) lines.push(`Reason: ${ctx.failure_reason}`)
        if (ctx.test_output) {
          lines.push("```")
          lines.push(ctx.test_output)
          lines.push("```")
        }
        if (ctx.expected) lines.push(`Expected: ${ctx.expected}`)
        if (ctx.actual) lines.push(`Actual: ${ctx.actual}`)
      }
      lines.push("")
    }
  }

  const totalCost = sections.reduce((sum, s) => sum + (s.cost ?? 0), 0)
  const totalTokens = sections.reduce((sum, s) => sum + (s.tokens ?? 0), 0)
  const candidatesCount = sections.filter(
    s => s.type === "optimization" || s.type === "line_profiler" || s.type === "refinement" || s.type === "adaptive",
  ).length

  lines.push("---")
  lines.push("## Summary")
  lines.push(`- Total Cost: ${formatCost(totalCost)}`)
  lines.push(`- Total Tokens: ${totalTokens}`)
  lines.push(`- Total Duration: ${formatDuration(totalDuration)}`)
  lines.push(`- Candidates: ${candidatesCount}`)
  if (errors.length > 0) lines.push(`- Errors: ${errors.length}`)
  lines.push("")

  return lines.join("\n")
}
