import type {
  ChatArtifactAttachment,
  ChatTimelineItem,
  ChatTimelineMessageItem,
} from '@easyflow/common-ui';

import { ChatTimelineBuilder } from '@easyflow/common-ui';

const ARTIFACT_ID_PATTERN = /^[\w-]{1,64}$/;
const SHA256_PATTERN = /^[a-f\d]{64}$/i;

function asText(value: unknown) {
  return value === null || value === undefined ? '' : String(value);
}

function artifactStatus(value: unknown): ChatArtifactAttachment['status'] {
  const status = asText(value).trim().toUpperCase();
  if (!status || status === 'AVAILABLE') return 'available';
  if (status === 'EXPIRED' || status === 'DELETED') return 'expired';
  if (status === 'DELETE_FAILED') return 'delete_failed';
  return 'unavailable';
}

function safeFileName(value: unknown) {
  const withoutControlCharacters = [...asText(value)]
    .filter((character) => {
      const code = character.codePointAt(0) ?? 0;
      return code > 31 && code !== 127;
    })
    .join('');
  return (
    withoutControlCharacters.split(/[\\/]/).pop()?.trim().slice(0, 255) || ''
  );
}

/**
 * 将 Artifact 事件裁剪为前端允许展示的稳定字段。
 *
 * @param payload AG-UI 或历史记录中的 Artifact 载荷。
 * @returns 安全 Artifact；标识或文件名非法时不投影。
 */
export function normalizeArtifactPayload(
  payload: Record<string, unknown>,
): ChatArtifactAttachment | undefined {
  const artifactId = asText(payload.artifactId).trim();
  const fileName = safeFileName(payload.fileName);
  if (!ARTIFACT_ID_PATTERN.test(artifactId) || !fileName) {
    return undefined;
  }
  const status = artifactStatus(payload.status);
  const rawSize = Number(payload.size);
  const mimeType = asText(payload.mimeType).trim().slice(0, 128);
  const sha256 = asText(payload.sha256).trim();
  return {
    artifactId,
    downloadUrl:
      status === 'available'
        ? `/api/v1/agent/artifacts/${encodeURIComponent(artifactId)}/content`
        : undefined,
    fileName,
    mimeType: mimeType || undefined,
    sha256: SHA256_PATTERN.test(sha256) ? sha256.toLowerCase() : undefined,
    size: Number.isSafeInteger(rawSize) && rawSize >= 0 ? rawSize : undefined,
    status,
  };
}

/**
 * 使用共享 Builder 将安全 Artifact 投影到聊天时间线。
 *
 * @param items 当前时间线。
 * @param payload Artifact 公开载荷。
 * @param metadata 当前轮次元数据。
 */
export function projectArtifactPayload(
  items: ChatTimelineItem[],
  payload: Record<string, unknown>,
  metadata?: Partial<ChatTimelineMessageItem>,
) {
  const artifact = normalizeArtifactPayload(payload);
  if (artifact) {
    ChatTimelineBuilder.upsertArtifact(items, artifact, metadata);
  }
}
