<template>
  <PageContainer title="模板管理">
    <el-form :inline="true" :model="listQuery" class="wo-query-form">
      <el-form-item label="模板名称">
        <el-input v-model="listQuery.templateName" clearable placeholder="请输入模板名称" class="w-input-md" />
      </el-form-item>
      <el-form-item label="模板类型">
        <el-select v-model="listQuery.templateType" clearable placeholder="全部" class="w-input-md">
          <el-option
            v-for="item in templateTypeOptions"
            :key="item.typeCode"
            :label="item.typeName"
            :value="item.typeCode"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="模板状态">
        <el-select v-model="listQuery.status" clearable placeholder="全部" class="w-input-md">
          <el-option v-for="item in templateStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="适用范围">
        <el-select v-model="listQuery.scopeType" clearable placeholder="全部" class="w-input-md">
          <el-option v-for="item in scopeTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="业务场景">
        <el-select v-model="listQuery.bizScene" clearable placeholder="全部" class="w-input-md">
          <el-option
            v-for="item in flowSceneOptions"
            :key="item.sceneCode"
            :label="item.sceneName"
            :value="item.sceneCode"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="生效状态">
        <el-select v-model="listQuery.effectiveStatus" clearable placeholder="全部" class="w-input-md">
          <el-option v-for="item in effectiveStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="水印下载">
        <el-select v-model="listQuery.watermarkEnabled" clearable placeholder="全部" class="w-input-md">
          <el-option v-for="item in watermarkFilterOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button v-if="canRead" type="primary" @click="handleSearch">查询</el-button>
      </el-form-item>
      <el-form-item>
        <el-button @click="resetListQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <QueryToolbar>
      <el-button v-if="canCreate" type="primary" @click="openCreateDrawer">上传模板</el-button>
      <el-button v-if="canRead" @click="load">刷新</el-button>
      <el-button v-if="canRead" @click="openFlowBindingDrawer">流程绑定</el-button>
    </QueryToolbar>

    <el-drawer v-model="createVisible" title="上传模板" :size="DRAWER_SIZE.lg" destroy-on-close>
      <el-form
        ref="formRef"
        :model="form"
        label-position="left"
        :label-width="LABEL_WIDTH.md"
        :rules="formRules"
      >
        <el-form-item label="模板名称" prop="templateName">
          <el-input v-model="form.templateName" placeholder="例如：会议签到表模板" />
        </el-form-item>
        <el-form-item label="模板类型" prop="templateType">
          <el-select v-model="form.templateType" class="w-input-md">
            <el-option
              v-for="item in templateTypeOptions"
              :key="item.typeCode"
              :label="item.typeName"
              :value="item.typeCode"
              :disabled="item.status !== 'ENABLED'"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="适用范围">
          <el-select v-model="form.scopeType" class="w-input-md">
            <el-option label="全部" value="ALL" />
            <el-option label="项目级" value="PROJECT" />
            <el-option label="会议级" value="MEETING" />
          </el-select>
        </el-form-item>
        <el-form-item v-if="form.scopeType === 'PROJECT'" label="项目ID">
          <el-input-number v-model="form.projectId" :min="1" />
        </el-form-item>
        <el-form-item v-if="form.scopeType === 'MEETING'" label="会议ID">
          <el-input-number v-model="form.meetingId" :min="1" />
        </el-form-item>
        <el-form-item label="业务场景">
          <el-select v-model="form.bizScene" class="w-input-md">
            <el-option
              v-for="item in flowSceneOptions"
              :key="item.sceneCode"
              :label="item.sceneName"
              :value="item.sceneCode"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="文件 ObjectKey" prop="objectKey">
          <el-input v-model="form.objectKey" readonly placeholder="上传完成后自动回填" />
        </el-form-item>
        <el-form-item label="生效开始时间">
          <el-date-picker
            v-model="form.effectiveFrom"
            type="datetime"
            value-format="YYYY-MM-DD HH:mm:ss"
            class="w-input-md"
          />
        </el-form-item>
        <el-form-item label="生效结束时间">
          <el-date-picker
            v-model="form.effectiveTo"
            type="datetime"
            value-format="YYYY-MM-DD HH:mm:ss"
            class="w-input-md"
          />
        </el-form-item>
        <el-form-item label="开启水印下载">
          <el-switch v-model="form.watermarkEnabled" />
        </el-form-item>
        <el-form-item label="下载限流/小时">
          <el-input-number v-model="form.downloadRateLimitPerHour" :min="1" :max="9999" />
        </el-form-item>
        <el-form-item label="本地文件">
          <el-upload :auto-upload="false" :show-file-list="false" :limit="1" :on-change="onCreateFileChange">
            <el-button>选择文件</el-button>
          </el-upload>
        </el-form-item>
        <el-form-item>
          <el-button v-if="canCreate" :disabled="!createFile" @click="uploadCreateFile">
            上传到 OSS 并回填 ObjectKey
          </el-button>
        </el-form-item>
        <el-form-item label="变更说明">
          <el-input v-model="form.changeLog" placeholder="可选" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createVisible = false">取消</el-button>
        <el-button v-if="canCreate" type="primary" @click="handleCreate">创建</el-button>
      </template>
    </el-drawer>

    <el-table :data="templateTypeOptions" class="mt-md" size="small" empty-text="暂无数据">
      <el-table-column prop="typeCode" label="类型编码" width="140" />
      <el-table-column prop="typeName" label="类型名称" width="180" />
      <el-table-column prop="status" label="状态" width="120" :formatter="statusFormatter" />
      <el-table-column label="操作" width="200">
        <template #default="{ row }">
          <el-button
            v-if="canPublish && row.status !== 'ENABLED'"
            size="small"
            type="success"
            @click="enableType(row.typeCode)"
          >
            启用
          </el-button>
          <el-button
            v-else-if="canPublish"
            size="small"
            type="warning"
            @click="disableType(row.typeCode)"
          >
            停用
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-table :data="rows" class="mt-md" empty-text="暂无数据">
      <el-table-column prop="templateName" label="模板名称" min-width="180" />
      <el-table-column label="模板类型" width="130">
        <template #default="{ row }">
          {{ getTemplateTypeLabel(row.templateType) }}
        </template>
      </el-table-column>
      <el-table-column label="适用范围" width="110">
        <template #default="{ row }">
          {{ getScopeTypeLabel(row.scopeType) }}
        </template>
      </el-table-column>
      <el-table-column prop="bizScene" label="业务场景" width="140" :formatter="bizSceneFormatter" />
      <el-table-column prop="currentVersionNo" label="当前版本" width="100" />
      <el-table-column prop="status" label="状态" width="110" :formatter="statusFormatter" />
      <el-table-column label="生效时间" min-width="220">
        <template #default="{ row }">
          {{ formatEffectiveTime(row) }}
        </template>
      </el-table-column>
      <el-table-column label="水印" width="90">
        <template #default="{ row }">
          {{ row.watermarkEnabled ? "开启" : "关闭" }}
        </template>
      </el-table-column>
      <el-table-column prop="downloadRateLimitPerHour" label="限流/小时" width="110" />
      <el-table-column prop="updatedAt" label="最近更新" width="180" />
      <el-table-column label="操作" min-width="420" fixed="right">
        <template #default="{ row }">
          <el-button size="small" v-if="canRead" @click="openDetailDrawer(row)">版本管理</el-button>
          <el-button
            size="small"
            type="success"
            v-if="canPublish"
            :disabled="row.status === 'ARCHIVED'"
            @click="handlePublish(row)"
          >
            发布
          </el-button>
          <el-button size="small" type="warning" v-if="canDisable" @click="handleDisable(row)">
            停用
          </el-button>
          <el-button size="small" v-if="canArchive" @click="handleArchive(row)">
            归档
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      class="mt-md"
      background
      layout="total, prev, pager, next, sizes"
      :total="totalCount"
      v-model:current-page="pageNo"
      v-model:page-size="pageSize"
      :page-sizes="[10, 20, 50, 100]"
      @size-change="load"
      @current-change="load"
    />

    <el-drawer v-model="detailVisible" title="模板管理详情" :size="DRAWER_SIZE.lg" destroy-on-close>
      <template v-if="detailRow">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="模板名称">{{ detailRow.templateName || "-" }}</el-descriptions-item>
          <el-descriptions-item label="模板状态">{{ getStatusLabel(detailRow.status) }}</el-descriptions-item>
          <el-descriptions-item label="模板类型">{{ getTemplateTypeLabel(detailRow.templateType) }}</el-descriptions-item>
          <el-descriptions-item label="业务场景">{{ getBizSceneLabel(detailRow.bizScene) }}</el-descriptions-item>
          <el-descriptions-item label="适用范围">{{ getScopeTypeLabel(detailRow.scopeType) }}</el-descriptions-item>
          <el-descriptions-item label="当前版本">V{{ detailRow.currentVersionNo || 1 }}</el-descriptions-item>
          <el-descriptions-item label="生效时间">{{ formatEffectiveTime(detailRow) }}</el-descriptions-item>
          <el-descriptions-item label="水印下载">{{ detailRow.watermarkEnabled ? "开启" : "关闭" }}</el-descriptions-item>
          <el-descriptions-item label="下载限流/小时">{{ detailRow.downloadRateLimitPerHour ?? "-" }}</el-descriptions-item>
          <el-descriptions-item label="最近更新">{{ detailRow.updatedAt || "-" }}</el-descriptions-item>
        </el-descriptions>

        <div class="mt-md flex items-center gap-sm">
          <el-button v-if="canCreate" :disabled="detailRow.status === 'ARCHIVED'" @click="openNewVersion(detailRow)">
            新增版本
          </el-button>
          <el-button v-if="canRead" @click="openVersionDiff(detailRow)">版本差异</el-button>
          <el-button v-if="canFlowLink" @click="openFlowBindingDrawer">流程绑定</el-button>
        </div>

        <el-descriptions v-if="currentVersionDetail" class="mt-md" :column="2" border>
          <el-descriptions-item label="当前版本 ObjectKey">
            {{ currentVersionDetail.objectKey || detailRow.currentObjectKey || "-" }}
          </el-descriptions-item>
          <el-descriptions-item label="当前版本状态">
            {{ getStatusLabel(currentVersionDetail.versionStatus) }}
          </el-descriptions-item>
          <el-descriptions-item label="当前版本变更说明">
            {{ currentVersionDetail.changeLog || "-" }}
          </el-descriptions-item>
          <el-descriptions-item label="当前版本创建时间">
            {{ currentVersionDetail.createdAt || "-" }}
          </el-descriptions-item>
        </el-descriptions>

        <el-tabs class="mt-md">
          <el-tab-pane label="版本历史">
            <el-table :data="detailVersionRows" empty-text="暂无版本记录">
              <el-table-column prop="versionNo" label="版本号" width="90" />
              <el-table-column prop="versionStatus" label="状态" width="100" :formatter="statusFormatter" />
              <el-table-column label="当前生效" width="100">
                <template #default="{ row }">
                  {{ row.effective ? "是" : "否" }}
                </template>
              </el-table-column>
              <el-table-column prop="objectKey" label="ObjectKey" min-width="220" show-overflow-tooltip />
              <el-table-column prop="changeLog" label="变更说明" min-width="180" />
              <el-table-column prop="rollbackReason" label="回滚原因" min-width="180" />
              <el-table-column prop="createdAt" label="创建时间" width="180" />
              <el-table-column label="操作" width="220">
                <template #default="{ row }">
                  <el-button size="small" v-if="canRead" @click="openVersionDiff(detailRow, row.versionNo)">
                    对比当前
                  </el-button>
                  <el-button
                    size="small"
                    type="primary"
                    v-if="canRollback"
                    :disabled="detailRow.status === 'ARCHIVED' || Number(row.versionNo) === Number(detailRow.currentVersionNo)"
                    @click="openRollback(detailRow, row.versionNo)"
                  >
                    回滚
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>

          <el-tab-pane label="流程绑定">
            <el-table :data="detailFlowBindings" empty-text="当前模板未绑定流程">
              <el-table-column prop="sceneName" label="流程场景" min-width="160" />
              <el-table-column label="影响说明" min-width="220">
                <template #default="{ row }">
                  {{ getSceneImpactDescription(row.sceneCode) }}
                </template>
              </el-table-column>
              <el-table-column prop="versionNo" label="绑定版本" width="120" />
            </el-table>
          </el-tab-pane>
        </el-tabs>
      </template>
    </el-drawer>

    <el-drawer v-model="flowBindingVisible" title="流程绑定" :size="DRAWER_SIZE.lg" destroy-on-close>
      <div class="text-secondary mb-sm">
        这里只展示可用于绑定的已发布模板，要求模板场景一致且当前处于生效期内。
      </div>
      <el-table :data="flowLinks" empty-text="暂无数据">
        <el-table-column prop="sceneName" label="流程场景" width="180" />
        <el-table-column prop="templateName" label="当前绑定模板" min-width="180" />
        <el-table-column prop="templateStatus" label="模板状态" width="120" :formatter="statusFormatter" />
        <el-table-column prop="versionNo" label="版本" width="100" />
        <el-table-column label="影响说明" min-width="180">
          <template #default="{ row }">
            {{ getSceneImpactDescription(row.sceneCode) }}
          </template>
        </el-table-column>
        <el-table-column label="绑定新模板" min-width="320">
          <template #default="{ row }">
            <el-select v-model="bindSelection[row.sceneCode]" placeholder="选择已发布模板" class="w-input-lg">
              <el-option
                v-for="item in publishedTemplatesForScene(row.sceneCode)"
                :key="item.id"
                :label="`${item.templateName}(#${item.id})`"
                :value="item.id"
              />
            </el-select>
            <el-button
              size="small"
              type="primary"
              class="ml-sm"
              v-if="canFlowLink"
              @click="handleBindFlow(row)"
            >
              绑定
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-drawer>

    <el-dialog v-model="rollbackDialogVisible" title="版本回滚" :width="DIALOG_WIDTH.md">
      <el-table :data="versionRows">
        <el-table-column prop="versionNo" label="版本号" width="90" />
        <el-table-column prop="versionStatus" label="状态" width="100" :formatter="statusFormatter" />
        <el-table-column prop="changeLog" label="变更说明" />
        <el-table-column prop="rollbackReason" label="最近回滚原因" min-width="180" />
        <el-table-column prop="createdAt" label="创建时间" width="190" />
        <el-table-column label="操作" width="120">
          <template #default="{ row }">
            <el-button size="small" type="primary" @click="handleRollback(row.versionNo)">回滚到此</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="mt-md">
        <div class="text-secondary mb-xs">回滚原因</div>
        <el-input
          v-model="rollbackReason"
          type="textarea"
          :rows="3"
          maxlength="200"
          show-word-limit
          placeholder="请输入本次回滚原因"
        />
      </div>
      <template #footer>
        <el-button @click="rollbackDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="newVersionDialogVisible" title="新增模板版本" :width="DIALOG_WIDTH.sm">
      <el-form
        ref="newVersionFormRef"
        :model="newVersionForm"
        label-position="left"
        :label-width="LABEL_WIDTH.md"
        :rules="newVersionFormRules"
      >
        <el-form-item label="文件 ObjectKey" prop="objectKey">
          <el-input v-model="newVersionForm.objectKey" placeholder="template/xxx.docx" />
        </el-form-item>
        <el-form-item label="本地文件">
          <el-upload :auto-upload="false" :show-file-list="false" :limit="1" :on-change="onNewVersionFileChange">
            <el-button>选择文件</el-button>
          </el-upload>
        </el-form-item>
        <el-form-item>
          <el-button :disabled="!newVersionFile" @click="uploadNewVersionFile">上传到 OSS 并回填 ObjectKey</el-button>
        </el-form-item>
        <el-form-item label="变更说明">
          <el-input v-model="newVersionForm.changeLog" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="newVersionDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitNewVersion">提交</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="diffDialogVisible" title="版本差异" :width="DIALOG_WIDTH.md">
      <el-form :inline="true">
        <el-form-item label="左版本">
          <el-input-number v-model="diffForm.leftVersionNo" :min="1" />
        </el-form-item>
        <el-form-item label="右版本">
          <el-input-number v-model="diffForm.rightVersionNo" :min="1" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="loadVersionDiff">查询差异</el-button>
        </el-form-item>
      </el-form>
      <el-descriptions :column="1" border>
        <el-descriptions-item label="ObjectKey 是否变更">{{ diffData.objectKeyChanged ? "是" : "否" }}</el-descriptions-item>
        <el-descriptions-item label="状态是否变更">{{ diffData.statusChanged ? "是" : "否" }}</el-descriptions-item>
        <el-descriptions-item label="变更说明是否变更">{{ diffData.changeLogChanged ? "是" : "否" }}</el-descriptions-item>
        <el-descriptions-item label="左版本 ObjectKey">{{ diffData.leftObjectKey || "-" }}</el-descriptions-item>
        <el-descriptions-item label="右版本 ObjectKey">{{ diffData.rightObjectKey || "-" }}</el-descriptions-item>
        <el-descriptions-item label="左版本变更说明">{{ diffData.leftChangeLog || "-" }}</el-descriptions-item>
        <el-descriptions-item label="右版本变更说明">{{ diffData.rightChangeLog || "-" }}</el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <el-button @click="diffDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </PageContainer>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
