<!-- 重绘文本面板，负责剧集文本编辑、保存和重新推理控制。 -->
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { CircleClose, FullScreen, Refresh } from "@element-plus/icons-vue";
import type { GenerationTask, ProjectAsset, Storyboard } from "@/api/creative";
import AssetPromptEditor from "@/components/creative/AssetPromptEditor.vue";
import { taskElapsedLabel } from "@/utils/taskTimeout";

const props = defineProps<{
  storyboards: Storyboard[];
  assets: ProjectAsset[];
  selectedId: string;
  reinferTask?: GenerationTask;
  now?: number;
  reinferring?: boolean;
}>();
const emit = defineEmits<{
  save: [payload: Partial<Storyboard>];
  reinfer: [];
  stopReinfer: [task: GenerationTask];
}>();
const content = ref("");
const expanded = ref(false);
const selected = computed(() => props.storyboards.find((item) => item.id === props.selectedId));
const active = computed(() =>
  Boolean(
    props.reinferTask &&
    [
      "pending_submission",
      "submitting",
      "submitted",
      "processing",
      "result_ready",
      "downloading",
      "cancel_requested",
    ].includes(props.reinferTask.status),
  ),
);
const actionLabel = computed(() =>
  props.reinferring
    ? "正在启动"
    : props.reinferTask?.status === "cancel_requested"
      ? "停止中"
      : active.value
        ? `停止反推 ${taskElapsedLabel(props.reinferTask!, props.now || Date.now())}`
        : "重新反推",
);

watch(selected, (storyboard) => (content.value = storyboard?.prompt_content || ""), { immediate: true });
/** 提交当前文本修改。 */
function save() {
  if (selected.value && content.value !== (selected.value.prompt_content || "")) {
    const refs = props.assets
      .filter((asset) => asset.name.trim() && content.value.includes(`@${asset.name.trim()}`))
      .map((asset) => ({ id: asset.id, name: asset.name }));
    emit("save", { prompt_content: content.value, asset_refs: refs });
  }
}
/** 根据任务状态触发或取消重新推理。 */
function toggleReinfer() {
  if (props.reinferTask) emit("stopReinfer", props.reinferTask);
  else emit("reinfer");
}
</script>

<template>
  <section class="redraw-column text-column">
    <header>
      <strong>分镜提示词</strong><small>{{ storyboards.length }} 个分镜</small>
    </header>
    <div
      v-if="selected"
      class="text-editor"
    >
      <div class="selected-heading">
        <strong>分镜 {{ selected.sequence_no }}</strong
        ><span>{{ selected.title || "未命名分镜" }}</span>
      </div>
      <div class="prompt-editor-wrap">
        <AssetPromptEditor
          v-model="content"
          :assets="assets"
          variant="redraw"
          placeholder="输入提示词，输入 @ 插入资产"
          @blur="save"
        />
        <button
          class="expand-button"
          type="button"
          title="放大编辑提示词"
          @click="expanded = true"
        >
          <el-icon><FullScreen /></el-icon>
        </button>
      </div>
      <el-button
        :type="active ? 'danger' : 'default'"
        :icon="active ? CircleClose : Refresh"
        :loading="reinferring"
        :disabled="reinferTask?.status === 'cancel_requested'"
        @click="toggleReinfer"
        >{{ actionLabel }}</el-button
      >
    </div>
    <div
      v-else
      class="column-empty"
    >
      完成视频抽帧后，将在这里显示分镜提示词。
    </div>
    <el-dialog
      v-model="expanded"
      title="分镜提示词"
      width="min(900px, calc(100vw - 28px))"
      class="web-dialog creative-dialog prompt-dialog"
      append-to-body
      @closed="save"
    >
      <AssetPromptEditor
        v-model="content"
        :assets="assets"
        variant="redraw"
        placeholder="输入提示词，输入 @ 插入资产"
        expanded
        @blur="save"
      />
    </el-dialog>
  </section>
</template>

<style scoped lang="scss">
.text-column {
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.text-editor {
  min-height: 0;
  padding: 12px;
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 10px;
}
.selected-heading {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.selected-heading strong {
  color: var(--web-accent-dark);
  font-size: 13px;
}
.selected-heading span {
  min-width: 0;
  overflow: hidden;
  color: var(--web-text-tertiary);
  font-size: 11px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.prompt-editor-wrap {
  position: relative;
  min-height: 0;
  flex: 1;
  overflow: hidden;
}
.prompt-editor-wrap :deep(.asset-prompt-editor) {
  height: 100%;
}
.expand-button {
  position: absolute;
  right: 9px;
  bottom: 9px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  color: var(--web-panel-control-text);
  background: var(--web-surface);
  border: 1px solid var(--web-line-strong);
  border-radius: 6px;
  cursor: pointer;
}
.expand-button:hover {
  color: var(--web-accent-dark);
  border-color: var(--web-line-emphasis);
}
.column-empty {
  min-height: 240px;
  display: grid;
  place-items: center;
  flex: 1;
  color: var(--web-panel-hint);
  font-size: 13px;
  text-align: center;
}
</style>
