<script lang="ts" setup>
import type { Edge, Node } from '@vue-flow/core';

import type { WorkflowRun } from '#/api/ai-platform/ai-platform';

import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';

import { ExternalLink } from '@vben/icons';
import { $t } from '@vben/locales';

import { ElAlert, ElButton, ElTag } from 'element-plus';

import { getWorkflowDetailApi, getWorkflowRunDetailApi } from '#/api/ai-platform/ai-platform';
import { ZqDesc, ZqDescItem } from '#/components/zq-desc';
import { ZqDialog } from '#/components/zq-dialog';
import { useAppContextStore } from '#/store/app-context';

import { definitionToFlowElements } from '../../workflow/shared/loadDefinition';
import { applyRunReplay } from '../../workflow/shared/useRunReplay';
import RunStatusTag from '../components/RunStatusTag.vue';
import WorkflowReadonlyCanvas from '../components/WorkflowReadonlyCanvas.vue';
import {
  formatDuration,
  formatTime,
  getTagLabel,
  getTagType,
  getTriggerOptions,
} from '../data';

const router = useRouter();
const appContextStore = useAppContextStore();
const triggerOptions = getTriggerOptions();

const visible = ref(false);
const loading = ref(false);
const runId = ref('');
const run = ref<WorkflowRun | null>(null);
const nodes = ref<Node[]>([]);
const edges = ref<Edge[]>([]);
const activeNodeId = ref('');
const definitionFallback = ref(false);

const dialogTitle = computed(() => run.value?.workflow_name || $t('ai-platform.workflowRuns.detail.runId'));

async function loadDetail() {
  if (!runId.value) return;

  loading.value = true;
  definitionFallback.value = false;
  activeNodeId.value = '';
  run.value = null;
  nodes.value = [];
  edges.value = [];

  try {
    const detail = await getWorkflowRunDetailApi(runId.value);
    run.value = detail;

    let definition = detail.definition_snapshot;
    if (!definition?.nodes?.length) {
      definitionFallback.value = true;
      try {
        const workflow = await getWorkflowDetailApi(detail.workflow_id);
        definition = detail.use_draft
          ? workflow.definition
          : workflow.published_definition || workflow.definition;
      } catch (error) {
        console.error(error);
        definition = { nodes: [], edges: [] };
      }
    }

    const base = definitionToFlowElements(definition || { nodes: [], edges: [] });
    const replayed = applyRunReplay(base.nodes, base.edges, detail);
    nodes.value = replayed.nodes;
    edges.value = replayed.edges;
  } catch (error) {
    console.error(error);
  } finally {
    loading.value = false;
  }
}

function open(id: string) {
  runId.value = id;
  visible.value = true;
}

function handleOpen() {
  loadDetail();
}

function openEditor() {
  if (!run.value?.workflow_id) return;
  visible.value = false;
  router.push(
    appContextStore.getContextPath(
      `/ai-platform/workflow/editor/${run.value.workflow_id}`,
    ),
  );
}

function triggerLabel(value?: string) {
  if (!value) return '-';
  return getTagLabel(value, triggerOptions);
}

defineExpose({ open });
</script>

<template>
  <ZqDialog
    v-model="visible"
    class="workflow-run-detail-dialog"
    :title="dialogTitle"
    :loading="loading"
    default-fullscreen
    :draggable="false"
    :show-footer="false"
    @open="handleOpen"
  >
    <template #title>
      <span class="flex items-center gap-2">
        {{ dialogTitle }}
        <RunStatusTag v-if="run" :status="run.status" />
      </span>
    </template>

    <template #header-extra>
      <ElButton
        v-if="run?.workflow_id"
        :icon="ExternalLink"
        @click="openEditor"
      >
        {{ $t('ai-platform.workflowRuns.detail.openEditor') }}
      </ElButton>
    </template>

    <div v-if="run" class="run-detail-layout flex h-full min-h-0 flex-col gap-4">
      <ElAlert
        v-if="definitionFallback"
        type="warning"
        :closable="false"
        show-icon
        :title="$t('ai-platform.workflowRuns.detail.snapshotMissing')"
      />

      <ZqDesc :column="4">
        <ZqDescItem :label="$t('ai-platform.workflowRuns.detail.runId')">
          {{ runId }}
        </ZqDescItem>
        <ZqDescItem :label="$t('ai-platform.workflowRuns.columns.trigger')">
          <ElTag
            :type="getTagType(run.trigger_type, triggerOptions)"
            size="small"
          >
            {{ triggerLabel(run.trigger_type) }}
          </ElTag>
        </ZqDescItem>
        <ZqDescItem :label="$t('ai-platform.workflowRuns.columns.steps')">
          {{ run.total_steps }}
        </ZqDescItem>
        <ZqDescItem :label="$t('ai-platform.workflowRuns.columns.tokens')">
          {{ run.total_tokens }}
        </ZqDescItem>
        <ZqDescItem :label="$t('ai-platform.workflowRuns.columns.duration')">
          {{ formatDuration(run.elapsed_time) }}
        </ZqDescItem>
        <ZqDescItem :label="$t('ai-platform.workflowRuns.columns.startedAt')">
          {{ formatTime(run.started_at) }}
        </ZqDescItem>
        <ZqDescItem :label="$t('ai-platform.workflowRuns.detail.completedAt')">
          {{ formatTime(run.completed_at) }}
        </ZqDescItem>
        <ZqDescItem :label="$t('ai-platform.workflowRuns.detail.version')">
          {{
            run.use_draft
              ? $t('ai-platform.workflowRuns.detail.draft')
              : run.workflow_version || '-'
          }}
        </ZqDescItem>
        <ZqDescItem
          v-if="run.error_message"
          :label="$t('ai-platform.workflowRuns.columns.error')"
          :span="4"
        >
          <span class="text-destructive">{{ run.error_message }}</span>
        </ZqDescItem>
      </ZqDesc>

      <div class="run-detail-canvas border-border overflow-hidden rounded-lg border">
        <WorkflowReadonlyCanvas
          :nodes="nodes"
          :edges="edges"
          :fit-node-id="activeNodeId"
        />
      </div>
    </div>
  </ZqDialog>
</template>

<style>
.workflow-run-detail-dialog.is-fullscreen .el-dialog__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.workflow-run-detail-dialog .zq-dialog-body {
  flex: 1;
  min-height: 0;
}

.workflow-run-detail-dialog.is-fullscreen .zq-dialog-body .el-scrollbar,
.workflow-run-detail-dialog.is-fullscreen .zq-dialog-body .el-scrollbar__wrap,
.workflow-run-detail-dialog.is-fullscreen .zq-dialog-body .el-scrollbar__view,
.workflow-run-detail-dialog.is-fullscreen .zq-dialog-body .el-scrollbar__view > div {
  height: 100%;
}

.workflow-run-detail-dialog .run-detail-layout {
  display: flex;
  height: 100%;
  min-height: 0;
  flex-direction: column;
  gap: 16px;
}

.workflow-run-detail-dialog .run-detail-canvas {
  flex: 1;
  min-height: 320px;
  height: 0;
}
</style>
