import type { CharacterState } from "$lib/types/states";
import type { ClaudeStreamMessage, ToolUseContentBlock } from "$lib/types/messages";

const SEARCH_TOOLS = ["Read", "Glob", "Grep", "WebSearch", "WebFetch"];
const CODING_TOOLS = ["Edit", "Write", "NotebookEdit"];

function getToolCategory(toolName: string): CharacterState {
  if (SEARCH_TOOLS.includes(toolName)) {
    return "searching";
  }

  if (CODING_TOOLS.includes(toolName)) {
    return "coding";
  }

  if (toolName.startsWith("mcp__")) {
    return "mcp";
  }

  if (toolName === "Task") {
    return "thinking";
  }

  return "typing";
}

export function mapMessageToState(message: ClaudeStreamMessage): CharacterState | null {
  switch (message.type) {
    case "system":
      if (message.subtype === "init") {
        return "idle";
      }
      return null;

    case "assistant": {
      const toolUses = message.message.content.filter(
        (block): block is ToolUseContentBlock => block.type === "tool_use"
      );

      if (toolUses.length > 0) {
        const lastTool = toolUses[toolUses.length - 1];
        return getToolCategory(lastTool.name);
      }

      const hasText = message.message.content.some((block) => block.type === "text");
      if (hasText) {
        return "typing";
      }

      const hasThinking = message.message.content.some((block) => block.type === "thinking");
      if (hasThinking) {
        return "thinking";
      }

      return null;
    }

    case "stream_event": {
      const event = message.event;

      if (event.type === "content_block_start") {
        if (event.content_block?.type === "thinking") {
          return "thinking";
        }
        if (event.content_block?.type === "text") {
          return "typing";
        }
        if (event.content_block?.type === "tool_use") {
          const toolBlock = event.content_block as ToolUseContentBlock;
          return getToolCategory(toolBlock.name);
        }
      }

      if (event.type === "content_block_delta") {
        if (event.delta?.type === "thinking_delta") {
          return "thinking";
        }
        if (event.delta?.type === "text_delta") {
          return "typing";
        }
      }

      return null;
    }

    case "result":
      if (message.subtype === "success") {
        return "success";
      }
      if (message.subtype.startsWith("error")) {
        return "error";
      }
      return null;

    case "user":
      return null;

    default:
      return null;
  }
}

export function extractTextFromMessage(message: ClaudeStreamMessage): string | null {
  if (message.type === "assistant") {
    const textBlocks = message.message.content
      .filter((block) => block.type === "text")
      .map((block) => (block as { type: "text"; text: string }).text);

    return textBlocks.length > 0 ? textBlocks.join("\n") : null;
  }

  if (message.type === "stream_event" && message.event.delta?.text) {
    return message.event.delta.text;
  }

  if (message.type === "result" && message.result) {
    return message.result;
  }

  return null;
}

export function extractToolInfo(
  message: ClaudeStreamMessage
): { name: string; input: Record<string, unknown> }[] {
  if (message.type !== "assistant") {
    return [];
  }

  return message.message.content
    .filter((block): block is ToolUseContentBlock => block.type === "tool_use")
    .map((block) => ({
      name: block.name,
      input: block.input,
    }));
}
