<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="90px">
      <el-form-item label="方案名称" prop="planName">
        <el-input v-model="queryParams.planName" placeholder="请输入方案名称" clearable style="width: 200px"
          @keyup.enter="handleQuery" />
      </el-form-item>
      <el-form-item label="循环方式" prop="loopMode">
        <el-select v-model="queryParams.loopMode" placeholder="请选择循环方式" clearable style="width: 160px">
          <el-option label="循环播放" value="loop" />
          <el-option label="播放一次" value="once" />
        </el-select>
      </el-form-item>
      <el-form-item label="播放状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择播放状态" clearable style="width: 160px">
          <el-option label="当前播放" value="1" />
          <el-option label="备用方案" value="0" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['base:plan:add']">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
          v-hasPermi="['base:plan:edit']">修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['base:plan:remove']">删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="Download" @click="handleExport"
          v-hasPermi="['base:plan:export']">导出</el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-alert v-if="currentPlayingCount > 1" title="检测到存在多条当前播放方案，请联系后端检查播放状态唯一性规则。" type="warning" show-icon
      :closable="false" class="play-status-alert" />

    <el-table v-loading="loading" :data="planList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="方案名称" align="left" prop="planName" min-width="180" show-overflow-tooltip />
      <el-table-column label="循环方式" align="center" prop="loopMode" width="110">
        <template #default="scope">
          <el-tag v-if="scope.row.loopMode === 'loop'" type="success">循环播放</el-tag>
          <el-tag v-else-if="scope.row.loopMode === 'once'" type="info">播放一次</el-tag>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column label="素材数" align="center" prop="assetCount" width="90">
        <template #default="scope">
          <el-tag type="primary">{{ scope.row.assetCount || 0 }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="播放状态" align="center" prop="status" width="110">
        <template #default="scope">
          <el-tag v-if="String(scope.row.status) === '1'" type="success">当前播放</el-tag>
          <el-tag v-else-if="String(scope.row.status) === '0'" type="info">备用方案</el-tag>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="240" fixed="right" class-name="small-padding fixed-width">
        <template #default="scope">
          <el-button link type="primary" icon="View" @click="handlePreview(scope.row)">预览</el-button>
          <el-button v-if="String(scope.row.status) !== '1'" link type="success" icon="CircleCheck"
            @click="handleStatusChange(scope.row, '1')" v-hasPermi="['base:plan:edit']">启用播放</el-button>
          <el-button v-if="String(scope.row.status) === '1'" link type="warning" icon="CircleClose"
            @click="handleStatusChange(scope.row, '0')" v-hasPermi="['base:plan:edit']">设为备用</el-button>
          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['base:plan:edit']">编辑</el-button>
          <el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)"
            v-hasPermi="['base:plan:remove']">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

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

    <!-- 添加或修改播放方案对话框 -->
    <el-dialog :title="title" v-model="open" width="960px" append-to-body>
      <el-form ref="planRef" :model="form" :rules="rules" label-width="110px">
        <el-row>
          <el-col :span="24">
            <el-form-item label="方案名称" prop="planName">
              <el-input v-model="form.planName" maxlength="100" show-word-limit placeholder="请输入方案名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="循环方式" prop="loopMode">
              <el-radio-group v-model="form.loopMode">
                <el-radio label="loop">循环播放</el-radio>
                <el-radio label="once">播放一次</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="播放状态" prop="status">
              <el-radio-group v-model="form.status">
                <el-radio label="1">当前播放</el-radio>
                <el-radio label="0">备用方案</el-radio>
              </el-radio-group>
              <div class="form-tip">同一时间仅允许一套方案作为当前播放方案，建议新增方案先保存为备用方案。</div>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="备注" prop="remark">
              <el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit
                placeholder="请输入备注" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-divider content-position="center">素材编排</el-divider>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button type="primary" icon="Plus" @click="handleSelectAsset">选择素材</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="danger" icon="Delete" @click="handleDeleteRobotOpsPlayPlanItem">移除素材</el-button>
          </el-col>
        </el-row>
        <el-table :data="robotOpsPlayPlanItemList" @selection-change="handleRobotOpsPlayPlanItemSelectionChange"
          ref="robotOpsPlayPlanItem" empty-text="请点击「选择素材」添加播放内容">
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column label="素材" min-width="260">
            <template #default="scope">
              <div class="asset-info">
                <div class="asset-thumb">
                  <image-preview v-if="getAssetThumb(scope.row)" :src="getAssetThumb(scope.row)" :width="54"
                    :height="54" />
                  <div v-else class="video-thumb">
                    <el-icon>
                      <VideoPlay />
                    </el-icon>
                  </div>
                </div>
                <div class="asset-meta">
                  <div class="asset-name">{{ scope.row.assetName || '未命名素材' }}</div>
                  <div class="asset-sub">
                    <el-tag v-if="scope.row.assetType === 'image'" size="small" type="success">图片</el-tag>
                    <el-tag v-else-if="scope.row.assetType === 'video'" size="small" type="warning">视频</el-tag>
                    <el-tag v-else size="small" type="info">未知</el-tag>
                    <span class="asset-id">ID: {{ scope.row.assetId }}</span>
                  </div>
                </div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="顺序" prop="playOrder" width="140" align="center">
            <template #default="scope">
              <el-button link type="primary" :disabled="scope.$index === 0"
                @click="moveItem(scope.$index, -1)">上移</el-button>
              <el-button link type="primary" :disabled="scope.$index === robotOpsPlayPlanItemList.length - 1"
                @click="moveItem(scope.$index, 1)">下移</el-button>
            </template>
          </el-table-column>
          <el-table-column label="停留时长" prop="staySeconds" width="160" align="center">
            <template #default="scope">
              <el-input-number v-if="scope.row.assetType === 'image'" v-model="scope.row.staySeconds" :min="1"
                :max="3600" :step="1" controls-position="right" style="width: 120px" />
              <span v-else class="text-muted">视频播完切换</span>
            </template>
          </el-table-column>
          <el-table-column label="文件信息" min-width="160">
            <template #default="scope">
              <div class="asset-file-info">
                <div>{{ scope.row.resolution || '-' }}</div>
                <div v-if="scope.row.assetType === 'video'">时长：{{ formatDuration(scope.row.durationSeconds) }}</div>
                <div v-else>图片停留：{{ scope.row.staySeconds || '-' }} 秒</div>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 选择素材弹窗 -->
    <el-dialog title="选择素材" v-model="assetSelectOpen" width="900px" append-to-body @closed="selectedAssets = []">
      <el-form :model="assetQueryParams" :inline="true" label-width="80px">
        <el-form-item label="素材名称">
          <el-input v-model="assetQueryParams.assetName" placeholder="请输入素材名称" clearable
            @keyup.enter="handleAssetQuery" />
        </el-form-item>
        <el-form-item label="素材类型">
          <el-select v-model="assetQueryParams.assetType" placeholder="请选择素材类型" clearable style="width: 140px">
            <el-option label="图片" value="image" />
            <el-option label="视频" value="video" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleAssetQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetAssetQuery">重置</el-button>
        </el-form-item>
      </el-form>
      <el-alert title="仅显示启用状态的素材；已停用素材不能被新播放方案选择。" type="info" show-icon :closable="false" class="asset-select-tip" />
      <el-table v-loading="assetLoading" :data="assetList" @selection-change="handleAssetSelectionChange">
        <el-table-column type="selection" width="50" align="center" />
        <el-table-column label="缩略图" width="90" align="center">
          <template #default="scope">
            <image-preview v-if="getAssetThumb(scope.row)" :src="getAssetThumb(scope.row)" :width="48" :height="48" />
            <div v-else class="video-thumb small">
              <el-icon>
                <VideoPlay />
              </el-icon>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="素材名称" prop="assetName" min-width="180" show-overflow-tooltip />
        <el-table-column label="类型" prop="assetType" width="90" align="center">
          <template #default="scope">
            <el-tag v-if="scope.row.assetType === 'image'" size="small" type="success">图片</el-tag>
            <el-tag v-else-if="scope.row.assetType === 'video'" size="small" type="warning">视频</el-tag>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="分辨率" prop="resolution" width="120" align="center">
          <template #default="scope">{{ scope.row.resolution || '-' }}</template>
        </el-table-column>
        <el-table-column label="视频时长" prop="durationSeconds" width="120" align="center">
          <template #default="scope">{{ formatDuration(scope.row.durationSeconds) }}</template>
        </el-table-column>
      </el-table>
      <pagination v-show="assetTotal > 0" :total="assetTotal" v-model:page="assetQueryParams.pageNum"
        v-model:limit="assetQueryParams.pageSize" @pagination="getAssetList" />
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="confirmSelectAsset">确 定</el-button>
          <el-button @click="handleCancelSelectAsset">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 播放方案预览弹窗 -->
    <el-dialog :title="previewPlan?.planName ? '播放方案预览 - ' + previewPlan.planName : '播放方案预览'" v-model="previewOpen"
      width="960px" append-to-body @closed="resetPreview">
      <div v-if="previewPlan" class="plan-preview">
        <div class="preview-header">
          <div>
            <div class="preview-title">{{ previewPlan.planName || '-' }}</div>
            <div class="preview-sub">
              <el-tag v-if="previewPlan.loopMode === 'loop'" type="success">循环播放</el-tag>
              <el-tag v-else-if="previewPlan.loopMode === 'once'" type="info">播放一次</el-tag>
              <el-tag v-if="String(previewPlan.status) === '1'" type="warning">当前播放</el-tag>
              <el-tag v-else type="info">备用方案</el-tag>
              <span>素材数：{{ previewItems.length }}</span>
              <span v-if="previewItems.length">当前：{{ previewIndex + 1 }} / {{ previewItems.length }}</span>
            </div>
          </div>
        </div>
        <div class="preview-body">
          <div class="preview-main">
            <div class="preview-stage">
              <div v-if="currentPreviewItem && currentPreviewItem.fileUrl">
                <img v-if="currentPreviewItem.assetType === 'image'" :src="currentPreviewItem.fileUrl"
                  class="preview-media preview-image" @error="handlePreviewMediaError" />
                <video v-else-if="currentPreviewItem.assetType === 'video'" ref="previewVideoRef"
                  :src="currentPreviewItem.fileUrl" class="preview-media preview-video" controls
                  @error="handlePreviewMediaError" />
                <div v-else class="preview-empty">暂不支持该素材类型预览</div>
              </div>
              <div v-else-if="currentPreviewItem && !currentPreviewItem.fileUrl" class="preview-empty">素材文件地址为空，无法预览
              </div>
              <div v-else class="preview-empty">暂无可预览素材</div>
            </div>
            <div v-if="currentPreviewItem" class="preview-current-info">
              <div class="preview-current-name">{{ currentPreviewItem.assetName || '未命名素材' }}</div>
              <div class="preview-current-desc">
                <el-tag v-if="currentPreviewItem.assetType === 'image'" size="small" type="success">图片</el-tag>
                <el-tag v-else-if="currentPreviewItem.assetType === 'video'" size="small" type="warning">视频</el-tag>
                <span v-if="currentPreviewItem.assetType === 'image'">停留 {{ currentPreviewItem.staySeconds || '-' }}
                  秒</span>
                <span v-else-if="currentPreviewItem.assetType === 'video'">视频播完切换</span>
                <span v-if="currentPreviewItem.resolution">分辨率：{{ currentPreviewItem.resolution }}</span>
                <span v-if="currentPreviewItem.durationSeconds">时长：{{ formatDuration(currentPreviewItem.durationSeconds)
                }}</span>
              </div>
            </div>
          </div>
          <div class="preview-list">
            <div class="preview-list-title">播放清单</div>
            <div v-for="(item, index) in previewItems" :key="item.assetId || index" class="preview-item"
              :class="{ active: index === previewIndex }" @click="setPreviewIndex(index)">
              <div class="preview-item-index">{{ index + 1 }}</div>
              <div class="preview-item-thumb">
                <image-preview v-if="getAssetThumb(item)" :src="getAssetThumb(item)" :width="44" :height="44" />
                <div v-else class="video-thumb small">
                  <el-icon>
                    <VideoPlay />
                  </el-icon>
                </div>
              </div>
              <div class="preview-item-meta">
                <div class="preview-item-name">{{ item.assetName || '未命名素材' }}</div>
                <div class="preview-item-desc">
                  <el-tag v-if="item.assetType === 'image'" size="small" type="success">图片</el-tag>
                  <el-tag v-else-if="item.assetType === 'video'" size="small" type="warning">视频</el-tag>
                  <el-tag v-if="String(item.assetStatus) === '0'" size="small" type="danger">已停用</el-tag>
                  <span v-if="item.assetType === 'image'">停留 {{ item.staySeconds || '-' }} 秒</span>
                  <span v-else>视频播完切换</span>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="preview-actions">
          <el-button :disabled="previewIndex <= 0" @click="setPreviewIndex(previewIndex - 1)">上一个</el-button>
          <el-button :disabled="previewIndex >= previewItems.length - 1"
            @click="setPreviewIndex(previewIndex + 1)">下一个</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="Plan">