import PageContainer from "../../components/PageContainer.vue";
import QueryToolbar from "../../components/QueryToolbar.vue";
import {
  addTemplateVersion,
  archiveTemplate,
  bindTemplateFlowLink,
  createTemplate,
  disableTemplate,
  disableTemplateTypeOption,
  enableTemplateTypeOption,
  fetchPublishedTemplateOptions,
  fetchTemplateFlowLinks,
  fetchTemplateFlowSceneOptions,
  fetchTemplateTypeOptions,
  fetchTemplateUploadSign,
  fetchTemplateVersionDiff,
  fetchTemplateVersions,
  fetchTemplates,
  publishTemplate,
  rollbackTemplate,
} from "../../api/modules";
import { PERMS } from "../../constants/permissions";
import { DRAWER_SIZE, DIALOG_WIDTH, LABEL_WIDTH } from "../../constants/ui";
import { useAuthStore } from "../../stores/auth";

type TemplateTypeCode = "AGENDA" | "SIGN_IN" | "INVITATION" | "OTHER";
type BizSceneCode = "MEETING_RECOMMEND" | "AUDIT_NOTIFY" | "SETTLEMENT";
type ScopeTypeCode = "ALL" | "PROJECT" | "MEETING";

const STATUS_LABELS: Record<string, string> = {
  ENABLED: "启用",
  DISABLED: "停用",
  DRAFT: "草稿",
  PUBLISHED: "已发布",
  ARCHIVED: "已归档",
};

