<template>
  <div v-loading="loading" class="model-management-workspace">
    <template v-if="!selectedGroup">
      <div class="model-toolbar">
        <el-input v-model="filters.keyword" clearable placeholder="模型名称、编码或能力" :prefix-icon="Search" @keyup.enter="loadModels" />
        <el-select v-model="filters.modelType" clearable placeholder="模型类型" @change="loadModels">
          <el-option label="目标检测" value="detection" /><el-option label="图像分割" value="segmentation" /><el-option label="红外分析" value="thermal" /><el-option label="点云分析" value="pointcloud" /><el-option label="变化检测" value="change" />
        </el-select>
        <el-select v-model="filters.status" clearable placeholder="版本状态" @change="loadModels"><el-option label="生产版本" value="production" /><el-option label="候选版本" value="candidate" /></el-select>
        <span class="filter-spacer"></span><el-button :icon="Refresh" @click="loadModels">刷新</el-button>
      </div>
      <section class="model-overview-metrics">
        <div><strong>{{ groups.length }}</strong><span>模型组</span><small>稳定算法能力</small></div>
        <div><strong>{{ groups.filter((item) => item.service_status === 'healthy').length }}</strong><span>服务正常</span><small>制品与运行契约有效</small></div>
        <div><strong>{{ groups.reduce((sum, item) => sum + Number(item.running_tests || 0), 0) }}</strong><span>运行中测试</span><small>隔离资源池</small></div>
        <div><strong>{{ groups.reduce((sum, item) => sum + Number(item.pending_releases || 0), 0) }}</strong><span>待审批发布</span><small>模型治理待办</small></div>
      </section>
      <el-card class="workspace-card" shadow="never">
        <el-table :data="groups" empty-text="暂无模型组" @row-dblclick="openGroup">
          <el-table-column label="模型能力" min-width="260">
            <template #default="scope"><button class="model-name-button" @click="openGroup(scope.row)"><i :class="`model-type-icon ${scope.row.model_type}`"><el-icon><component :is="modelIcon(scope.row.model_type)" /></el-icon></i><span><strong>{{ scope.row.name }}</strong><small>{{ scope.row.code }} · {{ scope.row.owner_team }}</small></span></button></template>
          </el-table-column>
          <el-table-column label="类型" width="105"><template #default="scope">{{ modelTypeLabel(scope.row.model_type) }}</template></el-table-column>
          <el-table-column label="输入模态" min-width="150"><template #default="scope"><el-tag v-for="item in scope.row.input_modalities" :key="item" class="modality-tag" size="small" effect="plain">{{ modalityLabel(item) }}</el-tag></template></el-table-column>
          <el-table-column label="生产版本" width="120"><template #default="scope"><strong>{{ scope.row.production_version || "未发布" }}</strong></template></el-table-column>
          <el-table-column label="候选版本" width="120"><template #default="scope">{{ scope.row.candidate_version || "-" }}</template></el-table-column>
          <el-table-column label="主要指标" min-width="185"><template #default="scope">{{ metricsText(scope.row.production_metrics) }}</template></el-table-column>
          <el-table-column label="服务" width="100"><template #default="scope"><el-tag :type="statusTagType(scope.row.service_status)" effect="plain">{{ scope.row.service_status === "healthy" ? "正常" : "关注" }}</el-tag></template></el-table-column>
          <el-table-column label="测试" width="90"><template #default="scope">{{ scope.row.test_count }}<small class="cell-subtext">累计任务</small></template></el-table-column>
          <el-table-column label="操作" width="160" fixed="right"><template #default="scope"><el-button link type="primary" @click="openGroup(scope.row)">管理</el-button><el-button link type="success" @click="openGroup(scope.row, 'test')">进入测试</el-button></template></el-table-column>
        </el-table>
      </el-card>
    </template>

    <template v-else>
      <header class="model-context-header">
        <el-button class="back-model-list" :icon="ArrowLeft" circle @click="backToModels" />
        <i :class="`model-type-icon ${selectedGroup.model_type}`"><el-icon><component :is="modelIcon(selectedGroup.model_type)" /></el-icon></i>
        <div class="model-context-title"><span>{{ selectedGroup.code }}</span><strong>{{ selectedGroup.name }}</strong><small>{{ selectedGroup.owner_team }} · {{ modelTypeLabel(selectedGroup.model_type) }}</small></div>
        <div class="model-context-facts"><span><small>生产版本</small><strong>{{ selectedGroup.production_version || "未发布" }}</strong></span><span><small>候选版本</small><strong>{{ selectedGroup.candidate_version || "-" }}</strong></span><span><small>输入模态</small><strong>{{ selectedGroup.input_modalities.map(modalityLabel).join(" / ") }}</strong></span></div>
        <el-tag :type="statusTagType(selectedGroup.service_status)" effect="dark">{{ selectedGroup.service_status === "healthy" ? "服务正常" : "服务关注" }}</el-tag>
        <el-button type="primary" :icon="VideoPlay" @click="switchPanel('test')">新建测试</el-button>
      </header>

      <el-tabs v-model="activePanel" class="model-detail-tabs" @tab-change="onPanelChange">
        <el-tab-pane label="能力概览" name="overview">
          <div class="model-detail-grid">
            <section class="model-capability-panel">
              <header><strong>模型能力</strong><span>输出契约 {{ detail?.output_contract_version }}</span></header>
              <p>{{ selectedGroup.description }}</p>
              <dl><div><dt>模型类型</dt><dd>{{ modelTypeLabel(selectedGroup.model_type) }}</dd></div><div><dt>责任团队</dt><dd>{{ selectedGroup.owner_team }}</dd></div><div><dt>版本数量</dt><dd>{{ detail?.version_count || versions.length }}</dd></div><div><dt>评估样本</dt><dd>{{ detail?.sample_count || 0 }}</dd></div><div><dt>测试任务</dt><dd>{{ detail?.test_count || selectedGroup.test_count }}</dd></div><div><dt>输入模态</dt><dd>{{ selectedGroup.input_modalities.map(modalityLabel).join("、") }}</dd></div></dl>
              <h3>适用场景</h3><div class="scene-tags"><el-tag v-for="scene in productionVersion?.scenes || []" :key="scene" effect="plain">{{ scene }}</el-tag></div>
            </section>
            <section class="model-production-panel">
              <header><strong>生产运行基线</strong><el-tag type="success" effect="plain">{{ productionVersion?.version || "未发布" }}</el-tag></header>
              <div class="production-metric-grid"><div v-for="([key, value]) in Object.entries(productionVersion?.metrics || {})" :key="key"><span>{{ metricLabel(key) }}</span><strong>{{ metricValue(key, value) }}</strong></div></div>
              <dl class="production-runtime"><div><dt>制品类型</dt><dd>{{ productionVersion?.artifact_type || "-" }}</dd></div><div><dt>制品校验</dt><dd>{{ productionVersion?.artifact_validation_status === "passed" ? "通过" : "待校验" }}</dd></div><div><dt>数据集</dt><dd>{{ productionVersion?.dataset_version || "-" }}</dd></div><div><dt>制品哈希</dt><dd class="hash-value">{{ productionVersion?.artifact_sha256 || "-" }}</dd></div></dl>
            </section>
          </div>
          <div class="recent-model-activity">
            <section><header><strong>近期测试</strong><el-button text @click="switchPanel('evaluations')">全部记录</el-button></header><el-table :data="detail?.recent_tests || []" size="small" empty-text="暂无测试记录"><el-table-column prop="task_no" label="任务编号" /><el-table-column prop="name" label="名称" /><el-table-column label="状态"><template #default="scope"><el-tag :type="statusTagType(scope.row.status)" size="small">{{ scope.row.status }}</el-tag></template></el-table-column><el-table-column prop="progress" label="进度" /></el-table></section>
            <section><header><strong>版本关系</strong><el-button text @click="switchPanel('versions')">版本管理</el-button></header><div class="version-flow"><div v-for="version in versions" :key="version.id" :class="version.status"><strong>{{ version.version }}</strong><span>{{ version.status }}</span><small>{{ version.display_name }}</small></div></div></section>
          </div>
        </el-tab-pane>

        <el-tab-pane label="版本与制品" name="versions">
          <div class="model-toolbar"><span class="toolbar-note">模型制品校验包括哈希、输入输出契约、运行时兼容性和冒烟测试。</span><span class="filter-spacer"></span><el-button :icon="Refresh" @click="loadSelectedGroup">刷新</el-button></div>
          <el-card class="workspace-card" shadow="never"><el-table :data="versions">
            <el-table-column label="版本" min-width="180"><template #default="scope"><strong>{{ scope.row.version }}</strong><small class="cell-subtext">{{ scope.row.display_name }}</small></template></el-table-column>
            <el-table-column label="生命周期" width="110"><template #default="scope"><el-tag :type="statusTagType(scope.row.status)" effect="plain">{{ versionStatus(scope.row.status) }}</el-tag></template></el-table-column>
            <el-table-column label="数据集" min-width="140" prop="dataset_version" />
            <el-table-column label="离线指标" min-width="220"><template #default="scope">{{ metricsText(scope.row.metrics) }}</template></el-table-column>
            <el-table-column label="制品" min-width="145"><template #default="scope">{{ scope.row.artifact_type || "-" }}<small class="cell-subtext">{{ formatBytes(scope.row.artifact_size_bytes) }}</small></template></el-table-column>
            <el-table-column label="校验" width="100"><template #default="scope"><el-tag :type="scope.row.artifact_validation_status === 'passed' ? 'success' : 'warning'" effect="plain">{{ scope.row.artifact_validation_status === "passed" ? "通过" : "待校验" }}</el-tag></template></el-table-column>
            <el-table-column label="创建时间" width="170"><template #default="scope">{{ formatDateTime(scope.row.created_at) }}</template></el-table-column>
            <el-table-column label="操作" width="155" fixed="right"><template #default="scope"><el-button link type="primary" @click="showArtifacts(scope.row)">制品详情</el-button><el-button link @click="revalidateArtifact(scope.row)">重新校验</el-button></template></el-table-column>
          </el-table></el-card>
        </el-tab-pane>
        <el-tab-pane label="运行配置" name="runtime"><ModelRuntimeDeploymentPanel v-if="activePanel === 'runtime'" :group="selectedGroup" :versions="versions" /></el-tab-pane>
        <el-tab-pane label="参数方案" name="parameters"><ModelParameterPanel v-if="activePanel === 'parameters'" :group="selectedGroup" :versions="versions" /></el-tab-pane>
        <el-tab-pane label="测试工作台" name="test"><ModelTestWorkbench v-if="activePanel === 'test'" :group="selectedGroup" :versions="versions" :initial-task-id="initialTaskId" /></el-tab-pane>
        <el-tab-pane label="评估记录" name="evaluations"><ModelEvaluationPanel v-if="activePanel === 'evaluations'" :group="selectedGroup" /></el-tab-pane>
        <el-tab-pane label="发布记录" name="releases"><ModelReleasePanel v-if="activePanel === 'releases'" :group="selectedGroup" :versions="versions" /></el-tab-pane>
      </el-tabs>

      <el-drawer v-model="artifactDrawer" title="模型制品详情" size="min(680px, 92vw)">
        <template v-if="artifactVersion"><div class="artifact-version-head"><el-tag :type="statusTagType(artifactVersion.status)" effect="dark">{{ versionStatus(artifactVersion.status) }}</el-tag><span><strong>{{ artifactVersion.version }}</strong><small>{{ artifactVersion.display_name }}</small></span></div><section v-for="artifact in artifacts" :key="String(artifact.id)" class="artifact-detail-section"><header><strong>{{ artifact.artifact_type }}</strong><el-tag :type="artifact.validation_status === 'passed' ? 'success' : 'warning'">{{ artifact.validation_status }}</el-tag></header><dl><div><dt>对象路径</dt><dd>{{ artifact.object_key }}</dd></div><div><dt>SHA-256</dt><dd class="hash-value">{{ artifact.sha256 }}</dd></div><div><dt>文件大小</dt><dd>{{ formatBytes(artifact.size_bytes) }}</dd></div><div><dt>运行要求</dt><dd>{{ JSON.stringify(artifact.runtime_constraints) }}</dd></div></dl><h3>校验报告</h3><div class="artifact-checks"><span v-for="([key, value]) in Object.entries(artifact.validation_report || {})" :key="key"><el-icon :class="value ? 'pass' : 'fail'"><CircleCheckFilled v-if="value" /><CircleCloseFilled v-else /></el-icon>{{ artifactCheckLabel(key) }}</span></div></section></template>
      </el-drawer>
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed, defineAsyncComponent, onMounted, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import { Aim, ArrowLeft, CircleCheckFilled, CircleCloseFilled, Cpu, DataAnalysis, Grid, Histogram, Refresh, Search, VideoPlay } from "@element-plus/icons-vue";
import { modelArtifacts, modelDetail, modelGroups, modelVersions, validateModelArtifact } from "../../services/api";
import { formatBytes, formatDateTime, type JsonMap, type ModelGroup, modelTypeLabel, type ModelVersion, statusTagType } from "../../types/model-management";