import { listPlan, getPlan, delPlan, addPlan, updatePlan } from "@/api/base/plan"
import { listMediAasset } from "@/api/base/mediAasset"

const { proxy } = getCurrentInstance()

const planList = ref([])
const robotOpsPlayPlanItemList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const checkedRobotOpsPlayPlanItem = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")

const previewOpen = ref(false)
const previewPlan = ref(null)
const previewItems = ref([])
const previewIndex = ref(0)
const previewVideoRef = ref(null)
const currentPreviewItem = computed(() => {
  return previewItems.value[previewIndex.value] || null
})
const currentPlayingCount = computed(() => {
  return planList.value.filter(item => String(item.status) === '1').length
})

function pausePreviewVideo() {
  const video = previewVideoRef.value
  if (video && typeof video.pause === 'function') {
    video.pause()
  }
}

function setPreviewIndex(index) {
  if (index < 0 || index >= previewItems.value.length) return
  pausePreviewVideo()
  previewIndex.value = index
}

const assetSelectOpen = ref(false)
const assetLoading = ref(false)
const assetList = ref([])
const selectedAssets = ref([])
const assetTotal = ref(0)
const assetQueryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  assetName: undefined,
  assetType: undefined,
  status: '1'
})

const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    planName: undefined,
    loopMode: undefined,
    status: undefined,
  },
  rules: {
    planName: [
      { required: true, message: "方案名称不能为空", trigger: "blur" },
      { max: 100, message: "方案名称不能超过 100 字", trigger: "blur" }
    ],
    loopMode: [
      { required: true, message: "请选择循环方式", trigger: "change" }
    ],
    status: [
      { required: true, message: "请选择播放状态", trigger: "change" }
    ],
    remark: [
      { max: 500, message: "备注不能超过 500 字", trigger: "blur" }
    ]
  }
})

