/**
 * 事件渲染属性生成器
 *
 * 完整复刻 remix next-agent 的 getEventRenderProps 逻辑：
 *   event-types.ts → event-transformers.ts → event-processors.ts → event-handlers.ts
 *
 * 用于在 useEventProcessor 中将 ApiEvent 转换为 ExtendedEvent 时填充 renderProps。
 */
import type {
  ApiEvent,
  MessageItemProps,
  ActionInfo,
  McpContent,
  PlanConfig,
  TaskTodoConfig,
  Operation,
  UserInteraction,
  Attachment,
  ImageAttachment,
  BaseEvent,
  MessageContent,
} from '../types'

// ─────────────────────────────────────────────
// 事件类型 / 动作类型常量（对应 next-agent-chat.type.ts）
// ─────────────────────────────────────────────

const ET = {
  UserInput: 'user_input',
  Text: 'text',
  ToolCall: 'tool_call',
  TaskUpdate: 'task_update',
  TaskEnd: 'task_end',
  UserInteraction: 'user_interaction',
  MessageAskUser: 'message_ask_user',
  AskUserReply: 'ask_user_reply',
  StepSummary: 'step_summary',
  Summary: 'summary',
} as const

const EA = {
  TextJson: 'text_json',
  Mcp: 'mcp',
  McpTool: 'mcp_tool',
  BrowserUseTakeover: 'browser_use_takeover',
  SlideInit: 'slide_init',
  MessageNotifyUser: 'message_notify_user',
  StepSummary: 'step_summary',
  Summary: 'summary',
  AgentScheduleTask: 'agent_schedule_task',
} as const

const ES = {
  RUNNING: 'running',
  SUCCESS: 'success',
  FAILED: 'failed',
} as const

/** task_update 等无 content 的事件类型集合 */
const CONTENTLESS_EVENTS = new Set<string>([ET.TaskUpdate])

// ─────────────────────────────────────────────
// 事件类型判断（对应 event-types.ts）
// ─────────────────────────────────────────────

function isUserInputEvent(e: ApiEvent) {
  return e.event_type === ET.UserInput
}

function isToolCallEvent(e: ApiEvent) {
  return e.event_type === ET.ToolCall
}

function isPlanEvent(e: ApiEvent) {
  return e.event_type === ET.Text && e.content?.action_type === EA.TextJson
}

function isMcpEvent(e: ApiEvent) {
  return (
    isToolCallEvent(e) &&
    (e.content?.action_type === EA.Mcp || e.content?.action_type === EA.McpTool)
  )
}

function isBrowserUseTakeoverEvent(e: ApiEvent) {
  return e.content?.action_type === EA.BrowserUseTakeover
}

function isSlideOutlineEvent(e: ApiEvent) {
  return isToolCallEvent(e) && e.content?.action_type === EA.SlideInit
}

function isAgentScheduleTaskEvent(e: ApiEvent) {
  return e.content?.action_type === EA.AgentScheduleTask
}

function isMessageNotifyUserEvent(e: ApiEvent) {
  return isToolCallEvent(e) && e.content?.action_type === EA.MessageNotifyUser
}

function isStepSummaryEvent(e: ApiEvent) {
  return (
    e.event_type === ET.StepSummary && e.content?.action_type === EA.StepSummary
  )
}

function isStepSummaryLegacy(e: ApiEvent) {
  return (
    e.event_type === ET.Summary && e.content?.action_type === EA.Summary
  )
}

/** 任务结束带文件（text 事件 + attachment_files） */
function isTaskEndWithFiles(e: ApiEvent) {
  return (
    e.event_type === ET.Text && !!e.content?.attachment_files?.length
  )
}

function isImageFile(fileType?: string) {
  return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'].includes(
    (fileType || '').toLowerCase(),
  )
}

// ─────────────────────────────────────────────
// 数据转换工具（对应 event-transformers.ts）
// ─────────────────────────────────────────────

/** 规范化动作类型：优先取 tool_name，fallback action_type */
function normalizeActionType(e: ApiEvent): string {
  return (e.content?.tool_name || e.content?.action_type || '') as string
}