const ModelParameterPanel = defineAsyncComponent(() => import("./ModelParameterPanel.vue"));
const ModelRuntimeDeploymentPanel = defineAsyncComponent(() => import("./ModelRuntimeDeploymentPanel.vue"));
const ModelTestWorkbench = defineAsyncComponent(() => import("./ModelTestWorkbench.vue"));
const ModelEvaluationPanel = defineAsyncComponent(() => import("./ModelEvaluationPanel.vue"));
const ModelReleasePanel = defineAsyncComponent(() => import("./ModelReleasePanel.vue"));

const props = defineProps<{ modelGroupId?: string; initialTaskId?: string }>();
const route = useRoute();
const router = useRouter();
const loading = ref(false);
const groups = ref<ModelGroup[]>([]);
const detail = ref<JsonMap>();
const versions = ref<ModelVersion[]>([]);
const activePanel = ref(String(route.query.panel || "overview"));
const filters = ref({ keyword: "", modelType: "", status: "" });
const artifactDrawer = ref(false);
const artifactVersion = ref<ModelVersion>();
const artifacts = ref<JsonMap[]>([]);

const selectedGroup = computed(() => groups.value.find((item) => item.id === props.modelGroupId));
const productionVersion = computed(() => versions.value.find((item) => item.status === "production"));