const { queryParams, form, rules } = toRefs(data)

function getAssetThumb(row) {
  if (row.thumbnailUrl) return row.thumbnailUrl
  if (row.assetType === 'image' && row.fileUrl) return row.fileUrl
  return ''
}

function formatDuration(seconds) {
  const value = Number(seconds)
  if (!value) return '-'
  const m = Math.floor(value / 60)
  const s = value % 60
  return m > 0 ? `${m}分${s}秒` : `${s}秒`
}

function moveItem(index, direction) {
  const targetIndex = index + direction
  if (targetIndex < 0 || targetIndex >= robotOpsPlayPlanItemList.value.length) return
  const list = robotOpsPlayPlanItemList.value
  const temp = list[index]
  list[index] = list[targetIndex]
  list[targetIndex] = temp
  refreshPlayOrder()
}

function refreshPlayOrder() {
  robotOpsPlayPlanItemList.value.forEach((item, index) => {
    item.playOrder = index + 1
    item.transitionType = item.transitionType || 'none'
  })
}

/** 查询播放方案列表 */
function getList() {
  loading.value = true
  listPlan(queryParams.value).then(response => {
    planList.value = response.rows || []
    total.value = response.total || 0
  }).catch(() => {
    planList.value = []
    total.value = 0
  }).finally(() => {
    loading.value = false
  })
}

