/*
 * Copyright 2025 coze-dev Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
import { uniqBy } from 'lodash-es';
import dayjs from 'dayjs';
import {
  type Span,
  type Int64,
  type TraceFrontendSpan,
} from '@coze-arch/bot-api/workflow_api';

import { type GotoParams } from './types';

export const sortSpans = (spans: TraceFrontendSpan[]) =>
  uniqBy(spans, span => span.span_id).sort((a, b) => {
    const startA = a.start_time ? Number(a.start_time) : Infinity;
    const startB = b.start_time ? Number(b.start_time) : Infinity;
    return startA - startB;
  });

export const getTimeFromSpan = (span: Span) =>
  span.start_time ? dayjs(span.start_time).format('YYYY-MM-DD HH:mm:ss') : '-';

export const isTriggerFromSpan = (span: Span) =>
  span.tags?.find(t => t.key === 'is_trigger');

export const getStrFromSpan = (span: Span, key: string): string => {
  const { tags } = span;
  if (!Array.isArray(tags) || !tags.length) {
    return '';
  }
  const target = tags.find(t => t.key === key);
  return target?.value?.v_str || '';
};
export const getLongFromSpan = (span: Span, key: string): Int64 | undefined => {
  const { tags } = span;
  if (!Array.isArray(tags) || !tags.length) {
    return '';
  }
  const target = tags.find(t => t.key === key);
  return target?.value?.v_long;
};

export const getTokensFromSpan = (span: Span) =>
  getLongFromSpan(span, 'tokens');

const DECIMAL = 60;
const UNIT_MILLISECOND = 1000;
const UNIT_SECOND = DECIMAL * UNIT_MILLISECOND;
const UNIT_MINUTES = DECIMAL * UNIT_SECOND;
const UNIT_HOUR = DECIMAL * UNIT_MINUTES;

export function formatDuration(time: number) {
  if (time < UNIT_MILLISECOND) {
    return `${time}ms`;
  } else if (time < UNIT_SECOND) {
    return `${(time / UNIT_MILLISECOND).toFixed(2)}s`;
  } else if (time < UNIT_MINUTES) {
    return `${(time / UNIT_SECOND).toFixed(2)}min`;
  } else if (time < UNIT_HOUR) {
    return `${(time / UNIT_MINUTES).toFixed(2)}h`;
  } else {
    return `${(time / UNIT_HOUR).toFixed(2)}d`;
  }
}

export const getGotoNodeParams = (span: Span): GotoParams => {
  const workflowId = getStrFromSpan(span, 'workflow_id');
  const nodeId = getStrFromSpan(span, 'workflow_node_id');
  const executeId = getStrFromSpan(span, 'execute_id');
  const subExecuteId = getStrFromSpan(span, 'sub_execute_id');

  return {
    workflowId,
    nodeId,
    executeId,
    subExecuteId,
  };
};
