<script setup lang="ts">
import type { NodeExecutionResult } from '../components/NodeResultCard.vue';

import { computed, inject, ref } from 'vue';

import { CheckCircle2, Loader2, Plus, XCircle } from '@vben/icons';

import { Handle, Position } from '@vue-flow/core';
import { ElTooltip } from 'element-plus';

import NodeResultCard from '../components/NodeResultCard.vue';

const props = defineProps<{
  // 新增：完整的执行结果（用于节点下方展示）
  executionResult?: NodeExecutionResult;
  executionStatus?: {
    elapsed_time?: number;
    error?: string;
    status: 'failed' | 'running' | 'success';
    tokens_used?: number;
  };
  icon?: any;
  inputs?: Array<{ id: string; label?: string }>;
  label?: string;
  nodeId?: string;
  nodeType?: string;
  outputs?: Array<{ id: string; label?: string }>;
  selected?: boolean;
}>();

const addButtonRef = ref<HTMLElement | null>(null);

// 从父组件注入的添加节点函数
const onNodeAddClick =
  inject<(nodeId: string, position: { x: number; y: number }) => void>(
    'onNodeAddClick',
  );

const handleClick = () => {
  const rect = addButtonRef.value?.getBoundingClientRect();
  if (rect && onNodeAddClick && props.nodeId) {
    onNodeAddClick(props.nodeId, { x: rect.right + 10, y: rect.top });
  }
};