/** 取消按钮 */
function cancel() {
  open.value = false
  reset()
}

/** 表单重置 */
function reset() {
  form.value = {
    id: null,
    planName: null,
    loopMode: 'loop',
    assetCount: 0,
    status: '0',
    remark: null,
    createBy: null,
    createTime: null,
    updateBy: null,
    updateTime: null
  }
  robotOpsPlayPlanItemList.value = []
  proxy.resetForm("planRef")
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1
  if (queryParams.value.planName) {
    queryParams.value.planName = queryParams.value.planName.trim()
  }
  getList()
}

/** 重置按钮操作 */
function resetQuery() {
  proxy.resetForm("queryRef")
  handleQuery()
}

/** 多选框选中数据 */
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.id)
  single.value = selection.length != 1
  multiple.value = !selection.length
}

/** 新增按钮操作 */
function handleAdd() {
  reset()
  open.value = true
  title.value = "新增播放方案"
  nextTick(() => {
    proxy.$refs.robotOpsPlayPlanItem?.clearSelection?.()
  })
}

/** 修改按钮操作 */
function handleUpdate(row) {
  reset()
  const _id = row.id || ids.value
  getPlan(_id).then(response => {
    const data = response.data || {}
    form.value = {
      ...data,
      loopMode: data.loopMode || 'loop',
      status: data.status != null ? String(data.status) : '0'
    }
    const itemList = data.robotOpsPlayPlanItemList || data.itemList || []
    robotOpsPlayPlanItemList.value = itemList.map((item, index) => ({
      ...item,
      playOrder: item.playOrder || index + 1,
      transitionType: item.transitionType || 'none'
    }))
    open.value = true
    title.value = "编辑播放方案"
  }).finally(() => {
    nextTick(() => {
      proxy.$refs.robotOpsPlayPlanItem?.clearSelection?.()
    })
  })
}