const BIZ_SCENE_LABELS: Record<string, string> = {
  MEETING_RECOMMEND: "会议推荐",
  AUDIT_NOTIFY: "审核通知",
  SETTLEMENT: "结算",
};

const authStore = useAuthStore();

const canRead = computed(() => authStore.hasPermission(PERMS.template.read));
const canCreate = computed(() => authStore.hasPermission(PERMS.template.create));
const canPublish = computed(() => authStore.hasPermission(PERMS.template.publish));
const canDisable = computed(() => authStore.hasPermission(PERMS.template.disable));
const canArchive = computed(() => authStore.hasPermission(PERMS.template.archive));
const canRollback = computed(() => authStore.hasPermission(PERMS.template.rollback));
const canFlowLink = computed(() => authStore.hasPermission(PERMS.template.flowLink));

const rows = ref<any[]>([]);
const pageNo = ref(1);
const pageSize = ref(20);
const totalCount = ref(0);

const createVisible = ref(false);
const detailVisible = ref(false);
const flowBindingVisible = ref(false);
const rollbackDialogVisible = ref(false);
const newVersionDialogVisible = ref(false);
const diffDialogVisible = ref(false);

const createFile = ref<File | null>(null);
const newVersionFile = ref<File | null>(null);
const selectedTemplateId = ref<number | null>(null);
const selectedTemplateType = ref<TemplateTypeCode>("OTHER");
const rollbackReason = ref("");

