import { CheckCircleFilled, CloseCircleFilled, LoadingOutlined } from "@ant-design/icons";
import { Collapse, Flex, Typography } from "antd";

import type { PartProps } from "./types";

interface ToolPartData {
  errorText?: string;
  input?: unknown;
  output?: unknown;
  toolCallId?: string;
  toolMetadata?: Record<string, unknown>;
  toolName?: string;
  type?: string;
}

function getToolState(part: ToolPartData) {
  if ("errorText" in part && part.errorText) return "output-error" as const;
  if ("output" in part) return "output-available" as const;
  if ("input" in part) return "input-available" as const;
  return "input-streaming" as const;
}

const FORMAT_JSON = (v: unknown) => JSON.stringify(v, null, 2);

export function ToolPart({ part }: PartProps) {
  const toolPart = part as unknown as ToolPartData;
  const state = getToolState(toolPart);
  const rawToolName = toolPart.toolName ?? (toolPart.type ?? "unknown").replace(/^tool-/, "");
  const toolName =
    typeof toolPart.toolMetadata?.["displayName"] === "string" ? toolPart.toolMetadata["displayName"] : rawToolName;

  const isStreaming = state === "input-streaming" || state === "input-available";

  if (state === "output-error") {
    return (
      <Collapse
        ghost
        items={[
          {
            children: <Typography.Text type="danger">{toolPart.errorText}</Typography.Text>,
            key: toolPart.toolCallId ?? toolName,
            label: (
              <Flex align="center" component="span" gap={4}>
                <CloseCircleFilled className="icon-error" />
                <Typography.Text type="danger">{toolName} 失败</Typography.Text>
              </Flex>
            ),
          },
        ]}
        size="small"
      />
    );
  }

  return (
    <Collapse
      defaultActiveKey={isStreaming ? [toolPart.toolCallId ?? toolName] : undefined}
      ghost
      items={[
        {
          children: (
            <Flex gap={4} vertical>
              {toolPart.input != null && (
                <>
                  <Typography.Text type="secondary">参数：</Typography.Text>
                  <pre className="tool-result-pre">{FORMAT_JSON(toolPart.input)}</pre>
                </>
              )}
              {"output" in toolPart && toolPart.output != null && (
                <>
                  <Typography.Text type="secondary">结果：</Typography.Text>
                  <pre className="tool-result-pre">{FORMAT_JSON(toolPart.output)}</pre>
                </>
              )}
              {!toolPart.input && !("output" in toolPart) && (
                <Typography.Text type="secondary">生成中...</Typography.Text>
              )}
            </Flex>
          ),
          key: toolPart.toolCallId ?? toolName,
          label: isStreaming ? (
            <Flex align="center" component="span" gap={4}>
              <LoadingOutlined className="icon-primary" />
              <Typography.Text type="secondary">
                {state === "input-streaming" ? "生成参数" : `调用 ${toolName}`}
              </Typography.Text>
            </Flex>
          ) : (
            <Flex align="center" component="span" gap={4}>
              <CheckCircleFilled className="icon-success" />
              <Typography.Text type="secondary">{toolName}</Typography.Text>
            </Flex>
          ),
        },
      ]}
      size="small"
    />
  );
}
