import { useMemo, useState } from 'react'
import { AlertTriangle, MessageCircle, StepForward, Wrench } from 'lucide-react'

import type { AuditErrorEvent, AuditMessageEvent, AuditStepEvent, AuditToolCallEvent } from '../../types/agentAudit'
import { MessageContent } from '../agentChat/MessageContent'
import { EventHeader } from './EventHeader'
import { AuditJsonValue } from './AuditJsonValue'
import { IconCircle } from './eventPrimitives'

function previewValue(value: unknown, maxLength = 160): string | null {
  if (value === null || value === undefined || value === '') return null
  const text =
    typeof value === 'string'
      ? value
      : (() => {
          try {
            return JSON.stringify(value)
          } catch (_err) {
            return String(value)
          }
        })()
  return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text
}

export function ToolCallRow({
  tool,
  collapsed,
  onToggle,
}: {
  tool: AuditToolCallEvent
  collapsed?: boolean
  onToggle?: () => void
}) {
  const [expanded, setExpanded] = useState(false)
  const isControlled = collapsed !== undefined
  const isExpanded = isControlled ? !collapsed : expanded
  const toggle = () => {
    if (isControlled) {
      onToggle?.()
    } else {
      setExpanded((prev) => !prev)
    }
  }
  const resultPreview = useMemo(() => {
    return previewValue(tool.result)
  }, [tool.result])
  const durationLabel = useMemo(() => {
    if (tool.execution_duration_ms === null || tool.execution_duration_ms === undefined) return null
    return `${(tool.execution_duration_ms / 1000).toFixed(2)}s`
  }, [tool.execution_duration_ms])

  return (
    <div className="rounded-lg border border-slate-200/80 bg-white px-3 py-2 shadow-[0_1px_2px_rgba(15,23,42,0.06)]">
      <EventHeader
        left={
          <>
            <IconCircle icon={Wrench} bgClass="bg-indigo-50" textClass="text-indigo-700" />
            <div>
              <div className="text-sm font-semibold text-slate-900">{tool.tool_name || 'Tool call'}</div>
              <div className="text-xs text-slate-600">{tool.timestamp ? new Date(tool.timestamp).toLocaleString() : '—'}</div>
            </div>
          </>
        }
        right={
          durationLabel || resultPreview ? (
            <div className="flex items-center gap-2">
              {durationLabel ? (
                <span className="rounded-full bg-indigo-100 px-2 py-1 text-[11px] font-medium text-indigo-800">
                  {durationLabel}
                </span>
              ) : null}
              {resultPreview ? <span className="rounded-full bg-indigo-50 px-2 py-1 text-[11px] font-medium text-indigo-700">Tool</span> : null}
            </div>
          ) : null
        }
        collapsed={!isExpanded}
        onToggle={toggle}
      />
      {!isExpanded && resultPreview ? (
        <div className="mt-2 text-sm text-slate-700">{resultPreview}</div>
      ) : null}
      {isExpanded && tool.parameters !== null && tool.parameters !== undefined ? (
        <div className="mt-2 space-y-1">
          <div className="text-[11px] font-semibold uppercase tracking-wide text-slate-600">Parameters</div>
          <AuditJsonValue value={tool.parameters} />
        </div>
      ) : null}
      {isExpanded && tool.result !== null && tool.result !== undefined ? (
        <div className="mt-2 space-y-1">
          <div className="text-[11px] font-semibold uppercase tracking-wide text-slate-600">Result</div>
          <AuditJsonValue value={tool.result} />
        </div>
      ) : null}
    </div>
  )
}

export function MessageRow({
  message,
  collapsed = false,
  onToggle,
}: {
  message: AuditMessageEvent
  collapsed?: boolean
  onToggle?: () => void
}) {
  const htmlBody = message.body_html && message.body_html.trim().length > 0 ? message.body_html : null
  const textBody = message.body_text || (htmlBody ? null : message.body_html)
  const hasBody = Boolean(htmlBody || (textBody && textBody.trim().length > 0))
  const attachments = message.attachments || []
  const selfAgentName = message.self_agent_name?.trim() || 'Agent'
  const peerAgentName = message.peer_agent?.name?.trim() || 'Linked agent'
  const [from, to] = message.peer_agent
    ? [selfAgentName, peerAgentName]
    : ['Agent', 'User']
  const directionLabel = message.is_outbound ? `${from} → ${to}` : `${to} → ${from}`

  return (
    <div className="rounded-lg border border-slate-200/80 bg-white px-3 py-2 shadow-[0_1px_2px_rgba(15,23,42,0.06)]">
      <EventHeader
        left={
          <>
            <IconCircle icon={MessageCircle} bgClass="bg-emerald-50" textClass="text-emerald-700" />
            <div>
              <div className="text-sm font-semibold text-slate-900">
                {directionLabel}{' '}
                <span className="text-xs font-normal text-slate-500">({message.channel || 'web'})</span>
              </div>
              <div className="text-xs text-slate-600">{message.timestamp ? new Date(message.timestamp).toLocaleString() : '—'}</div>
            </div>
          </>
        }
        right={<span className="rounded-full bg-emerald-50 px-2 py-1 text-[11px] font-medium text-emerald-700">Message</span>}
        collapsed={collapsed}
        onToggle={onToggle}
      />
      {!collapsed ? (
        <>
          {hasBody ? (
            <div className="mt-2 prose prose-sm max-w-none text-slate-800">
              <MessageContent bodyHtml={htmlBody} bodyText={textBody} showEmptyState={false} />
            </div>
          ) : null}
          {attachments.length > 0 ? (
            <div className="mt-3 flex flex-wrap gap-2">
              {attachments.map((attachment) => {
                const href = attachment.download_url || attachment.url
                const label = attachment.filespace_path || attachment.filename
                return (
                  <a
                    key={attachment.id}
                    href={href}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex items-center gap-2 rounded-full border border-indigo-200 bg-indigo-50 px-3 py-1 text-xs font-semibold text-indigo-700 transition hover:bg-indigo-100"
                    title={attachment.filespace_path || attachment.filename}
                  >
                    <span className="max-w-[240px] truncate">{label}</span>
                    {attachment.file_size_label ? <span className="text-indigo-500">{attachment.file_size_label}</span> : null}
                  </a>
                )
              })}
            </div>
          ) : null}
        </>
      ) : null}
    </div>
  )
}

