<template>
  <div v-loading="loading" class="release-workspace">
    <div class="model-toolbar">
      <el-alert type="info" :closable="false" show-icon title="发布时模型制品与参数快照成对生效，生产配置不能原位修改。" />
      <span class="filter-spacer"></span>
      <el-button :icon="Document" @click="openAudit">审计记录</el-button>
      <el-button type="primary" :icon="Promotion" @click="openCreateRelease">申请发布</el-button>
    </div>

    <section class="release-overview-strip">
      <div><span>当前生产版本</span><strong>{{ productionRelease?.model_version || group.production_version || "-" }}</strong><small>{{ productionRelease?.parameter_profile_name || "生产参数快照" }}</small></div>
      <div><span>当前灰度</span><strong>{{ grayReleaseRecord ? `${grayReleaseRecord.gray_percent}%` : "无" }}</strong><small>{{ grayReleaseRecord?.model_version || "没有进行中的灰度" }}</small></div>
      <div><span>待审批申请</span><strong>{{ releases.filter((item) => item.status === "requested").length }}</strong><small>需要发布审批人处理</small></div>
      <div><span>发布保护</span><strong>双快照</strong><small>模型哈希与参数修订</small></div>
    </section>

    <el-card class="workspace-card" shadow="never">
      <el-table :data="releases" empty-text="暂无发布记录">
        <el-table-column label="发布单" min-width="190"><template #default="scope"><span class="entity-id">{{ scope.row.release_no }}</span><small class="cell-subtext">{{ formatDateTime(scope.row.created_at) }}</small></template></el-table-column>
        <el-table-column label="模型版本" min-width="140"><template #default="scope"><strong>{{ scope.row.model_version }}</strong><small class="cell-subtext">{{ scope.row.model_version_name }}</small></template></el-table-column>
        <el-table-column label="参数快照" min-width="150"><template #default="scope">{{ scope.row.parameter_profile_name }}<small class="cell-subtext">r{{ scope.row.parameter_revision }}</small></template></el-table-column>
        <el-table-column label="评估依据" min-width="145"><template #default="scope">{{ scope.row.evaluation_task_no || "生产基线" }}</template></el-table-column>
        <el-table-column label="状态" width="105"><template #default="scope"><el-tag :type="statusTagType(scope.row.status)" effect="plain">{{ releaseStatusLabel(scope.row.status) }}</el-tag></template></el-table-column>
        <el-table-column label="灰度" width="145"><template #default="scope"><el-progress :percentage="Number(scope.row.gray_percent)" :stroke-width="8" /></template></el-table-column>
        <el-table-column label="申请与审批" min-width="150"><template #default="scope">{{ scope.row.applicant }}<small class="cell-subtext">{{ scope.row.approver || "待审批" }}</small></template></el-table-column>
        <el-table-column label="操作" width="230" fixed="right">
          <template #default="scope"><div class="list-actions">
            <el-button v-if="scope.row.status === 'requested'" link type="success" @click="approve(scope.row)">批准</el-button>
            <el-button v-if="scope.row.status === 'requested'" link type="danger" @click="reject(scope.row)">驳回</el-button>
            <el-button v-if="['approved','gray'].includes(scope.row.status)" link type="warning" @click="openGray(scope.row)">灰度</el-button>
            <el-button v-if="['approved','gray'].includes(scope.row.status)" link type="primary" @click="promote(scope.row)">转生产</el-button>
            <el-button v-if="['production','gray'].includes(scope.row.status) && scope.row.rollback_version_id" link type="danger" @click="rollback(scope.row)">回滚</el-button>
          </div></template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-timeline class="model-release-timeline">
      <el-timeline-item v-for="release in releases.slice(0, 8)" :key="release.id" :timestamp="formatDateTime(release.updated_at)" placement="top" :type="release.status === 'production' ? 'success' : release.status === 'rejected' ? 'danger' : 'primary'">
        <strong>{{ release.release_no }} · {{ releaseStatusLabel(release.status) }}</strong>
        <p>{{ release.model_version }} 与 {{ release.parameter_profile_name }} r{{ release.parameter_revision }}，灰度比例 {{ release.gray_percent }}%</p>
      </el-timeline-item>
    </el-timeline>

    <el-dialog v-model="createDialog" title="申请模型发布" width="600px">
      <el-form label-position="top">
        <el-form-item label="候选模型版本"><el-select v-model="createForm.model_version_id" @change="selectReleaseVersion"><el-option v-for="version in candidateVersions" :key="version.id" :label="`${version.version} · ${version.display_name}`" :value="version.id" /></el-select></el-form-item>
        <el-form-item label="生产参数快照"><el-select v-model="createForm.parameter_profile_id"><el-option v-for="profile in releaseProfiles" :key="profile.id" :label="`${profile.name} r${profile.revision}`" :value="profile.id" /></el-select></el-form-item>
        <el-form-item label="评估依据"><el-select v-model="createForm.evaluation_task_id" clearable><el-option v-for="test in completedTests" :key="String(test.id)" :label="`${test.task_no} · ${test.name}`" :value="test.id" /></el-select></el-form-item>
        <el-form-item label="初始灰度范围"><el-select v-model="createForm.strategy_type"><el-option label="按流量比例" value="traffic" /><el-option label="按线路区段" value="line" /><el-option label="按任务标签" value="task_tag" /></el-select></el-form-item>
        <el-form-item label="申请说明"><el-input v-model="createForm.comment" type="textarea" :rows="3" maxlength="300" show-word-limit /></el-form-item>
      </el-form>
      <template #footer><el-button @click="createDialog = false">取消</el-button><el-button type="primary" :loading="saving" @click="submitRelease">提交申请</el-button></template>
    </el-dialog>

    <el-dialog v-model="grayDialog" title="调整灰度策略" width="520px">
      <el-form label-position="top">
        <el-form-item label="灰度比例"><el-slider v-model="grayPercent" :min="1" :max="99" show-input /></el-form-item>
        <el-form-item label="灰度范围"><el-select v-model="grayStrategy"><el-option label="全线路按流量" value="traffic" /><el-option label="京广线指定区段" value="line-jingguang" /><el-option label="高优先级任务" value="priority-high" /></el-select></el-form-item>
      </el-form>
      <template #footer><el-button @click="grayDialog = false">取消</el-button><el-button type="primary" :loading="saving" @click="submitGray">应用灰度</el-button></template>
    </el-dialog>

    <el-drawer v-model="auditOpen" title="模型治理审计" size="min(720px, 92vw)">
      <el-timeline class="audit-timeline-wide"><el-timeline-item v-for="log in auditLogs" :key="String(log.id)" :timestamp="formatDateTime(log.created_at)" placement="top"><strong>{{ actionLabel(String(log.action)) }}</strong><p>{{ log.operator_name }} · {{ log.entity_type }} / {{ log.entity_id }}</p><small>{{ log.reason || "-" }}</small></el-timeline-item></el-timeline>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Document, Promotion } from "@element-plus/icons-vue";