const detailRow = ref<any | null>(null);
const detailVersionRows = ref<any[]>([]);
const versionRows = ref<any[]>([]);
const flowLinks = ref<any[]>([]);
const publishedTemplateOptions = ref<any[]>([]);
const bindSelection = ref<Record<string, number | undefined>>({});

const templateTypeOptions = ref<Array<{ typeCode: TemplateTypeCode; typeName: string; status: "ENABLED" | "DISABLED" }>>([]);
const flowSceneOptions = ref<Array<{ sceneCode: BizSceneCode; sceneName: string }>>([]);

const templateStatusOptions = [
  { label: "草稿", value: "DRAFT" },
  { label: "已发布", value: "PUBLISHED" },
  { label: "已停用", value: "DISABLED" },
  { label: "已归档", value: "ARCHIVED" },
];

const scopeTypeOptions = [
  { label: "全部", value: "ALL" },
  { label: "项目级", value: "PROJECT" },
  { label: "会议级", value: "MEETING" },
];

const effectiveStatusOptions = [
  { label: "生效中", value: "ACTIVE" },
  { label: "未生效", value: "UPCOMING" },
  { label: "已过期", value: "EXPIRED" },
];

const watermarkFilterOptions = [
  { label: "开启", value: "true" },
  { label: "关闭", value: "false" },
];

