<template>
  <div v-loading="loading" class="parameter-workspace">
    <div class="model-toolbar parameter-toolbar">
      <div class="toolbar-field">
        <span>模型版本</span>
        <el-select v-model="selectedVersionId" @change="loadSchemaAndSelectProfile">
          <el-option v-for="version in versions" :key="version.id" :label="`${version.version} · ${version.status}`" :value="version.id" />
        </el-select>
      </div>
      <div class="toolbar-field">
        <span>参数方案</span>
        <el-select v-model="selectedProfileId" @change="selectProfile">
          <el-option v-for="profile in versionProfiles" :key="profile.id" :label="`${profile.name} r${profile.revision}`" :value="profile.id" />
        </el-select>
      </div>
      <span class="filter-spacer"></span>
      <el-button :icon="DocumentChecked" @click="validateDraft">校验参数</el-button>
      <el-button :icon="CopyDocument" :disabled="compareSelection.length < 2" @click="compareSelected">比较</el-button>
      <el-button type="primary" :icon="Plus" @click="openSaveDialog(selectedProfile ? 'revision' : 'new')">
        {{ selectedProfile ? "保存新修订" : "新建方案" }}
      </el-button>
    </div>

    <div class="parameter-layout">
      <aside class="parameter-profile-list">
        <header><strong>方案修订</strong><span>{{ versionProfiles.length }} 项</span></header>
        <el-table :data="versionProfiles" size="small" height="610" @selection-change="compareSelection = $event">
          <el-table-column type="selection" width="38" />
          <el-table-column label="方案" min-width="150">
            <template #default="scope">
              <button class="profile-row-button" :class="{ active: selectedProfileId === scope.row.id }" @click="selectedProfileId = scope.row.id; selectProfile()">
                <strong>{{ scope.row.name }} r{{ scope.row.revision }}</strong>
                <span>{{ scope.row.model_version }} · {{ scopeLabel(scope.row.scope_type) }}</span>
              </button>
            </template>
          </el-table-column>
          <el-table-column label="状态" width="72">
            <template #default="scope"><el-tag :type="statusTagType(scope.row.status)" size="small" effect="plain">{{ profileStatus(scope.row.status) }}</el-tag></template>
          </el-table-column>
        </el-table>
      </aside>

      <main class="parameter-form-panel">
        <header class="parameter-form-head">
          <div>
            <strong>{{ selectedProfile ? `${selectedProfile.name} r${selectedProfile.revision}` : "临时参数" }}</strong>
            <span>参数定义 {{ schema?.schema_version || "-" }} · 修改不会影响已运行任务</span>
          </div>
          <div v-if="selectedProfile" class="list-actions">
            <el-tag :type="statusTagType(selectedProfile.status)" effect="plain">{{ profileStatus(selectedProfile.status) }}</el-tag>
            <el-button
              v-if="selectedProfile.status !== 'locked'"
              text
              :type="selectedProfile.status === 'inactive' ? 'success' : 'warning'"
              @click="toggleProfileStatus"
            >{{ selectedProfile.status === "inactive" ? "启用" : "停用" }}</el-button>
          </div>
        </header>

        <el-alert
          v-if="validation"
          class="parameter-validation-alert"
          :type="validation.valid ? 'success' : 'error'"
          :closable="false"
          show-icon
          :title="validation.valid ? '参数校验通过' : `发现 ${validation.errors?.length || 0} 个参数错误`"
        >
          <template #default>
            <span v-if="validation.resource_estimate">预计显存 {{ validation.resource_estimate.memory_gb }} GB，资源池 {{ validation.resource_estimate.device_pool }}</span>
          </template>
        </el-alert>

        <div v-for="group in parameterGroups" :key="group.title" class="parameter-section">
          <header><strong>{{ group.title }}</strong><span>{{ group.fields.length }} 个参数</span></header>
          <div class="parameter-fields">
            <div v-for="field in group.fields" :key="field" class="parameter-field">
              <div class="parameter-label">
                <span>{{ property(field).title }}</span>
                <small>{{ field }}</small>
              </div>
              <div class="parameter-control">
                <el-switch v-if="property(field).type === 'boolean'" v-model="draft[field]" />
                <el-select v-else-if="property(field).enum" v-model="draft[field]">
                  <el-option v-for="option in property(field).enum" :key="String(option)" :label="String(option)" :value="option" />
                </el-select>
                <template v-else-if="['number', 'integer'].includes(property(field).type)">
                  <el-slider
                    v-model="draft[field]"
                    :min="property(field).minimum ?? 0"
                    :max="property(field).maximum ?? 100"
                    :step="property(field).multipleOf ?? (property(field).type === 'integer' ? 1 : 0.01)"
                    :show-tooltip="false"
                  />
                  <el-input-number
                    v-model="draft[field]"
                    :min="property(field).minimum"
                    :max="property(field).maximum"
                    :step="property(field).multipleOf ?? (property(field).type === 'integer' ? 1 : 0.01)"
                    controls-position="right"
                  />
                </template>
                <el-input v-else v-model="draft[field]" />
              </div>
              <p v-if="fieldError(field)" class="field-error">{{ fieldError(field) }}</p>
            </div>
          </div>
        </div>

        <details class="advanced-parameter-json">
          <summary>结构化参数</summary>
          <el-input v-model="draftJson" type="textarea" :rows="12" @change="applyDraftJson" />
        </details>
      </main>
    </div>

    <el-dialog v-model="saveDialog" :title="saveMode === 'new' ? '新建参数方案' : '保存参数修订'" width="520px">
      <el-form label-position="top">
        <el-form-item v-if="saveMode === 'new'" label="方案名称"><el-input v-model="saveForm.name" maxlength="64" /></el-form-item>
        <el-form-item label="适用范围">
          <el-select v-model="saveForm.scope_type"><el-option label="测试" value="test" /><el-option label="场景方案" value="scene" /><el-option label="模型默认" value="version_default" /></el-select>
        </el-form-item>
        <el-form-item label="变更原因"><el-input v-model="saveForm.change_reason" type="textarea" :rows="3" maxlength="300" show-word-limit /></el-form-item>
      </el-form>
      <template #footer><el-button @click="saveDialog = false">取消</el-button><el-button type="primary" :loading="saving" @click="saveProfile">保存</el-button></template>
    </el-dialog>

    <el-dialog v-model="compareDialog" title="参数方案差异" width="min(920px, 92vw)">
      <el-table :data="comparison?.differences || []" max-height="560">
        <el-table-column prop="parameter" label="参数" min-width="180" fixed />
        <el-table-column v-for="(profile, index) in comparison?.profiles || []" :key="profile.id" :label="`${profile.name} r${profile.revision}`" min-width="150">
          <template #default="scope"><code :class="{ 'changed-value': scope.row.changed }">{{ valueText(scope.row.values[index]) }}</code></template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { CopyDocument, DocumentChecked, Plus } from "@element-plus/icons-vue";