export function StepRow({
  step,
  collapsed = false,
  onToggle,
}: {
  step: AuditStepEvent
  collapsed?: boolean
  onToggle?: () => void
}) {
  return (
    <div className="rounded-lg border border-slate-200/80 bg-white px-3 py-2 shadow-[0_1px_2px_rgba(15,23,42,0.06)]">
      <EventHeader
        left={
          <>
            <IconCircle icon={StepForward} bgClass="bg-slate-100" textClass="text-slate-700" />
            <div>
              <div className="text-sm font-semibold text-slate-900">Step</div>
              <div className="text-xs text-slate-600">{step.timestamp ? new Date(step.timestamp).toLocaleString() : '—'}</div>
            </div>
          </>
        }
        right={
          step.is_system ? (
            <span className="rounded-full bg-amber-50 px-2 py-1 text-[11px] font-semibold text-amber-700">
              {step.system_code || 'System'}
            </span>
          ) : (
            <span className="rounded-full bg-slate-100 px-2 py-1 text-[11px] font-semibold text-slate-700">Step</span>
          )
        }
        collapsed={collapsed}
        onToggle={onToggle}
      />
      {!collapsed ? (
        <>
          {step.description ? <div className="mt-2 whitespace-pre-wrap break-words text-sm text-slate-800">{step.description}</div> : null}
          {step.is_system && step.system_notes ? (
            <div className="mt-2 rounded-md bg-slate-50 px-2 py-1 text-[12px] text-slate-700">{step.system_notes}</div>
          ) : null}
        </>
      ) : null}
    </div>
  )
}

export function ErrorRow({
  error,
  collapsed = false,
  onToggle,
}: {
  error: AuditErrorEvent
  collapsed?: boolean
  onToggle?: () => void
}) {
  const hasContext = error.context && Object.keys(error.context).length > 0
  const categoryLabel = (error.category || 'OTHER').replaceAll('_', ' ')

  return (
    <div className="rounded-lg border border-rose-200/90 bg-white px-3 py-2 shadow-[0_1px_2px_rgba(15,23,42,0.06)]">
      <EventHeader
        left={
          <>
            <IconCircle icon={AlertTriangle} bgClass="bg-rose-50" textClass="text-rose-700" />
            <div>
              <div className="text-sm font-semibold text-slate-900">{categoryLabel}</div>
              <div className="text-xs text-slate-600">{error.timestamp ? new Date(error.timestamp).toLocaleString() : '—'}</div>
            </div>
          </>
        }
        right={<span className="rounded-full bg-rose-50 px-2 py-1 text-[11px] font-semibold text-rose-700">{error.level || 'ERROR'}</span>}
        collapsed={collapsed}
        onToggle={onToggle}
      />
      {!collapsed ? (
        <div className="mt-2 space-y-2">
          <div className="flex flex-wrap gap-2">
            {error.source ? <span className="rounded-full bg-rose-50 px-2 py-1 text-[11px] font-medium text-rose-700">{error.source}</span> : null}
            {error.exception_class ? <span className="rounded-full bg-rose-50 px-2 py-1 text-[11px] font-medium text-rose-700">{error.exception_class}</span> : null}
            {error.completion_id ? <span className="rounded-full bg-indigo-50 px-2 py-1 text-[11px] font-medium text-indigo-700">Completion {error.completion_id}</span> : null}
          </div>
          {error.message ? <div className="whitespace-pre-wrap break-words text-sm text-slate-900">{error.message}</div> : null}
          {hasContext ? (
            <div className="space-y-1">
              <div className="text-[11px] font-semibold uppercase tracking-wide text-slate-600">Context</div>
              <AuditJsonValue value={error.context} />
            </div>
          ) : null}
          {error.traceback ? (
            <details className="rounded-md border border-rose-100 bg-rose-50/60 px-3 py-2">
              <summary className="cursor-pointer text-xs font-semibold text-rose-700">Traceback</summary>
              <pre className="mt-2 max-h-72 overflow-auto whitespace-pre-wrap break-words text-[12px] text-slate-900">{error.traceback}</pre>
            </details>
          ) : null}
        </div>
      ) : null}
    </div>
  )
}