const listQuery = ref({
  templateName: "",
  templateType: "" as TemplateTypeCode | "",
  status: "",
  scopeType: "" as ScopeTypeCode | "",
  bizScene: "" as BizSceneCode | "",
  effectiveStatus: "",
  watermarkEnabled: "" as "" | "true" | "false",
});

const form = ref({
  templateName: "",
  templateType: "AGENDA" as TemplateTypeCode,
  scopeType: "ALL" as ScopeTypeCode,
  projectId: undefined as number | undefined,
  meetingId: undefined as number | undefined,
  bizScene: "MEETING_RECOMMEND" as BizSceneCode,
  objectKey: "",
  changeLog: "",
  effectiveFrom: "",
  effectiveTo: "",
  watermarkEnabled: false,
  downloadRateLimitPerHour: 100,
});

const newVersionForm = ref({
  objectKey: "",
  changeLog: "",
});

const diffForm = ref({
  leftVersionNo: 1,
  rightVersionNo: 1,
});

const diffData = ref<any>({
  objectKeyChanged: false,
  statusChanged: false,
  changeLogChanged: false,
  leftObjectKey: "",
  rightObjectKey: "",
  leftChangeLog: "",
  rightChangeLog: "",
});

const formRef = ref<FormInstance>();
const newVersionFormRef = ref<FormInstance>();

const formRules = ref<FormRules>({
  templateName: [{ required: true, message: "请输入模板名称", trigger: "blur" }],
  templateType: [{ required: true, message: "请选择模板类型", trigger: "change" }],
  objectKey: [{ required: true, message: "请先上传模板文件", trigger: "blur" }],
});

const newVersionFormRules = ref<FormRules>({
  objectKey: [{ required: true, message: "请输入文件 ObjectKey", trigger: "blur" }],
});

const getStatusLabel = (value?: unknown) => {
  const key = String(value ?? "").trim();
  return STATUS_LABELS[key] || key || "-";
};

const getBizSceneLabel = (value?: unknown) => {
  const key = String(value ?? "").trim();
  return BIZ_SCENE_LABELS[key] || key || "-";
};

const statusFormatter = (_row: any, _column: any, value: unknown) => getStatusLabel(value);
const bizSceneFormatter = (_row: any, _column: any, value: unknown) => getBizSceneLabel(value);

const detailFlowBindings = computed(() => {
  if (!detailRow.value?.id) {
    return [];
  }
  return flowLinks.value.filter((item) => Number(item.templateId) === Number(detailRow.value.id));
});

const currentVersionDetail = computed(() => {
  if (!detailVersionRows.value.length) {
    return null;
  }
  const currentVersionNo = Number(detailRow.value?.currentVersionNo || 0);
  return (
    detailVersionRows.value.find((item) => Number(item.versionNo) === currentVersionNo) ||
    detailVersionRows.value.find((item) => Boolean(item.effective)) ||
    detailVersionRows.value[0]
  );
});

const getTemplateTypeLabel = (code: string) =>
  templateTypeOptions.value.find((item) => item.typeCode === code)?.typeName || code || "-";

const getScopeTypeLabel = (code: ScopeTypeCode | string) =>
  scopeTypeOptions.find((item) => item.value === code)?.label || code || "-";

const formatEffectiveTime = (row: any) => {
  const start = String(row?.effectiveFrom || "").trim();
  const end = String(row?.effectiveTo || "").trim();
  if (!start && !end) {
    return "长期有效";
  }
  return `${start || "未设置"} ~ ${end || "未设置"}`;
};