import {
  changeModelParameterProfileStatus, compareModelParameterProfiles, createModelParameterProfile,
  createModelParameterRevision, modelParameterProfiles, modelParameterSchema, validateModelParameters
} from "../../services/api";
import type { JsonMap, ModelGroup, ModelVersion, ParameterProfile, ParameterProperty, ParameterSchema } from "../../types/model-management";
import { statusTagType } from "../../types/model-management";

const props = defineProps<{ group: ModelGroup; versions: ModelVersion[] }>();
const loading = ref(false);
const saving = ref(false);
const profiles = ref<ParameterProfile[]>([]);
const schema = ref<ParameterSchema>();
const selectedVersionId = ref("");
const selectedProfileId = ref("");
const draft = ref<Record<string, any>>({});
const draftJson = ref("{}");
const validation = ref<any>();
const compareSelection = ref<ParameterProfile[]>([]);
const comparison = ref<any>();
const compareDialog = ref(false);
const saveDialog = ref(false);
const saveMode = ref<"new" | "revision">("new");
const saveForm = ref({ name: "", scope_type: "test", change_reason: "" });

const versionProfiles = computed(() => profiles.value.filter((item) => item.model_version_id === selectedVersionId.value));
const selectedProfile = computed(() => profiles.value.find((item) => item.id === selectedProfileId.value));
const parameterGroups = computed(() => schema.value?.ui_schema.groups || []);

function property(field: string): ParameterProperty {
  return schema.value?.json_schema.properties[field] || { type: "string", title: field };
}