import {
  createModelRelease, decideModelRelease, modelAuditLogs, modelParameterProfiles, modelReleases,
  modelTests, rollbackModelRelease, updateModelReleaseGray
} from "../../services/api";
import { formatDateTime, type JsonMap, type ModelGroup, type ModelRelease, type ModelVersion, type ParameterProfile, releaseStatusLabel, statusTagType } from "../../types/model-management";

const props = defineProps<{ group: ModelGroup; versions: ModelVersion[] }>();
const loading = ref(false);
const saving = ref(false);
const releases = ref<ModelRelease[]>([]);
const profiles = ref<ParameterProfile[]>([]);
const tests = ref<JsonMap[]>([]);
const auditLogs = ref<JsonMap[]>([]);
const createDialog = ref(false);
const grayDialog = ref(false);
const auditOpen = ref(false);
const activeGrayRelease = ref<ModelRelease>();
const grayPercent = ref(10);
const grayStrategy = ref("traffic");
const createForm = ref({ model_version_id: "", parameter_profile_id: "", evaluation_task_id: "", strategy_type: "traffic", comment: "" });

const productionRelease = computed(() => releases.value.find((item) => item.status === "production"));
const grayReleaseRecord = computed(() => releases.value.find((item) => item.status === "gray"));
const candidateVersions = computed(() => props.versions.filter((item) => ["candidate", "approved"].includes(item.status)));
const releaseProfiles = computed(() => profiles.value.filter((item) => item.model_version_id === createForm.value.model_version_id && item.status !== "inactive"));
const completedTests = computed(() => tests.value.filter((item) => ["completed", "partially_completed"].includes(String(item.status))));