// 节点类型配色 - 支持 dark 模式，使用 Tailwind dark: 前缀
const nodeColorConfig = computed(() => {
  const configs: Record<
    string,
    { headerBg: string; iconBg: string; iconColor: string }
  > = {
    // 流程控制
    start: {
      headerBg:
        'bg-gradient-to-r from-emerald-50 to-green-50 dark:from-emerald-950 dark:to-green-950',
      iconBg: 'bg-emerald-200 dark:bg-emerald-800',
      iconColor: 'text-emerald-600 dark:text-emerald-400',
    },
    end: {
      headerBg:
        'bg-gradient-to-r from-rose-50 to-red-50 dark:from-rose-950 dark:to-red-950',
      iconBg: 'bg-rose-200 dark:bg-rose-800',
      iconColor: 'text-rose-600 dark:text-rose-400',
    },
    condition: {
      headerBg:
        'bg-gradient-to-r from-amber-50 to-yellow-50 dark:from-amber-950 dark:to-yellow-950',
      iconBg: 'bg-amber-200 dark:bg-amber-800',
      iconColor: 'text-amber-600 dark:text-amber-400',
    },
    parallel: {
      headerBg:
        'bg-gradient-to-r from-cyan-50 to-sky-50 dark:from-cyan-950 dark:to-sky-950',
      iconBg: 'bg-cyan-200 dark:bg-cyan-800',
      iconColor: 'text-cyan-600 dark:text-cyan-400',
    },
    merge: {
      headerBg:
        'bg-gradient-to-r from-slate-50 to-gray-100 dark:from-slate-900 dark:to-gray-900',
      iconBg: 'bg-slate-300 dark:bg-slate-700',
      iconColor: 'text-slate-600 dark:text-slate-400',
    },

    // AI 相关
    llm: {
      headerBg:
        'bg-gradient-to-r from-violet-50 to-purple-50 dark:from-violet-950 dark:to-purple-950',
      iconBg: 'bg-violet-200 dark:bg-violet-800',
      iconColor: 'text-violet-600 dark:text-violet-400',
    },
    intent: {
      headerBg:
        'bg-gradient-to-r from-fuchsia-50 to-pink-50 dark:from-fuchsia-950 dark:to-pink-950',
      iconBg: 'bg-fuchsia-200 dark:bg-fuchsia-800',
      iconColor: 'text-fuchsia-600 dark:text-fuchsia-400',
    },

    // 代码和模板
    code: {
      headerBg:
        'bg-gradient-to-r from-orange-50 to-amber-50 dark:from-orange-950 dark:to-amber-950',
      iconBg: 'bg-orange-200 dark:bg-orange-800',
      iconColor: 'text-orange-600 dark:text-orange-400',
    },
    template: {
      headerBg:
        'bg-gradient-to-r from-teal-50 to-emerald-50 dark:from-teal-950 dark:to-emerald-950',
      iconBg: 'bg-teal-200 dark:bg-teal-800',
      iconColor: 'text-teal-600 dark:text-teal-400',
    },

    // HTTP
    http: {
      headerBg:
        'bg-gradient-to-r from-blue-50 to-indigo-50 dark:from-blue-950 dark:to-indigo-950',
      iconBg: 'bg-blue-200 dark:bg-blue-800',
      iconColor: 'text-blue-600 dark:text-blue-400',
    },

    // 数据库
    db_query: {
      headerBg:
        'bg-gradient-to-r from-indigo-50 to-blue-50 dark:from-indigo-950 dark:to-blue-950',
      iconBg: 'bg-indigo-200 dark:bg-indigo-800',
      iconColor: 'text-indigo-600 dark:text-indigo-400',
    },
    db_insert: {
      headerBg:
        'bg-gradient-to-r from-green-50 to-emerald-50 dark:from-green-950 dark:to-emerald-950',
      iconBg: 'bg-green-200 dark:bg-green-800',
      iconColor: 'text-green-600 dark:text-green-400',
    },
    db_update: {
      headerBg:
        'bg-gradient-to-r from-yellow-50 to-amber-50 dark:from-yellow-950 dark:to-amber-950',
      iconBg: 'bg-yellow-200 dark:bg-yellow-800',
      iconColor: 'text-yellow-600 dark:text-yellow-400',
    },
    db_delete: {
      headerBg:
        'bg-gradient-to-r from-red-50 to-rose-50 dark:from-red-950 dark:to-rose-950',
      iconBg: 'bg-red-200 dark:bg-red-800',
      iconColor: 'text-red-600 dark:text-red-400',
    },
    db_sql: {
      headerBg:
        'bg-gradient-to-r from-purple-50 to-violet-50 dark:from-purple-950 dark:to-violet-950',
      iconBg: 'bg-purple-200 dark:bg-purple-800',
      iconColor: 'text-purple-600 dark:text-purple-400',
    },

    // Text-to-SQL
    text_to_sql: {
      headerBg:
        'bg-gradient-to-r from-cyan-50 to-teal-50 dark:from-cyan-950 dark:to-teal-950',
      iconBg: 'bg-cyan-200 dark:bg-cyan-800',
      iconColor: 'text-cyan-600 dark:text-cyan-400',
    },

    // 对话流
    question: {
      headerBg:
        'bg-gradient-to-r from-sky-50 to-blue-50 dark:from-sky-950 dark:to-blue-950',
      iconBg: 'bg-sky-200 dark:bg-sky-800',
      iconColor: 'text-sky-600 dark:text-sky-400',
    },
    choice: {
      headerBg:
        'bg-gradient-to-r from-lime-50 to-green-50 dark:from-lime-950 dark:to-green-950',
      iconBg: 'bg-lime-200 dark:bg-lime-800',
      iconColor: 'text-lime-600 dark:text-lime-400',
    },
    message: {
      headerBg:
        'bg-gradient-to-r from-pink-50 to-rose-50 dark:from-pink-950 dark:to-rose-950',
      iconBg: 'bg-pink-200 dark:bg-pink-800',
      iconColor: 'text-pink-600 dark:text-pink-400',
    },
    confirm: {
      headerBg:
        'bg-gradient-to-r from-orange-50 to-red-50 dark:from-orange-950 dark:to-red-950',
      iconBg: 'bg-orange-200 dark:bg-orange-800',
      iconColor: 'text-orange-600 dark:text-orange-400',
    },

    // Snowflake
    snowflake_cortex_llm: {
      headerBg:
        'bg-gradient-to-r from-cyan-50 to-blue-50 dark:from-cyan-950 dark:to-blue-950',
      iconBg: 'bg-cyan-200 dark:bg-cyan-800',
      iconColor: 'text-cyan-600 dark:text-cyan-400',
    },
    snowflake_cortex_analyst: {
      headerBg:
        'bg-gradient-to-r from-blue-50 to-cyan-50 dark:from-blue-950 dark:to-cyan-950',
      iconBg: 'bg-blue-200 dark:bg-blue-800',
      iconColor: 'text-blue-600 dark:text-blue-400',
    },

    // 子流程
    subflow: {
      headerBg:
        'bg-gradient-to-r from-indigo-50 to-purple-50 dark:from-indigo-950 dark:to-purple-950',
      iconBg: 'bg-indigo-200 dark:bg-indigo-800',
      iconColor: 'text-indigo-600 dark:text-indigo-400',
    },

    // 知识库
    knowledge_retrieval: {
      headerBg:
        'bg-gradient-to-r from-teal-50 to-cyan-50 dark:from-teal-950 dark:to-cyan-950',
      iconBg: 'bg-teal-200 dark:bg-teal-800',
      iconColor: 'text-teal-600 dark:text-teal-400',
    },
  };

  return (
    configs[props.nodeType || ''] || {
      headerBg: 'bg-gradient-to-r from-card to-muted',
      iconBg: 'bg-card border border-border',
      iconColor: 'text-primary',
    }
  );
});
</script>

