<template>
  <div class="app-container">
    <el-form
      :model="queryParams"
      ref="queryForm"
      size="small"
      :inline="true"
      v-show="showSearch"
      label-width="68px"
    >
      <el-form-item label="订单编号" prop="orderNum">
        <el-input
          v-model="queryParams.orderNum"
          placeholder="请输入订单编号"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="用户ID" prop="uuid">
        <el-input
          v-model="queryParams.uuid"
          placeholder="请输入用户ID"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="操作类型" prop="type">
        <el-select v-model="queryParams.type" placeholder="请选择操作类型" clearable>
          <el-option
            v-for="dict in dict.type.ai_function_type"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="是否置顶" prop="isTop">
        <el-select v-model="queryParams.isTop" placeholder="请选择" clearable>
          <el-option
            v-for="dict in dict.type.sys_yes_no"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select
          v-model="queryParams.status"
          placeholder="请选择状态"
          filterable
          clearable
          style="width: 200px; margin-bottom: 16px;"
        >
          <el-option
            v-for="(label, value) in statusMap"
            :key="value"
            :label="label"
            :value="Number(value)"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="创建时间">
        <el-date-picker
          v-model="dateRange"
          style="width: 240px"
          value-format="yyyy-MM-dd"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        ></el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['ai:order:export']"
        >导出</el-button>
      </el-form-item>
    </el-form>
    <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>

    <el-table v-loading="loading" :data="orderList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="主键ID" align="center" prop="id" width="60" />
      <!-- <el-table-column label="备注" align="center" prop="remark" /> -->
      <el-table-column label="订单编号" align="center" prop="orderNum" width="150"/>
      <el-table-column label="用户ID" align="center" prop="uuid" width="100" />
      <el-table-column label="操作类型" align="center" prop="type" width="90" >
        <template slot-scope="scope">
          <dict-tag :options="dict.type.ai_function_type" :value="scope.row.type" />
        </template>
      </el-table-column>
      <el-table-column label="金额" align="center" prop="amount" width="100" />
      <el-table-column label="生成结果" align="center" width="200">
        <template slot-scope="scope">
          <!-- 判断是否为链接 -->
          <template v-if="isUrl(scope.row.result)">
            <!-- 图片链接 -->
            <img
              v-if="isImage(scope.row.result)"
              :src="scope.row.result"
              class="preview-img"
              @click="viewImage(scope.row.result)"
              alt="预览图片"
            />
            <!-- 视频链接 -->
            <video
              v-else-if="isVideo(scope.row.result)"
              :src="scope.row.result"
              class="preview-video"
              @click="playVideo(scope.row.result)"
            />
          </template>
          <!-- 视频任务失败等场景：result 为 VideoTaskError JSON（表格内简短，悬停看全文） -->
          <template v-else-if="parseVolcTaskErrorJson(scope.row.result)">
            <span
              v-for="err in [parseVolcTaskErrorJson(scope.row.result)]"
              :key="'oe-' + scope.row.id"
              class="order-result-error-wrap"
            >
              <el-tooltip
                placement="top-start"
                effect="dark"
                :open-delay="200"
                popper-class="order-result-error-tooltip-popper"
              >
                <div slot="content" class="order-result-error-tooltip-body">
                  <div class="order-result-error-tooltip-row">
                    <span class="order-result-error-tooltip-k">错误编号：</span>
                    <span class="order-result-error-tooltip-v">{{ err.code || '—' }}</span>
                  </div>
                  <div
                    v-if="volcTaskErrorHintForCode(err.code)"
                    class="order-result-error-tooltip-row"
                  >
                    <span class="order-result-error-tooltip-k">中文说明：</span>
                    <span class="order-result-error-tooltip-v">{{
                      volcTaskErrorHintForCode(err.code)
                    }}</span>
                  </div>
                  <div class="order-result-error-tooltip-row order-result-error-tooltip-row--msg">
                    <span class="order-result-error-tooltip-k">信息：</span>
                    <span class="order-result-error-tooltip-v">{{ err.message || '—' }}</span>
                  </div>
                </div>
                <span class="order-result-error-compact">{{ volcTaskErrorCellSummary(err) }}</span>
              </el-tooltip>
            </span>
          </template>
          <!-- 非链接内容（如任务 id，可点击尝试拉取视频） -->
          <span v-else @click="handleOtherEvent(scope.row)">{{ scope.row.result }}</span>
        </template>
      </el-table-column>
      <el-table-column label="文字描述" align="center" prop="text">
        <template slot-scope="scope">
          <!-- 核心：给 popover 加 ref，触发元素绑定 v-popover -->
          <el-popover
            ref="promptPopover"
            placement="top"
            width="400"
            trigger="hover"
            :content="scope.row.text || '无提示词'"
          ></el-popover>
          <!-- 触发元素：绑定 v-popover 到 popover 的 ref -->
          <div
            class="text-ellipsis-two-lines"
            v-popover:promptPopover
            style="cursor: pointer;"
          >{{ scope.row.text}}</div>
        </template>
      </el-table-column>
      <el-table-column label="置顶" align="center" key="status" width="60">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.isTop"
            active-value="Y"
            inactive-value="N"
            @change="handleIsTopChange(scope.row)"
          ></el-switch>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" align="center" prop="createTime" width="150"/>
      <el-table-column label="状态" align="center" prop="status" :formatter="formatStatus" width="70"/>
      <el-table-column label="来源" align="center" prop="source" width="70"/>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改订单管理对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="订单编号" prop="orderNum">
          <el-input v-model="form.orderNum" placeholder="请输入订单编号" />
        </el-form-item>
        <el-form-item label="用户ID" prop="userId">
          <el-input v-model="form.userId" placeholder="请输入用户ID" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select
            v-model="form.status"
            placeholder="请选择状态"
            filterable
            clearable
            style="width: 200px;"
          >
            <el-option
              v-for="(label, value) in statusMap"
              :key="value"
              :label="label"
              :value="Number(value)"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="金额" prop="amount">
          <el-input v-model="form.amount" placeholder="请输入金额" />
        </el-form-item>
        <el-form-item label="生成结果" prop="result">
          <el-input v-model="form.result" placeholder="请输入生成结果" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 图片预览弹窗 -->
    <el-dialog :visible.sync="imageDialogVisible" title="图片预览" width="60%">
      <img :src="previewImageUrl" class="dialog-img" alt="大图预览" />
    </el-dialog>

    <!-- 新增视频弹窗 -->
    <el-dialog :visible.sync="videoDialogVisible" title="视频播放" width="60%">
      <video :src="previewVideoUrl" controls class="dialog-video"></video>
    </el-dialog>
  </div>