/** 提交按钮 */
function submitForm() {
  proxy.$refs["planRef"].validate(valid => {
    if (!valid) return
    if (!robotOpsPlayPlanItemList.value.length) {
      proxy.$modal.msgWarning('请至少选择一个素材')
      return
    }
    for (const item of robotOpsPlayPlanItemList.value) {
      if (!item.assetId) {
        proxy.$modal.msgWarning('存在未选择素材的明细，请检查')
        return
      }
      if (item.assetType === 'image' && (!item.staySeconds || Number(item.staySeconds) <= 0)) {
        proxy.$modal.msgWarning('图片素材必须填写停留时长')
        return
      }
    }
    if (String(form.value.status) === '1') {
      proxy.$modal.confirm('设为当前播放后，其他播放方案应自动变为备用方案，确认继续吗？').then(() => {
        doSubmitForm()
      }).catch(() => { })
      return
    }
    doSubmitForm()
  })
}

function doSubmitForm() {
  refreshPlayOrder()
  const submitItemList = robotOpsPlayPlanItemList.value.map(item => ({
    id: item.id,
    planId: item.planId,
    assetId: item.assetId,
    playOrder: item.playOrder,
    staySeconds: item.assetType === 'image' ? item.staySeconds : null,
    transitionType: item.transitionType || 'none'
  }))
  const payload = {
    id: form.value.id,
    planName: form.value.planName,
    loopMode: form.value.loopMode,
    status: String(form.value.status || '0'),
    remark: form.value.remark,
    robotOpsPlayPlanItemList: submitItemList,
    itemList: submitItemList
  }
  if (form.value.id != null) {
    updatePlan(payload).then(() => {
      proxy.$modal.msgSuccess("修改成功")
      open.value = false
      getList()
    })
  } else {
    addPlan(payload).then(() => {
      proxy.$modal.msgSuccess("新增成功")
      open.value = false
      getList()
    })
  }
}

/** 删除按钮操作 */
function handleDelete(row) {
  const _ids = row.id || ids.value
  proxy.$modal.confirm('确认删除选中的播放方案吗？如删除的是当前播放方案，可能导致车端无可播放方案，请谨慎操作。').then(function () {
    return delPlan(_ids)
  }).then(() => {
    getList()
    proxy.$modal.msgSuccess("删除成功")
  }).catch(() => { })
}

/** 播放方案素材明细删除按钮操作 */
function handleDeleteRobotOpsPlayPlanItem() {
  if (checkedRobotOpsPlayPlanItem.value.length === 0) {
    proxy.$modal.msgError("请先选择要移除的素材")
    return
  }
  robotOpsPlayPlanItemList.value = robotOpsPlayPlanItemList.value.filter(item => {
    return !checkedRobotOpsPlayPlanItem.value.includes(item)
  })
  checkedRobotOpsPlayPlanItem.value = []
  proxy.$refs.robotOpsPlayPlanItem?.clearSelection?.()
  refreshPlayOrder()
}

/** 复选框选中数据 */
function handleRobotOpsPlayPlanItemSelectionChange(selection) {
  checkedRobotOpsPlayPlanItem.value = selection
}

/** 导出按钮操作 */
function handleExport() {
  proxy.download('base/plan/export', {
    ...queryParams.value
  }, `播放方案_${new Date().getTime()}.xlsx`)
}

