<script setup lang="ts">
import type {ChatTimelineToolApprovalPayload, ChatTimelineToolItem,} from './types';

import {IconifyIcon} from '@easyflow/icons';

import {computed, ref} from 'vue';

const props = defineProps<{
  item: ChatTimelineToolItem;
  loading?: boolean;
}>();

const emit = defineEmits<{
  approve: [payload: ChatTimelineToolApprovalPayload];
  reject: [payload: ChatTimelineToolApprovalPayload];
}>();

const expanded = ref(false);

const isApprovalMode = computed(() => props.item.mode === 'approval');
const canApprove = computed(
  () => isApprovalMode.value && props.item.status === 'pending_approval',
);
const hasDetails = computed(() => Boolean(props.item.input));

const statusText = computed(() => {
  switch (props.item.status) {
    case 'approving': {
      return '确认中';
    }
    case 'error': {
      return '失败';
    }
    case 'pending_approval': {
      return '待确认';
    }
    case 'rejected': {
      return '已拒绝';
    }
    case 'success': {
      return '已完成';
    }
    default: {
      return '调用中';
    }
  }
});

const modeText = computed(() =>
  isApprovalMode.value ? '需要确认后执行' : '自动执行',
);

function formatPayload(value: unknown) {
  if (value === null || value === undefined || value === '') {
    return '';
  }
  if (typeof value === 'string') {
    return value;
  }
  try {
    return JSON.stringify(value, null, 2);
  } catch {
    return String(value);
  }
}

function toggleExpanded() {
  if (!hasDetails.value) {
    return;
  }
  expanded.value = !expanded.value;
}

function getApprovalPayload() {
  return props.item.approval;
}

function handleApprove() {
  const payload = getApprovalPayload();
  if (!payload || !canApprove.value) {
    return;
  }
  emit('approve', payload);
}

function handleReject() {
  const payload = getApprovalPayload();
  if (!payload || !canApprove.value) {
    return;
  }
  emit('reject', payload);
}
</script>

<template>
  <section
    class="chat-tool-card"
    :class="[`is-${item.status}`, { 'is-approval': isApprovalMode }]"
  >
    <button
      v-if="!isApprovalMode"
      type="button"
      class="chat-tool-card__compact"
      :class="{ 'is-clickable': hasDetails }"
      :disabled="!hasDetails"
      @click="toggleExpanded"
    >
      <span class="chat-tool-card__title">
        <IconifyIcon
          aria-hidden="true"
          class="chat-tool-card__tool-icon"
          icon="mdi:hammer"
        />
        <span class="chat-tool-card__name">{{ item.toolName }}</span>
      </span>
      <span class="chat-tool-card__meta">
        <span>{{ modeText }}</span>
        <span class="chat-tool-card__status">
          <span class="chat-tool-card__status-dot" aria-hidden="true"></span>
          <span>{{ statusText }}</span>
        </span>
      </span>
    </button>

    <template v-else>
      <div class="chat-tool-card__approval-head">
        <IconifyIcon
          aria-hidden="true"
          class="chat-tool-card__tool-icon"
          icon="mdi:hammer"
        />
        <div class="chat-tool-card__heading">
          <div class="chat-tool-card__name">{{ item.toolName }}</div>
          <div class="chat-tool-card__desc">{{ modeText }}</div>
        </div>
        <span class="chat-tool-card__status">
          <span class="chat-tool-card__status-dot" aria-hidden="true"></span>
          <span>{{ statusText }}</span>
        </span>
      </div>

      <pre v-if="item.input" class="chat-tool-card__payload">{{
        formatPayload(item.input)
      }}</pre>

      <div v-if="canApprove" class="chat-tool-card__actions">
        <button
          type="button"
          class="chat-tool-card__button"
          :disabled="loading"
          @click="handleReject"
        >
          拒绝
        </button>
        <button
          type="button"
          class="chat-tool-card__button is-primary"
          :disabled="loading"
          @click="handleApprove"
        >
          批准
        </button>
      </div>

      <div v-if="item.rejectReason" class="chat-tool-card__result-note">
        {{ item.rejectReason }}
      </div>
    </template>

    <div
      v-if="!isApprovalMode && expanded && hasDetails"
      class="chat-tool-card__body"
    >
      <pre v-if="item.input" class="chat-tool-card__payload">{{
        formatPayload(item.input)
      }}</pre>
    </div>
  </section>