async function loadModels() {
  loading.value = true;
  try { groups.value = await modelGroups({ keyword: filters.value.keyword || undefined, modelType: filters.value.modelType || undefined, status: filters.value.status || undefined }); }
  finally { loading.value = false; }
}

async function loadSelectedGroup() {
  if (!props.modelGroupId) return;
  loading.value = true;
  try { [detail.value, versions.value] = await Promise.all([modelDetail(props.modelGroupId), modelVersions(props.modelGroupId)]); }
  finally { loading.value = false; }
}

function openGroup(group: ModelGroup, panel = "overview") {
  router.push({ path: `/algorithm-assets/models/${group.id}`, query: { panel } });
}
function backToModels() { router.push("/algorithm-assets/models"); }
function switchPanel(panel: string) { activePanel.value = panel; onPanelChange(panel); }
function onPanelChange(panel: string | number) { router.replace({ query: { ...route.query, panel: String(panel) } }); }

async function showArtifacts(version: ModelVersion) {
  artifactVersion.value = version;
  artifactDrawer.value = true;
  artifacts.value = await modelArtifacts(version.id);
}

async function revalidateArtifact(version: ModelVersion) {
  await validateModelArtifact(version.id);
  ElMessage.success("模型制品校验通过");
  await loadSelectedGroup();
}