<template>
  <div class="flex flex-col">
    <!-- 节点主体 -->
    <div
      class="bg-card group relative w-[280px] max-w-[280px] rounded-xl border shadow-sm transition-all duration-200 hover:shadow-md"
      :class="[
        selected ? 'border-primary ring-primary ring-1' : '',
        executionStatus?.status === 'running'
          ? 'animate-pulse-border !border-blue-500 shadow-lg shadow-blue-500/20 ring-2 ring-blue-500/50'
          : '',
        executionStatus?.status === 'success'
          ? '!border-green-500 ring-1 ring-green-500'
          : '',
        executionStatus?.status === 'failed'
          ? '!border-red-500 ring-2 ring-red-500'
          : '',
        !selected && !executionStatus?.status ? 'border-border' : '',
      ]"
    >
      <!-- Status Badge (Absolute Top Right) -->
      <div
        v-if="executionStatus"
        class="absolute -top-3 right-4 z-20 flex items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] shadow-sm"
        :class="[
          executionStatus.status === 'running'
            ? 'border-blue-500/30 bg-blue-500/10 text-blue-600 dark:text-blue-400'
            : '',
          executionStatus.status === 'success'
            ? 'border-green-500/30 bg-green-500/10 text-green-600 dark:text-green-400'
            : '',
          executionStatus.status === 'failed'
            ? 'border-red-500/30 bg-red-500/10 text-red-600 dark:text-red-400'
            : '',
        ]"
      >
        <Loader2
          v-if="executionStatus.status === 'running'"
          class="size-3 animate-spin"
        />
        <CheckCircle2
          v-if="executionStatus.status === 'success'"
          class="size-3"
        />
        <ElTooltip
          v-if="executionStatus.status === 'failed' && executionStatus.error"
          :content="executionStatus.error"
          placement="top"
        >
          <XCircle class="size-3 cursor-help" />
        </ElTooltip>
        <XCircle
          v-else-if="executionStatus.status === 'failed'"
          class="size-3"
        />

        <span v-if="executionStatus.status === 'running'">Running...</span>
        <span v-else-if="executionStatus.elapsed_time !== undefined">{{ executionStatus.elapsed_time }}ms</span>
      </div>

      <!-- Header -->
      <div
        class="border-border/50 flex items-center gap-3 rounded-t-xl border-b px-4 py-3"
        :class="nodeColorConfig.headerBg"
      >
        <div
          class="flex size-8 shrink-0 items-center justify-center rounded-lg shadow-sm"
          :class="[nodeColorConfig.iconBg, nodeColorConfig.iconColor]"
        >
          <slot name="icon"></slot>
        </div>
        <div class="flex flex-1 flex-col overflow-hidden">
          <div class="text-foreground truncate text-sm font-semibold">
            {{ label }}
          </div>
          <div class="text-muted-foreground truncate text-[10px]">
            <slot name="desc"></slot>
          </div>
        </div>
        <!-- Token Usage -->
        <div
          v-if="executionStatus?.tokens_used"
          class="text-muted-foreground bg-muted border-border flex items-center rounded border px-1.5 py-0.5 text-[10px]"
        >
          {{ executionStatus.tokens_used }} T
        </div>
        <div class="flex gap-1">
          <slot name="actions"></slot>
        </div>
      </div>

      <!-- Body -->
      <div class="text-muted-foreground min-w-0 space-y-2 overflow-hidden p-4 text-xs">
        <slot></slot>
      </div>

      <!-- Input Handles (Left) -->
      <div v-if="inputs && inputs.length > 0">
        <Handle
          v-for="(input, index) in inputs"
          :key="input.id"
          type="target"
          :position="Position.Left"
          :id="input.id"
          class="!bg-primary !z-20 !h-3 !w-3 !border-2 !border-white transition-transform hover:scale-125"
          :style="{ top: `${((index + 1) * 100) / (inputs.length + 1)}%` }"
        />
      </div>
      <!-- Default single input if not specified but needed logic can be handled in parent -->

      <!-- Output Handles (Right) -->
      <div v-if="outputs && outputs.length > 0">
        <Handle
          v-for="(output, index) in outputs"
          :key="output.id"
          type="source"
          :position="Position.Right"
          :id="output.id"
          class="!bg-primary !z-20 !h-3 !w-3 !border-2 !border-white transition-transform hover:scale-125"
          :style="{ top: `${((index + 1) * 100) / (outputs.length + 1)}%` }"
        />
      </div>

      <!-- 悬停时显示的添加按钮 - 放在节点更右侧，不覆盖 Handle -->
      <!-- 分支类型节点（condition/intent/parallel/choice）不显示通用添加按钮，需要从具体分支 Handle 拖线 -->
      <div
        v-if="
          nodeType !== 'end' &&
          !['condition', 'intent', 'parallel', 'choice'].includes(
            nodeType || '',
          )
        "
        ref="addButtonRef"
        class="bg-primary hover:bg-primary/90 absolute -right-8 top-1/2 flex size-6 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full text-white opacity-0 shadow-md transition-opacity hover:scale-110 group-hover:opacity-100"
        title="{{ $t('ai-platform.workflow.nodes.common.addNextNode') }}"
        @click.stop="handleClick"
      >
        <Plus class="pointer-events-none size-3.5" />
      </div>
    </div>

    <!-- 节点下方的执行结果卡片（独立显示，不在节点内部） -->
    <NodeResultCard
      v-if="executionResult"
      :result="executionResult"
      :node-type="nodeType"
      class="mt-3"
    />
  </div>
</template>

<style scoped>
/* 自定义 Handle 样式 */
:deep(.vue-flow__handle) {
  z-index: 20;
  width: 10px;
  height: 10px;
  background: hsl(var(--primary));
}

/* 运行中边框呼吸动画 */
@keyframes pulse-border {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
  }
  50% {
    box-shadow: 0 0 0 8px rgba(59, 130, 246, 0);
  }
}

.animate-pulse-border {
  animation: pulse-border 1.5s ease-in-out infinite;
}
</style>