const buildListParams = () => ({
  templateName: listQuery.value.templateName || undefined,
  templateType: listQuery.value.templateType || undefined,
  status: listQuery.value.status || undefined,
  scopeType: listQuery.value.scopeType || undefined,
  bizScene: listQuery.value.bizScene || undefined,
  effectiveStatus: listQuery.value.effectiveStatus || undefined,
  watermarkEnabled: listQuery.value.watermarkEnabled ? listQuery.value.watermarkEnabled === "true" : undefined,
  pageNo: pageNo.value,
  pageSize: pageSize.value,
});

const buildTemplateName = (row: any) => row?.templateName || `模板#${row?.id ?? "-"}`;

const confirmAction = async (message: string, title: string, type: "warning" | "info" | "success" = "warning") => {
  try {
    await ElMessageBox.confirm(message, title, {
      type,
      confirmButtonText: "确定",
      cancelButtonText: "取消",
    });
    return true;
  } catch {
    return false;
  }
};

const publishedTemplatesForScene = (sceneCode: string) =>
  publishedTemplateOptions.value.filter((item) => item.bizScene === sceneCode);

const findFlowBindingsByTemplateId = (templateId: number) =>
  flowLinks.value.filter((item) => Number(item.templateId) === Number(templateId));

const findPublishedTemplateOption = (templateId: number) =>
  publishedTemplateOptions.value.find((item) => Number(item.id) === Number(templateId));

const getSceneImpactDescription = (sceneCode: string) => {
  if (sceneCode === "AUDIT_NOTIFY") {
    return "绑定后将用于审核通知文档生成。";
  }
  if (sceneCode === "SETTLEMENT") {
    return "绑定后将用于结算材料生成。";
  }
  return "绑定后将用于会议推荐模板生成。";
};

const resetCreateForm = () => {
  form.value = {
    templateName: "",
    templateType: "AGENDA",
    scopeType: "ALL",
    projectId: undefined,
    meetingId: undefined,
    bizScene: "MEETING_RECOMMEND",
    objectKey: "",
    changeLog: "",
    effectiveFrom: "",
    effectiveTo: "",
    watermarkEnabled: false,
    downloadRateLimitPerHour: 100,
  };
};

const openCreateDrawer = () => {
  resetCreateForm();
  createFile.value = null;
  createVisible.value = true;
};

const openFlowBindingDrawer = async () => {
  if (!canRead.value) {
    return;
  }
  flowBindingVisible.value = true;
  await Promise.all([loadFlowLinks(), loadPublishedTemplates()]);
};

const refreshDetailData = async () => {
  if (!detailRow.value?.id || !canRead.value) {
    detailVersionRows.value = [];
    return;
  }
  const versionsResp = await fetchTemplateVersions(detailRow.value.id);
  detailVersionRows.value = versionsResp?.data || [];
};

const openDetailDrawer = async (row: any) => {
  detailRow.value = { ...row };
  detailVisible.value = true;
  await refreshDetailData();
};

const loadPublishedTemplates = async () => {
  if (!canRead.value) {
    publishedTemplateOptions.value = [];
    return;
  }
  const resp = await fetchPublishedTemplateOptions();
  publishedTemplateOptions.value = resp?.data || [];
};

const loadFlowLinks = async () => {
  if (!canRead.value) {
    flowLinks.value = [];
    bindSelection.value = {};
    return;
  }
  const resp = await fetchTemplateFlowLinks();
  flowLinks.value = resp?.data || [];
  bindSelection.value = flowLinks.value.reduce((acc, item) => {
    acc[item.sceneCode] = item.templateId ? Number(item.templateId) : undefined;
    return acc;
  }, {} as Record<string, number | undefined>);
};

const loadTypeOptions = async () => {
  if (!canRead.value) {
    templateTypeOptions.value = [];
    return;
  }
  const resp = await fetchTemplateTypeOptions();
  templateTypeOptions.value = resp?.data || [];
  const enabled = templateTypeOptions.value.filter((item) => item.status === "ENABLED");
  if (enabled.length > 0 && !enabled.some((item) => item.typeCode === form.value.templateType)) {
    form.value.templateType = enabled[0].typeCode;
  }
};

const loadFlowSceneOptions = async () => {
  if (!canRead.value) {
    flowSceneOptions.value = [];
    return;
  }
  const resp = await fetchTemplateFlowSceneOptions();
  flowSceneOptions.value = resp?.data || [];
};

const load = async () => {
  if (!canRead.value) {
    rows.value = [];
    totalCount.value = 0;
    return;
  }
  const resp = await fetchTemplates(buildListParams());
  rows.value = resp?.data?.list || [];
  totalCount.value = Number(resp?.data?.total || 0);
  await Promise.all([loadFlowLinks(), loadPublishedTemplates()]);
  if (detailRow.value?.id) {
    const latest = rows.value.find((item) => Number(item.id) === Number(detailRow.value.id));
    if (latest) {
      detailRow.value = { ...latest };
    }
  }
};

const putToSignedUrl = async (url: string, file: File, contentType: string) => {
  const result = await fetch(url, {
    method: "PUT",
    headers: {
      "Content-Type": contentType || "application/octet-stream",
    },
    body: file,
  });
  if (!result.ok) {
    throw new Error(`Upload failed: ${result.status}`);
  }
};