</template>

<style scoped>
.chat-tool-card {
  max-width: min(78%, 680px);
  overflow: hidden;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
}

.chat-tool-card.is-approval {
  padding: 16px;
  background: var(--el-color-primary-light-9);
  border-color: var(--el-color-primary-light-7);
}

.chat-tool-card__compact,
.chat-tool-card__approval-head {
  display: flex;
  gap: 8px;
  align-items: center;
  width: 100%;
  min-width: 0;
}

.chat-tool-card__compact {
  justify-content: space-between;
  padding: 10px 12px;
  color: inherit;
  text-align: left;
  background: transparent;
  border: 0;
}

.chat-tool-card__compact.is-clickable {
  cursor: pointer;
}

.chat-tool-card__compact.is-clickable:hover {
  background: var(--el-fill-color-lighter);
}

.chat-tool-card__compact:focus-visible,
.chat-tool-card__button:focus-visible {
  outline: 2px solid var(--el-color-primary-light-5);
  outline-offset: 2px;
}

.chat-tool-card__approval-head {
  align-items: flex-start;
}

.chat-tool-card__title,
.chat-tool-card__meta,
.chat-tool-card__status {
  display: inline-flex;
  align-items: center;
  min-width: 0;
}

.chat-tool-card__title {
  gap: 6px;
}

.chat-tool-card__heading {
  flex: 1 1 auto;
  min-width: 0;
}

.chat-tool-card__name {
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 14px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  white-space: nowrap;
}

.chat-tool-card__desc {
  margin-top: 2px;
  font-size: 12px;
  line-height: 18px;
  color: var(--el-text-color-secondary);
}

.chat-tool-card__tool-icon {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  margin-top: 2px;
  color: var(--el-text-color-secondary);
}

.chat-tool-card.is-approval .chat-tool-card__tool-icon,
.chat-tool-card.is-pending_approval .chat-tool-card__tool-icon,
.chat-tool-card.is-approving .chat-tool-card__tool-icon,
.chat-tool-card.is-running .chat-tool-card__tool-icon {
  color: var(--el-color-primary);
}

.chat-tool-card__meta {
  flex: 0 0 auto;
  gap: 8px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.chat-tool-card__status {
  gap: 4px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.chat-tool-card__status-dot {
  width: 6px;
  height: 6px;
  background: currentColor;
  border-radius: 50%;
}

.chat-tool-card.is-approving .chat-tool-card__status,
.chat-tool-card.is-pending_approval .chat-tool-card__status,
.chat-tool-card.is-running .chat-tool-card__status {
  color: var(--el-color-primary);
}

.chat-tool-card.is-success .chat-tool-card__status {
  color: var(--el-color-success);
}

.chat-tool-card.is-error .chat-tool-card__status,
.chat-tool-card.is-rejected .chat-tool-card__status {
  color: var(--el-color-danger);
}

.chat-tool-card__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 12px 12px;
}

.chat-tool-card__payload {
  max-height: 180px;
  padding: 10px;
  margin: 12px 0 0;
  overflow: auto;
  font-size: 12px;
  line-height: 18px;
  color: var(--el-text-color-secondary);
  white-space: pre-wrap;
  background: var(--el-bg-color);
  border-radius: 8px;
}

.chat-tool-card__body .chat-tool-card__payload {
  margin: 0;
  background: var(--el-fill-color-light);
}

.chat-tool-card__actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 12px;
}

.chat-tool-card__button {
  min-width: 64px;
  height: 32px;
  padding: 0 12px;
  font-size: 13px;
  color: var(--el-text-color-primary);
  cursor: pointer;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color);
  border-radius: 6px;
}

.chat-tool-card__button:hover {
  border-color: var(--el-color-primary-light-5);
}

.chat-tool-card__button:disabled {
  cursor: not-allowed;
  opacity: 0.62;
}

.chat-tool-card__button.is-primary {
  color: var(--el-color-white);
  background: var(--el-color-primary);
  border-color: var(--el-color-primary);
}

.chat-tool-card__result-note {
  margin-top: 12px;
  font-size: 12px;
  line-height: 18px;
  color: var(--el-color-danger);
}
</style>