</template>

<script>
import {
  listOrder,
  getOrder,
  delOrder,
  addOrder,
  downloadVideo,
  changeIsTop,
  updateOrder
} from "@/api/ai/order";

export default {
  name: "Order",
  dicts: ["ai_function_type", "sys_yes_no"],
  data() {
    return {
      imageDialogVisible: false,
      videoDialogVisible: false,
      previewVideoUrl: "",
      previewImageUrl: "",
      dateRange: [],
      statusMap: {
        0: "进行中",
        1: "已完成",
        2: "已失败"
      },
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 订单管理表格数据
      orderList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        orderNum: null,
        userId: null,
        type: null,
        amount: null,
        result: null,
        status: null
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        delFlag: [
          { required: true, message: "删除标志不能为空", trigger: "blur" }
        ]
      }
    };
  },
  created() {
    this.getList();
  },
  methods: {
    handleIsTopChange(row) {
      let text = row.isTop === "Y" ? "置顶" : "取消置顶";
      this.$modal
        .confirm('确认要"' + text + '""' + row.id + '"作品吗？')
        .then(function() {
          return changeIsTop(row.id, row.isTop);
        })
        .then(() => {
          this.$modal.msgSuccess(text + "成功");
        })
        .catch(function() {
          row.isTop = row.isTop === "Y" ? "N" : "Y";
        });
    },
    // 判断是否为 http(s) URL（与 portal-ui 生成视频模块一致）
    isUrl(str) {
      const value = String(str || "").trim();
      return /^https?:\/\//i.test(value);
    },
    /** 已知错误码对应中文说明（与门户 VideoGen 一致） */
    volcTaskErrorHintForCode(code) {
      const c = String(code || "").trim();
      const hints = {
        OutputVideoSensitiveContentDetected: "输出视频可能包含敏感信息",
        InvalidParameter: "请求参数无效"
      };
      return hints[c] || "";
    },
    /** 表格内摘要：已知码只显示中文，未知码显示 code */
    volcTaskErrorCellSummary(err) {
      if (!err) return "—";
      const code = String(err.code || "").trim();
      const hint = this.volcTaskErrorHintForCode(code);
      if (hint) return hint;
      if (code) return code;
      const msg = String(err.message || "").trim();
      return msg ? msg.slice(0, 32) + (msg.length > 32 ? "…" : "") : "—";
    },
    /** 已知火山错误码后附中文说明（括号），导出等场景可用 */
    volcFailureCodeWithHint(code) {
      const c = String(code || "").trim();
      if (!c) return "";
      const hint = this.volcTaskErrorHintForCode(c);
      return hint ? `${c}（${hint}）` : c;
    },
    /** result 为火山回调失败写入的 VideoTaskError JSON 时解析为 { code, message } */
    parseVolcTaskErrorJson(str) {
      const s = String(str || "").trim();
      if (!s || s[0] !== "{") return null;
      try {
        const o = JSON.parse(s);
        if (
          o &&
          typeof o === "object" &&
          !Array.isArray(o) &&
          ("code" in o || "message" in o)
        ) {
          return {
            code: o.code != null ? String(o.code) : "",
            message: o.message != null ? String(o.message) : ""
          };
        }
      } catch (_) {
        /* ignore */
      }
      return null;
    },
    // 判断是否为图片结果（与 portal-ui GeneratedAssets 一致）
    isImage(url) {
      const value = String(url || "").trim();
      if (!value) return false;
      return /\.(jpeg|jpg|png|gif|webp|bmp)(\?.*)?$/i.test(value);
    },
    // 判断是否为视频结果（与 portal-ui VideoGen/GeneratedAssets 一致）
    isVideo(url) {
      const value = String(url || "").trim();
      if (!value) return false;
      return /\.(mp4|mov|webm|ogg|m4v|avi|mkv)(\?.*)?$/i.test(value);
    },
    // 查看图片
    viewImage(url) {
      this.previewImageUrl = url;
      this.imageDialogVisible = true;
    },
    // 播放视频
    playVideo(url) {
      this.previewVideoUrl = url;
      this.videoDialogVisible = true;
    },
    // 非链接内容点击事件
    async handleOtherEvent(row) {
      if (this.parseVolcTaskErrorJson(row.result)) return;
      // 防止重复点击
      if (row.isDownloading) return;
      const originalResult = row.result;
      try {
        // 标记为下载中状态
        row.isDownloading = true;
        // 保存原始内容
        
        // 修改显示内容为“下载中...”
        row.result = "下载中...";

        // 执行下载操作
        const resultId = originalResult; // 假设result存储的是ID
        var res = await downloadVideo(resultId);
        if (res.status === "succeeded") {
          row.result = res.content.video_url;
        } else {
          row.result = "视频生成中"
        }
       
      } catch (error) {
        console.error('下载失败:', error);
        // 失败后恢复原始内容
        row.result = originalResult || row.result.replace("下载中...", "");
        this.$message.error('下载失败，请重试');
      } finally {
        // 重置下载状态
        row.isDownloading = false;
      }
    },

    formatStatus(row) {
      // 如果有匹配的类型则显示对应文字，否则显示"未知"
      return this.statusMap[row.status] || "未知";
    },
    /** 查询订单管理列表 */
    getList() {
      this.loading = true;
      listOrder(this.addDateRange(this.queryParams, this.dateRange)).then(
        response => {
          this.orderList = response.rows;
          this.total = response.total;
          this.loading = false;
        }
      );
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        delFlag: null,
        createBy: null,
        createTime: null,
        updateBy: null,
        updateTime: null,
        remark: null,
        orderNum: null,
        userId: null,
        type: null,
        amount: null,
        result: null,
        status: null
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加订单管理";
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids;
      getOrder(id).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改订单管理";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.id != null) {
            updateOrder(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addOrder(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal
        .confirm('是否确认删除订单管理编号为"' + ids + '"的数据项？')
        .then(function() {
          return delOrder(ids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download(
        "ai/order/export",
        {
          ...this.queryParams
        },
        `order_${new Date().getTime()}.xlsx`
      );
    }
  }
};
</script>

<style>
.dialog-video {
  width: 100%;
  height: auto;
}

.preview-img {
  width: 80px;
  height: 60px;
  object-fit: cover;
  cursor: pointer;
  border-radius: 4px;
}

.preview-video {
  width: 120px;
  height: 80px;
  border-radius: 4px;
}

.dialog-img {
  width: 100%;
  height: auto;
}

.order-result-error-wrap {
  display: inline-block;
}

.order-result-error-compact {
  display: inline-block;
  max-width: 200px;
  margin: 0 auto;
  font-size: 12px;
  line-height: 1.35;
  color: #c45656;
  cursor: help;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

.order-result-error-tooltip-body {
  max-width: 420px;
  text-align: left;
  line-height: 1.5;
  font-size: 12px;
}

.order-result-error-tooltip-row {
  margin-bottom: 6px;
}

.order-result-error-tooltip-row:last-child {
  margin-bottom: 0;
}

.order-result-error-tooltip-row--msg .order-result-error-tooltip-v {
  display: block;
  margin-top: 2px;
  white-space: pre-wrap;
  word-break: break-word;
}

.order-result-error-tooltip-k {
  font-weight: 600;
  color: #fde2e2;
}

.order-result-error-tooltip-v {
  color: #fff;
}

.text-ellipsis-two-lines {
  /* 必须设置宽度（继承表格列宽，也可手动指定） */
  width: 100%;
  /* 核心属性：多行文本溢出隐藏 */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; /* 显示2行 */
  line-clamp: 2; /* 标准属性，兼容现代浏览器 */
  overflow: hidden;
  /* 可选：调整行高，优化显示 */
  line-height: 1.5;
  max-height: 3em; /* 行高1.5 × 2行 = 3em，防止高度溢出 */
  /* 可选：文本对齐 */
  text-align: center;
  /* 解决scoped样式穿透（如果需要） */
  /deep/ & {
    box-sizing: border-box;
    padding: 0 4px;
  }
}
</style>