const onCreateFileChange = (uploadFile: any) => {
  createFile.value = (uploadFile?.raw as File) || null;
};

const uploadCreateFile = async () => {
  if (!createFile.value) {
    ElMessage.warning("请先选择文件");
    return;
  }
  const resp = await fetchTemplateUploadSign({
    fileName: createFile.value.name,
    contentType: createFile.value.type,
    templateType: form.value.templateType,
  });
  const uploadUrl = resp?.data?.uploadUrl;
  const objectKey = resp?.data?.objectKey;
  const contentType = resp?.data?.contentType || createFile.value.type || "application/octet-stream";
  if (!uploadUrl || !objectKey) {
    ElMessage.error("获取上传签名失败");
    return;
  }
  await putToSignedUrl(uploadUrl, createFile.value, contentType);
  form.value.objectKey = objectKey;
  ElMessage.success("文件已上传并回填 ObjectKey");
};

const handleCreate = async () => {
  if (!formRef.value) {
    return;
  }
  const valid = await formRef.value.validate().catch(() => false);
  if (!valid) {
    return;
  }
  if (form.value.scopeType === "PROJECT" && !form.value.projectId) {
    ElMessage.warning("项目级模板需要填写项目ID");
    return;
  }
  if (form.value.scopeType === "MEETING" && !form.value.meetingId) {
    ElMessage.warning("会议级模板需要填写会议ID");
    return;
  }
  if (form.value.effectiveFrom && form.value.effectiveTo && form.value.effectiveFrom > form.value.effectiveTo) {
    ElMessage.warning("生效开始时间不能晚于生效结束时间");
    return;
  }
  await createTemplate({
    templateName: form.value.templateName,
    templateType: form.value.templateType,
    scopeType: form.value.scopeType,
    projectId: form.value.projectId,
    meetingId: form.value.meetingId,
    bizScene: form.value.bizScene,
    objectKey: form.value.objectKey,
    changeLog: form.value.changeLog,
    effectiveFrom: form.value.effectiveFrom || undefined,
    effectiveTo: form.value.effectiveTo || undefined,
    watermarkEnabled: form.value.watermarkEnabled,
    downloadRateLimitPerHour: form.value.downloadRateLimitPerHour,
  });
  ElMessage.success("模板创建成功");
  createVisible.value = false;
  await load();
};

const enableType = async (typeCode: string) => {
  await enableTemplateTypeOption(typeCode);
  ElMessage.success(`模板类型 ${typeCode} 已启用`);
  await loadTypeOptions();
};

const disableType = async (typeCode: string) => {
  await disableTemplateTypeOption(typeCode);
  ElMessage.success(`模板类型 ${typeCode} 已停用`);
  await loadTypeOptions();
};

const handlePublish = async (row: any) => {
  const confirmed = await confirmAction(
    `确认发布「${buildTemplateName(row)}」？发布后当前版本将作为租户域内生效模板。`,
    "发布模板",
  );
  if (!confirmed) {
    return;
  }
  await publishTemplate(row.id);
  ElMessage.success("模板已发布");
  await load();
  if (detailVisible.value && Number(detailRow.value?.id) === Number(row.id)) {
    await refreshDetailData();
  }
};

const handleDisable = async (row: any) => {
  const bindings = findFlowBindingsByTemplateId(row.id);
  const bindingTip = bindings.length
    ? ` 当前已绑定场景：${bindings.map((item) => item.sceneName || item.sceneCode).join("、")}。`
    : "";
  const confirmed = await confirmAction(
    `确认停用「${buildTemplateName(row)}」？停用后模板将无法继续下载或被业务流程使用。${bindingTip}`,
    "停用模板",
  );
  if (!confirmed) {
    return;
  }
  await disableTemplate(row.id);
  ElMessage.success("模板已停用");
  await load();
  if (detailVisible.value && Number(detailRow.value?.id) === Number(row.id)) {
    await refreshDetailData();
  }
};

const handleArchive = async (row: any) => {
  const bindings = findFlowBindingsByTemplateId(row.id);
  const bindingTip = bindings.length
    ? ` 当前已绑定场景：${bindings.map((item) => item.sceneName || item.sceneCode).join("、")}，如需归档建议先完成替换。`
    : "";
  const confirmed = await confirmAction(
    `确认归档「${buildTemplateName(row)}」？归档后不可再发布、不可新增版本，也不可回滚。${bindingTip}`,
    "归档模板",
  );
  if (!confirmed) {
    return;
  }
  await archiveTemplate(row.id);
  ElMessage.success("模板已归档");
  await load();
  if (detailVisible.value && Number(detailRow.value?.id) === Number(row.id)) {
    await refreshDetailData();
  }
};

const openRollback = async (row: any, targetVersionNo?: number) => {
  selectedTemplateId.value = row.id;
  rollbackReason.value = "";
  const resp = await fetchTemplateVersions(row.id);
  const allVersions = resp?.data || [];
  versionRows.value = targetVersionNo
    ? allVersions.filter((item: any) => Number(item.versionNo) === Number(targetVersionNo))
    : allVersions;
  rollbackDialogVisible.value = true;
};