async function load() {
  loading.value = true;
  try {
    [releases.value, profiles.value, tests.value] = await Promise.all([
      modelReleases(props.group.id), modelParameterProfiles(props.group.id), modelTests({ modelGroupId: props.group.id, limit: 100 })
    ]);
  } finally { loading.value = false; }
}

function openCreateRelease() {
  const version = candidateVersions.value[0];
  createForm.value = { model_version_id: version?.id || "", parameter_profile_id: "", evaluation_task_id: "", strategy_type: "traffic", comment: "" };
  selectReleaseVersion();
  createDialog.value = true;
}

function selectReleaseVersion() {
  createForm.value.parameter_profile_id = profiles.value.find((item) => item.model_version_id === createForm.value.model_version_id && item.status !== "inactive")?.id || "";
  const matchingTask = completedTests.value.find((item) => String(item.executed_versions || "").includes(props.versions.find((version) => version.id === createForm.value.model_version_id)?.version || ""));
  createForm.value.evaluation_task_id = String(matchingTask?.id || "");
}

async function submitRelease() {
  if (!createForm.value.model_version_id || !createForm.value.parameter_profile_id) return ElMessage.warning("请选择模型版本和参数方案");
  if (!createForm.value.evaluation_task_id) return ElMessage.warning("请选择已完成且通过的评估任务");
  saving.value = true;
  try {
    await createModelRelease({
      model_group_id: props.group.id,
      model_version_id: createForm.value.model_version_id,
      parameter_profile_id: createForm.value.parameter_profile_id,
      evaluation_task_id: createForm.value.evaluation_task_id,
      gray_strategy: { type: createForm.value.strategy_type, scope: "configured" },
      applicant: "算法工程师",
      comment: createForm.value.comment || "候选版本通过回归评估，申请进入发布流程"
    });
    createDialog.value = false;
    ElMessage.success("发布申请已提交");
    await load();
  } finally { saving.value = false; }
}

async function approve(release: ModelRelease) {
  const { value } = await ElMessageBox.prompt("请输入审批意见", "批准发布", { inputValue: "评估结果满足门槛，同意进入灰度" });
  await decideModelRelease(release.id, "approve", value);
  ElMessage.success("发布申请已批准");
  await load();
}

async function reject(release: ModelRelease) {
  const { value } = await ElMessageBox.prompt("请输入驳回原因", "驳回发布", { inputValidator: (text) => Boolean(text?.trim()) || "必须填写驳回原因" });
  await decideModelRelease(release.id, "reject", value);
  ElMessage.success("发布申请已驳回");
  await load();
}

function openGray(release: ModelRelease) {
  activeGrayRelease.value = release;
  grayPercent.value = release.gray_percent || 10;
  grayStrategy.value = String(release.gray_strategy?.type || "traffic");
  grayDialog.value = true;
}

async function submitGray() {
  if (!activeGrayRelease.value) return;
  saving.value = true;
  try {
    await updateModelReleaseGray(activeGrayRelease.value.id, grayPercent.value, { type: grayStrategy.value, scope: "configured" });
    grayDialog.value = false;
    ElMessage.success("灰度策略已更新");
    await load();
  } finally { saving.value = false; }
}

async function promote(release: ModelRelease) {
  await ElMessageBox.confirm(`确认将 ${release.model_version} 与参数快照 ${release.parameter_profile_name} 转为生产版本？`, "生产切换", { type: "warning", confirmButtonText: "确认切换" });
  await decideModelRelease(release.id, "promote", "灰度观测正常，转为正式生产版本");
  ElMessage.success("生产版本已切换");
  await load();
}

async function rollback(release: ModelRelease) {
  await ElMessageBox.confirm("回滚会同时恢复模型版本与生产参数快照，确认继续？", "模型回滚", { type: "error", confirmButtonText: "确认回滚" });
  await rollbackModelRelease(release.id, String(release.rollback_version_id), String(release.rollback_profile_id), "生产观测异常，执行成对回滚");
  ElMessage.success("模型和参数已回滚");
  await load();
}

async function openAudit() {
  auditOpen.value = true;
  auditLogs.value = await modelAuditLogs({});
}

function actionLabel(value: string) { return ({ created: "创建", revision_created: "创建参数修订", activated: "启用参数", deactivated: "停用参数", requested: "申请发布", promoted: "转为生产", rolled_back: "执行回滚", feedback_created: "结果反馈", cloned: "复制测试" } as Record<string, string>)[value] || value; }

onMounted(load);
</script>