/** 创建 base 属性（对应 createBaseEventProps） */
function createBaseProps(e: ApiEvent): { base: BaseEvent } {
  const normalizedTimestamp =
    typeof e.timestamp === 'number'
      ? e.timestamp
      : typeof e.content?.timestamp === 'number'
        ? e.content.timestamp
        : undefined

  return {
    base: {
      event_id: e.event_id,
      event_type: e.event_type,
      event_status: e.event_status,
      stream: e.stream,
      plan_step_state: e.plan_step_state,
      action_type: normalizeActionType(e),
      timestamp: normalizedTimestamp,
      metadata: {
        ...(e.metadata as Record<string, unknown>),
        ...(e.content?.metadata as Record<string, unknown>),
        isUserInput: isUserInputEvent(e),
        isScheduleTask: isAgentScheduleTaskEvent(e),
      },
    },
  }
}

/** 创建 action 属性（对应 createActionProps） */
function createAction(e: ApiEvent): ActionInfo {
  return {
    name: (e.content?.action_name as string) || '',
    arguments: e.content?.arguments as string[] | undefined,
    action_type: normalizeActionType(e),
    block: isPlanEvent(e) || isSlideOutlineEvent(e),
    tool_input: e.content?.tool_input,
    tool_output: e.content?.tool_output,
  }
}

// ─────────────────────────────────────────────
// 附件处理（对应 event-processors.ts processEventAttachments）
// ─────────────────────────────────────────────

function processAttachmentFiles(
  files: NonNullable<ApiEvent['content']>['attachment_files'],
): Attachment[] {
  if (!files?.length) return []
  return files
    .filter(f => f.file_name && f.file_type && f.path)
    .map(f => ({
      file_name: f.file_name!,
      file_type: f.file_type!,
      file_url: f.path!,
    }))
}

function processEventAttachments(e: ApiEvent): [Attachment[], ImageAttachment[]] {
  const attachments: Attachment[] = []
  const imageAttachments: ImageAttachment[] = []
  const toolOutput = e.content?.tool_output

  // tool_output 中的单文件附件
  if (
    toolOutput &&
    typeof toolOutput === 'object' &&
    !Array.isArray(toolOutput)
  ) {
    const to = toolOutput as Record<string, unknown>
    if (to.path && to.file_type && to.file_name) {
      attachments.push({
        file_name: to.file_name as string,
        file_type: to.file_type as string,
        file_url: to.path as string,
      })
    }
  }

  // user_input / message_notify_user / step_summary 的 attachment_files
  if (
    (isUserInputEvent(e) ||
      isMessageNotifyUserEvent(e) ||
      isStepSummaryEvent(e) ||
      isStepSummaryLegacy(e)) &&
    e.content?.attachment_files?.length
  ) {
    attachments.push(...processAttachmentFiles(e.content.attachment_files))
  }

  // 任务结束带文件（text + attachment_files）
  if (isTaskEndWithFiles(e) && e.content?.attachment_files?.length) {
    const all = processAttachmentFiles(e.content.attachment_files)

    const imageFiles = all.filter(a => isImageFile(a.file_type))
    imageAttachments.push(
      ...imageFiles.map(a => ({
        url: a.file_url,
        path: a.file_url,
        file_name: a.file_name,
      })),
    )
    const rest = all.filter(a => !isImageFile(a.file_type))
    if (rest.length > 0) attachments.push(...rest.slice(0, 3))
  }

  return [attachments, imageAttachments]
}

// ─────────────────────────────────────────────
// 通用事件属性（对应 event-processors.ts createCommonEventProps）
// ─────────────────────────────────────────────

function tryParseObject(str: string): Record<string, unknown> {
  try {
    const parsed = JSON.parse(str)
    if (typeof parsed === 'object' && parsed !== null) return parsed
  } catch {
    // ignore
  }
  return {}
}