const handleRollback = async (versionNo: number) => {
  if (!selectedTemplateId.value) {
    return;
  }
  if (!rollbackReason.value.trim()) {
    ElMessage.warning("请先填写回滚原因");
    return;
  }
  const confirmed = await confirmAction(
    `确认回滚到 V${versionNo}？\n回滚原因：${rollbackReason.value.trim()}`,
    "回滚模板",
  );
  if (!confirmed) {
    return;
  }
  await rollbackTemplate(selectedTemplateId.value, {
    versionNo,
    rollbackReason: rollbackReason.value.trim(),
  });
  ElMessage.success(`已回滚到版本 V${versionNo}`);
  rollbackDialogVisible.value = false;
  await load();
  if (detailVisible.value && Number(detailRow.value?.id) === Number(selectedTemplateId.value)) {
    await refreshDetailData();
  }
};

const handleBindFlow = async (row: any) => {
  const sceneCode = row.sceneCode;
  const templateId = bindSelection.value[sceneCode];
  if (!templateId) {
    ElMessage.warning("请先选择模板");
    return;
  }
  const targetTemplate = findPublishedTemplateOption(templateId);
  const currentTemplateName = row.templateName || "未绑定";
  const nextTemplateName = targetTemplate?.templateName || `模板#${templateId}`;
  const confirmed = await confirmAction(
    `确认将场景「${row.sceneName || sceneCode}」从「${currentTemplateName}」切换为「${nextTemplateName}」？${getSceneImpactDescription(sceneCode)}`,
    "绑定流程模板",
  );
  if (!confirmed) {
    return;
  }
  await bindTemplateFlowLink(sceneCode, { templateId });
  ElMessage.success("流程绑定已更新");
  await loadFlowLinks();
};

const openVersionDiff = async (row: any, leftVersionNo?: number) => {
  selectedTemplateId.value = row.id;
  const current = Number(row.currentVersionNo || 1);
  diffForm.value.leftVersionNo = leftVersionNo || (current > 1 ? current - 1 : 1);
  diffForm.value.rightVersionNo = current;
  diffData.value = {
    objectKeyChanged: false,
    statusChanged: false,
    changeLogChanged: false,
    leftObjectKey: "",
    rightObjectKey: "",
    leftChangeLog: "",
    rightChangeLog: "",
  };
  diffDialogVisible.value = true;
  await loadVersionDiff();
};

const loadVersionDiff = async () => {
  if (!selectedTemplateId.value) {
    return;
  }
  const resp = await fetchTemplateVersionDiff(selectedTemplateId.value, {
    leftVersionNo: diffForm.value.leftVersionNo,
    rightVersionNo: diffForm.value.rightVersionNo,
  });
  diffData.value = resp?.data || diffData.value;
};

const openNewVersion = (row: any) => {
  selectedTemplateId.value = row.id;
  selectedTemplateType.value = (row?.templateType || "OTHER") as TemplateTypeCode;
  newVersionForm.value = {
    objectKey: "",
    changeLog: "",
  };
  newVersionFile.value = null;
  newVersionDialogVisible.value = true;
};

const onNewVersionFileChange = (uploadFile: any) => {
  newVersionFile.value = (uploadFile?.raw as File) || null;
};

const uploadNewVersionFile = async () => {
  if (!newVersionFile.value) {
    ElMessage.warning("请先选择文件");
    return;
  }
  const resp = await fetchTemplateUploadSign({
    fileName: newVersionFile.value.name,
    contentType: newVersionFile.value.type,
    templateType: selectedTemplateType.value,
  });
  const uploadUrl = resp?.data?.uploadUrl;
  const objectKey = resp?.data?.objectKey;
  const contentType = resp?.data?.contentType || newVersionFile.value.type || "application/octet-stream";
  if (!uploadUrl || !objectKey) {
    ElMessage.error("获取上传签名失败");
    return;
  }
  await putToSignedUrl(uploadUrl, newVersionFile.value, contentType);
  newVersionForm.value.objectKey = objectKey;
  ElMessage.success("版本文件已上传");
};

const submitNewVersion = async () => {
  if (!selectedTemplateId.value || !newVersionFormRef.value) {
    return;
  }
  const valid = await newVersionFormRef.value.validate().catch(() => false);
  if (!valid) {
    return;
  }
  await addTemplateVersion(selectedTemplateId.value, newVersionForm.value);
  ElMessage.success("已新增版本，模板状态已回到草稿");
  newVersionDialogVisible.value = false;
  await load();
  if (detailVisible.value && Number(detailRow.value?.id) === Number(selectedTemplateId.value)) {
    await refreshDetailData();
  }
};

const handleSearch = async () => {
  pageNo.value = 1;
  await load();
};

const resetListQuery = async () => {
  listQuery.value = {
    templateName: "",
    templateType: "",
    status: "",
    scopeType: "",
    bizScene: "",
    effectiveStatus: "",
    watermarkEnabled: "",
  };
  pageNo.value = 1;
  pageSize.value = 20;
  await load();
};

onMounted(async () => {
  await loadFlowSceneOptions();
  await loadTypeOptions();
  await load();
});
</script>