/** 预览 */
function handlePreview(row) {
  if (!row || !row.id) {
    proxy.$modal.msgWarning('请选择要预览的播放方案')
    return
  }
  getPlan(row.id).then(response => {
    const data = response.data || {}
    const itemList = data.robotOpsPlayPlanItemList || data.itemList || []
    previewPlan.value = data
    previewItems.value = itemList
      .map((item, index) => ({
        ...item,
        playOrder: item.playOrder || index + 1,
        transitionType: item.transitionType || 'none'
      }))
      .sort((a, b) => Number(a.playOrder || 0) - Number(b.playOrder || 0))
    previewIndex.value = 0
    previewOpen.value = true
    if (!previewItems.value.length) {
      proxy.$modal.msgWarning('该播放方案暂无素材明细')
    }
  }).catch(() => {
    proxy.$modal.msgError('获取播放方案详情失败，无法预览')
  })
}

function resetPreview() {
  pausePreviewVideo()
  previewPlan.value = null
  previewItems.value = []
  previewIndex.value = 0
}

function handlePreviewMediaError() {
  proxy.$modal.msgWarning('素材文件暂无法预览，请检查文件地址是否有效。')
}


/** 状态变更 (启用播放/设为备用) */
function handleStatusChange(row, targetStatus) {
  const isEnable = targetStatus === '1'
  const actionText = isEnable ? '启用播放' : '设为备用'
  const confirmMsg = isEnable
    ? '确认启动播放吗？注意：系统通常只允许一个方案处于当前播放状态，其他方案可能会自动转为备用。'
    : '确认设为备用吗？'

  // 修改点：添加第二个参数对象，设置 dangerouslyUseHTMLString: true
  proxy.$modal.confirm(confirmMsg, {
    dangerouslyUseHTMLString: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    // 1. 显示加载状态，防止重复点击
    loading.value = true

    // 2. 获取该方案的最新完整数据
    return getPlan(row.id)
  }).then(response => {
    const data = response.data || {}

    // 3. 构建提交 payload，仅修改 status，保留其他所有数据（包括素材列表）
    const itemList = data.robotOpsPlayPlanItemList || data.itemList || []

    // 确保素材列表格式正确（复用 submitForm 中的处理逻辑）
    const submitItemList = itemList.map(item => ({
      id: item.id,
      planId: item.planId,
      assetId: item.assetId,
      playOrder: item.playOrder,
      staySeconds: item.assetType === 'image' ? item.staySeconds : null,
      transitionType: item.transitionType || 'none'
    }))

    const payload = {
      id: data.id,
      planName: data.planName,
      loopMode: data.loopMode,
      status: String(targetStatus), // 【关键】修改为目标状态
      remark: data.remark,
      robotOpsPlayPlanItemList: submitItemList,
      itemList: submitItemList
    }

    // 4. 调用更新接口
    return updatePlan(payload)
  }).then(() => {
    proxy.$modal.msgSuccess(`${actionText}成功`)
    getList() // 刷新列表以显示最新状态
  }).catch((error) => {
    // 如果是用户取消确认，不报错
    if (error !== 'cancel') {
      console.error(error)
      proxy.$modal.msgError(`${actionText}失败`)
    }
  }).finally(() => {
    loading.value = false
  })
}
/** 选择素材 */
function handleSelectAsset() {
  selectedAssets.value = []
  assetSelectOpen.value = true
  getAssetList()
}

/** 获取素材列表 */
function getAssetList() {
  assetLoading.value = true
  listMediAasset(assetQueryParams).then(response => {
    assetList.value = response.rows || []
    assetTotal.value = response.total || 0
  }).catch(() => {
    assetList.value = []
    assetTotal.value = 0
  }).finally(() => {
    assetLoading.value = false
  })
}

/** 重置素材查询 */
function resetAssetQuery() {
  assetQueryParams.pageNum = 1
  assetQueryParams.assetName = undefined
  assetQueryParams.assetType = undefined
  assetQueryParams.status = '1'
  getAssetList()
}

/** 素材选择变化 */
function handleAssetSelectionChange(selection) {
  selectedAssets.value = selection
}

/** 素材搜索 */
function handleAssetQuery() {
  assetQueryParams.pageNum = 1
  if (assetQueryParams.assetName) {
    assetQueryParams.assetName = assetQueryParams.assetName.trim()
  }
  getAssetList()
}

