import { KvPanel, SectionCard } from '@overdeck/deck-ui'
import type { JSX } from 'react'
import type { FactoryRunView } from '../../lib/factory-types'
import { CollapsibleText } from './FactoryTraceTables'
import {
  displayStatus,
  displayText,
  formatAbsoluteTimestamp,
  formatElapsed,
  formatEstimatedSpend,
  formatTokenCount,
  hostsForAttempts,
} from './factory-helpers'

function parsePayload(payloadJson: string | null): Record<string, unknown> | null {
  if (!payloadJson) return null
  try {
    const parsed = JSON.parse(payloadJson) as unknown
    return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)
      ? parsed as Record<string, unknown>
      : null
  } catch {
    return null
  }
}

function stringField(value: unknown): string | null {
  return typeof value === 'string' && value.trim() !== '' ? value.trim() : null
}

function modelProvider(model: string | null): string | null {
  if (!model || !model.includes('/')) return null
  return model.split('/', 1)[0] ?? null
}

const GPT_EFFORTS = ['medium', 'high', 'xhigh', 'pro']

// GPT seats carry their effort in the model id and run with thinking off, so the
// thinking field would report every one of them as "off".
function declaredEffort(model: string | null, thinking: string | null): string {
  const suffix = model?.split('-').pop()
  if (model?.startsWith('gpt/') && suffix && GPT_EFFORTS.includes(suffix)) return suffix
  return thinking ?? 'unknown'
}

function unique(values: Array<string | null | undefined>): string[] {
  return [...new Set(values.filter((value): value is string => typeof value === 'string' && value.trim() !== ''))]
}

function seatDeclarations(run: FactoryRunView): string {
  const entries = run.events
    .filter((event) => event.type === 'agent_start')
    .map((event) => {
      const payload = parsePayload(event.payloadJson)
      const name = stringField(event.name) ?? 'agent'
      const codingAgent = stringField(payload?.coding_agent) ?? 'unknown'
      const model = stringField(payload?.model) ?? 'unknown'
      const provider = stringField(payload?.provider) ?? modelProvider(model) ?? 'unknown'
      const effort = declaredEffort(stringField(payload?.model), stringField(payload?.thinking))
      return `${name}: ${codingAgent} · ${provider} · ${model} · effort ${effort}`
    })
  return entries.length > 0 ? entries.join('\n') : '—'
}

function sessionIdentity(run: FactoryRunView): string {
  const entries = run.events
    .filter((event) => event.type === 'agent_start')
    .map((event) => {
      const payload = parsePayload(event.payloadJson)
      const name = stringField(event.name) ?? 'agent'
      const sessionId = stringField(payload?.session_id) ?? 'unknown'
      const clientSessionId = stringField(payload?.client_session_id) ?? 'unavailable'
      return `${name}: pi ${sessionId} · sol ${clientSessionId}`
    })
  return entries.length > 0 ? entries.join('\n') : '—'
}

function accountsForAttempts(run: FactoryRunView): string {
  const values = unique((run.attempts ?? []).map((attempt) => attempt.account))
  return values.length > 0 ? values.join(', ') : '—'
}

function providerHealth(run: FactoryRunView): string {
  const values = unique((run.attempts ?? []).map((attempt) => {
    if (attempt.providerFailure) {
      return attempt.providerFailure.resumeAt
        ? `${displayText(attempt.agent, 'agent')}: ${attempt.providerFailure.kind} until ${attempt.providerFailure.resumeAt}`
        : `${displayText(attempt.agent, 'agent')}: ${attempt.providerFailure.kind}`
    }
    if (attempt.usage?.billingStatus) {
      return `${displayText(attempt.agent, 'agent')}: no failure · billing ${attempt.usage.billingStatus}`
    }
    return null
  }))
  return values.length > 0 ? values.join('\n') : 'unknown'
}

function contextOccupancy(run: FactoryRunView): string {
  const values = unique((run.attempts ?? []).map((attempt) => {
    const usage = attempt.usage
    if (!usage?.usageEstimated) return null
    const window = usage.contextWindow
    return `${displayText(attempt.agent, 'agent')}: est. ${usage.totalTokens ?? 'unknown'}/${window ?? 'unknown'}`
  }))
  return values.length > 0 ? values.join('\n') : '—'
}

// A provider that reports no billing has no measured cost; rendering the zero it
// sums to would present unavailable as free.
function spend(run: FactoryRunView): string {
  const attempts = run.attempts ?? []
  const billed = attempts.filter((attempt) => attempt.usage && !attempt.usage.usageEstimated)
  const unbilled = attempts.filter((attempt) => attempt.usage?.usageEstimated)
  if (unbilled.length > 0 && billed.length === 0) return 'unavailable'
  if (unbilled.length > 0) return `${formatEstimatedSpend(run.totalCost)} · partly unavailable`
  return formatEstimatedSpend(run.totalCost)
}

export function FactoryRunMetadata({ run }: { run: FactoryRunView }): JSX.Element {
  return (
    <SectionCard title="Run metadata">
      {run.request !== null && run.request.trim() !== '' ? (
        <div className="mb-3"><CollapsibleText eyebrow={`${displayText(run.adwName, 'run')} · ${run.adwId}`} label="Request" text={run.request} /></div>
      ) : null}
      <KvPanel rows={[
        { label: 'repo', value: displayText(run.repo) },
        { label: 'adw id', value: displayText(run.adwId) },
        { label: 'adw name', value: displayText(run.adwName) },
        { label: 'preset', value: displayText(run.preset) },
        { label: 'engineer', value: displayText(run.engineer) },
        { label: 'status', value: displayStatus(run.status) },
        { label: 'host', value: hostsForAttempts(run.attempts ?? []) },
        { label: 'accounts', value: accountsForAttempts(run) },
        { label: 'declared seats', value: seatDeclarations(run) },
        { label: 'session identity', value: sessionIdentity(run) },
        { label: 'provider health', value: providerHealth(run) },
        { label: 'started', value: formatAbsoluteTimestamp(run.startedAt) },
        { label: 'ended', value: formatAbsoluteTimestamp(run.endedAt) },
        { label: run.endedAt ? 'duration' : 'elapsed', value: formatElapsed(run.startedAt, run.endedAt) },
        { label: 'tokens', value: formatTokenCount(run.totalTokens) },
        { label: 'context occupancy', value: contextOccupancy(run) },
        { label: 'spend', value: spend(run) },
      ]} />
    </SectionCard>
  )
}