async function load() {
  loading.value = true;
  try {
    profiles.value = await modelParameterProfiles(props.group.id);
    selectedVersionId.value = props.versions.find((item) => item.status === "candidate")?.id || props.versions[0]?.id || "";
    await loadSchemaAndSelectProfile();
  } finally { loading.value = false; }
}

async function loadSchemaAndSelectProfile() {
  if (!selectedVersionId.value) return;
  schema.value = await modelParameterSchema(selectedVersionId.value);
  const current = versionProfiles.value.find((item) => item.status === "active") || versionProfiles.value[0];
  selectedProfileId.value = current?.id || "";
  selectProfile();
}

function selectProfile() {
  const values = selectedProfile.value?.parameters || defaultsFromSchema();
  draft.value = JSON.parse(JSON.stringify(values));
  validation.value = undefined;
  syncJson();
}

function defaultsFromSchema() {
  const values: JsonMap = {};
  Object.entries(schema.value?.json_schema.properties || {}).forEach(([key, item]) => { values[key] = item.default; });
  return values;
}

async function validateDraft(showSuccess = true) {
  validation.value = await validateModelParameters({
    model_group_id: props.group.id,
    model_version_id: selectedVersionId.value,
    parameters: draft.value
  });
  if (showSuccess) ElMessage[validation.value.valid ? "success" : "error"](validation.value.valid ? "参数校验通过" : "参数校验未通过");
  syncJson();
  return Boolean(validation.value.valid);
}

function fieldError(field: string) {
  return validation.value?.errors?.find((item: any) => item.field === field)?.message || "";
}

function openSaveDialog(mode: "new" | "revision") {
  saveMode.value = mode;
  saveForm.value = {
    name: mode === "new" ? `${props.group.name}参数方案` : selectedProfile.value?.name || "",
    scope_type: selectedProfile.value?.scope_type || "test",
    change_reason: ""
  };
  saveDialog.value = true;
}

async function saveProfile() {
  if (!(await validateDraft(false))) return;
  if (saveMode.value === "new" && !saveForm.value.name.trim()) return ElMessage.warning("请输入方案名称");
  if (!saveForm.value.change_reason.trim()) return ElMessage.warning("请填写变更原因");
  saving.value = true;
  try {
    const saved = saveMode.value === "revision" && selectedProfile.value
      ? await createModelParameterRevision(selectedProfile.value.id, {
          parameters: draft.value, scope_value: selectedProfile.value.scope_value,
          change_reason: saveForm.value.change_reason, operator: "算法工程师"
        })
      : await createModelParameterProfile(props.group.id, {
          model_version_id: selectedVersionId.value, name: saveForm.value.name,
          scope_type: saveForm.value.scope_type, scope_value: {}, parameters: draft.value,
          based_on_id: selectedProfile.value?.id, change_reason: saveForm.value.change_reason, operator: "算法工程师"
        });
    profiles.value = await modelParameterProfiles(props.group.id);
    selectedProfileId.value = saved.id;
    selectProfile();
    saveDialog.value = false;
    ElMessage.success("参数方案已保存为不可变修订");
  } finally { saving.value = false; }
}

async function toggleProfileStatus() {
  if (!selectedProfile.value) return;
  await changeModelParameterProfileStatus(selectedProfile.value.id, selectedProfile.value.status === "inactive");
  profiles.value = await modelParameterProfiles(props.group.id);
  ElMessage.success("参数方案状态已更新");
}

async function compareSelected() {
  comparison.value = await compareModelParameterProfiles(compareSelection.value.map((item) => item.id));
  compareDialog.value = true;
}

function applyDraftJson() {
  try { draft.value = JSON.parse(draftJson.value); validation.value = undefined; }
  catch { ElMessage.error("结构化参数格式不正确"); syncJson(); }
}
function syncJson() { draftJson.value = JSON.stringify(draft.value, null, 2); }
function valueText(value: unknown) { return typeof value === "object" ? JSON.stringify(value) : String(value ?? "-"); }
function profileStatus(value: string) { return ({ active: "有效", inactive: "停用", locked: "生产锁定" } as Record<string, string>)[value] || value; }
function scopeLabel(value: string) { return ({ test: "测试", scene: "场景", version_default: "版本默认", production_snapshot: "生产快照" } as Record<string, string>)[value] || value; }

watch(() => draft.value, syncJson, { deep: true });
onMounted(load);
</script>