/** 确认选择素材 */
function confirmSelectAsset() {
  if (!selectedAssets.value.length) {
    proxy.$modal.msgWarning('请选择素材')
    return
  }
  const existsIds = robotOpsPlayPlanItemList.value.map(item => Number(item.assetId))
  let addCount = 0
  let skipCount = 0
  selectedAssets.value.forEach(asset => {
    if (existsIds.includes(Number(asset.id))) {
      skipCount++
      return
    }
    robotOpsPlayPlanItemList.value.push({
      assetId: asset.id,
      assetName: asset.assetName,
      assetType: asset.assetType,
      fileUrl: asset.fileUrl,
      thumbnailUrl: asset.thumbnailUrl,
      durationSeconds: asset.durationSeconds,
      resolution: asset.resolution,
      assetStatus: asset.status,
      playOrder: robotOpsPlayPlanItemList.value.length + 1,
      staySeconds: asset.assetType === 'image' ? 10 : null,
      transitionType: 'none'
    })
    existsIds.push(Number(asset.id))
    addCount++
  })
  refreshPlayOrder()
  nextTick(() => {
    selectedAssets.value = []
  })
  assetSelectOpen.value = false
  if (addCount > 0 && skipCount > 0) {
    proxy.$modal.msgSuccess('已添加 ' + addCount + ' 个素材，跳过 ' + skipCount + ' 个重复素材')
  } else if (addCount > 0) {
    proxy.$modal.msgSuccess('已添加 ' + addCount + ' 个素材')
  } else if (skipCount > 0) {
    proxy.$modal.msgWarning('所选素材已全部存在，请勿重复添加')
  }
}

function handleCancelSelectAsset() {
  selectedAssets.value = []
  assetSelectOpen.value = false
}

getList()
</script>

<style scoped>
.asset-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.asset-thumb {
  width: 54px;
  height: 54px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.video-thumb {
  width: 54px;
  height: 54px;
  border-radius: 6px;
  background: #f5f7fa;
  border: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 24px;
}

.video-thumb.small {
  width: 48px;
  height: 48px;
  font-size: 22px;
}

.asset-meta {
  min-width: 0;
}

.asset-name {
  font-weight: 500;
  color: #303133;
  max-width: 170px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.asset-sub {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

.asset-id {
  color: #909399;
  font-size: 12px;
}

.asset-file-info {
  color: #606266;
  font-size: 13px;
  line-height: 1.6;
}

.text-muted {
  color: #909399;
}

.asset-select-tip {
  margin-bottom: 12px;
}

.form-tip {
  width: 100%;
  margin-top: 4px;
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
}

.play-status-alert {
  margin-bottom: 12px;
}

.plan-preview {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.preview-title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.preview-sub {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  color: #909399;
  font-size: 13px;
}

.preview-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 16px;
}

.preview-stage {
  min-height: 420px;
  background: #111827;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.preview-media {
  max-width: 100%;
  max-height: 420px;
}

.preview-image {
  object-fit: contain;
}

.preview-video {
  width: 100%;
  height: 420px;
  background: #000;
}

.preview-empty {
  color: #cbd5e1;
  font-size: 14px;
}

.preview-list {
  border: 1px solid #e4e7ed;
  border-radius: 10px;
  padding: 12px;
  max-height: 420px;
  overflow-y: auto;
}

.preview-list-title {
  font-weight: 600;
  color: #303133;
  margin-bottom: 10px;
}

.preview-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border-radius: 8px;
  cursor: pointer;
}

.preview-item:hover {
  background: #f5f7fa;
}

.preview-item.active {
  background: #ecf5ff;
}

.preview-item-index {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #e4e7ed;
  color: #606266;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
}

.preview-item.active .preview-item-index {
  background: #409eff;
  color: #fff;
}

.preview-item-thumb {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
}

.preview-item-meta {
  min-width: 0;
  flex: 1;
}

.preview-item-name {
  font-size: 13px;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-item-desc {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  color: #909399;
  font-size: 12px;
}

.preview-actions {
  display: flex;
  justify-content: center;
  gap: 12px;
}

.preview-main {
  min-width: 0;
}

.preview-current-info {
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  background: #f8fafc;
}

.preview-current-name {
  font-weight: 600;
  color: #303133;
  margin-bottom: 6px;
}

.preview-current-desc {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  color: #606266;
  font-size: 13px;
}
</style>