function createCommonProps(e: ApiEvent): Partial<MessageItemProps> {
  const base = createBaseProps(e)
  const [attachments, imageAttachments] = processEventAttachments(e)

  // 计划事件（text + text_json）
  if (isPlanEvent(e)) {
    return {
      ...base,
      planConfig: {
        ...tryParseObject(
          typeof e.content?.content === 'string' ? e.content.content : '{}',
        ),
        fast_mode: e.content?.fast_mode,
      } as PlanConfig,
    }
  }

  const result: Partial<MessageItemProps> = { ...base }

  if (attachments.length > 0) result.attachment = attachments
  if (imageAttachments.length > 0) result.imageAttachment = imageAttachments

  // 文本内容
  if (
    !CONTENTLESS_EVENTS.has(e.event_type) &&
    e.content?.content &&
    typeof e.content.content === 'string'
  ) {
    result.content = {
      content: e.content.content,
      refer_content: e.content.refer_content,
    } as MessageContent
  }

  return result
}

// ─────────────────────────────────────────────
// 各事件类型处理器（对应 event-handlers.ts）
// ─────────────────────────────────────────────

function handleDefault(e: ApiEvent): MessageItemProps {
  return {
    action: createAction(e),
    ...createCommonProps(e),
  }
}

function handleToolCall(e: ApiEvent): MessageItemProps {
  // 规范化 action_type
  if (e.content) {
    (e.content as Record<string, unknown>).action_type = normalizeActionType(e)
  }

  const baseAction = { action: createAction(e) }

  // MCP 工具事件
  if (isMcpEvent(e)) {
    const meta = e.content?.metadata as Record<string, unknown> | undefined
    return {
      ...createBaseProps(e),
      ...baseAction,
      mcpContent: {
        metadata: {
          ...meta,
          name: (meta?.name || meta?.mcp_name) as string | undefined,
        },
        status:
          !(meta?.is_auto_executed) &&
          e.event_status !== ES.SUCCESS &&
          e.event_status !== ES.FAILED
            ? 'ready'
            : e.event_status,
        tool_call_id: e.content?.tool_call_id,
        action_type: e.content?.action_type,
        tool_input: e.content?.tool_input,
        tool_output: e.content?.tool_output,
      } as McpContent,
    }
  }

  // 浏览器接管事件
  if (isBrowserUseTakeoverEvent(e)) {
    return {
      ...createBaseProps(e),
      ...baseAction,
      content: { content: '' },
      operation: {
        operation_type: e.content?.action_type,
        content:
          typeof e.content?.content === 'string' ? e.content.content : '',
      } as Operation,
    }
  }

  return { ...baseAction, ...createCommonProps(e) }
}

function handleTaskUpdate(e: ApiEvent): MessageItemProps {
  const rawContent = e.content?.content
  const list = Array.isArray(rawContent)
    ? rawContent
    : rawContent &&
        typeof rawContent === 'object' &&
        Array.isArray((rawContent as { list?: unknown }).list)
      ? ((rawContent as { list: Record<string, unknown>[] }).list ?? [])
      : []

  return {
    action: createAction(e),
    ...createCommonProps(e),
    taskTodoConfig: {
      list,
    } as TaskTodoConfig,
  }
}

function handleUserInteraction(e: ApiEvent): MessageItemProps {
  if (e.content) {
    (e.content as Record<string, unknown>).action_type = normalizeActionType(e)
  }
  const interactionContent = (
    (e.content?.content as Record<string, unknown>) || {}
  )
  const { text, ...rest } = interactionContent
  return {
    action: createAction(e),
    ...createBaseProps(e),
    userInteraction: { content: text as string | undefined, ...rest } as UserInteraction,
  }
}

// ─────────────────────────────────────────────
// 主入口（对应 event-handlers.ts getEventRenderProps）
// ─────────────────────────────────────────────

export function getEventRenderProps(event: ApiEvent): MessageItemProps {
  switch (event.event_type) {
    case ET.UserInput:
    case ET.Text:
    case ET.MessageAskUser:
    case ET.AskUserReply:
      return handleDefault(event)

    case ET.ToolCall:
      return handleToolCall(event)

    case ET.TaskUpdate:
      return handleTaskUpdate(event)

    case ET.UserInteraction:
      return handleUserInteraction(event)

    default:
      return {
        action: {
          action_type: normalizeActionType(event),
          name: (event.content?.action_name as string) || '',
          block: isSlideOutlineEvent(event),
        },
        ...createCommonProps(event),
      }
  }
}