function modelIcon(type: string) { return ({ detection: Aim, segmentation: Grid, thermal: Histogram, pointcloud: DataAnalysis, change: Cpu } as Record<string, any>)[type] || Cpu; }
function modalityLabel(value: string) { return ({ image: "图片", video: "视频", thermal: "红外", pointcloud: "点云", raster: "栅格" } as Record<string, string>)[value] || value; }
function metricsText(value: unknown) { const metrics = (value || {}) as JsonMap; return Object.entries(metrics).map(([key, item]) => `${metricLabel(key)} ${metricValue(key, item)}`).join(" / ") || "-"; }
function metricLabel(value: string) { return ({ precision: "精确率", recall: "召回率", f1: "F1", map50: "mAP50", miou: "mIoU", dice: "Dice", temperature_error_c: "温度误差", registration_error_m: "配准误差", anomaly_recall: "异常召回", iou: "IoU" } as Record<string, string>)[value] || value; }
function metricValue(key: string, value: unknown) { const number = Number(value); if (["precision", "recall", "f1", "map50", "miou", "dice", "anomaly_recall", "iou"].includes(key)) return `${(number * 100).toFixed(1)}%`; if (key.includes("error_m")) return `${number.toFixed(3)} m`; if (key.includes("temperature")) return `${number.toFixed(2)}°C`; return String(value); }
function versionStatus(value: string) { return ({ production: "生产", candidate: "候选", approved: "已批准", retired: "已退役", invalid: "无效" } as Record<string, string>)[value] || value; }
function artifactCheckLabel(value: string) { return ({ checksum: "文件校验和", contract: "输入输出契约", runtime: "运行时兼容", smoke_test: "校验集运行" } as Record<string, string>)[value] || value; }

watch(() => props.modelGroupId, async () => { await loadModels(); await loadSelectedGroup(); });
watch(() => route.query.panel, (panel) => { activePanel.value = String(panel || "overview"); });
onMounted(async () => { await loadModels(); await loadSelectedGroup(); });
</script>
