<script setup lang="ts">
import { Delete, Edit, Plus, RefreshRight } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { computed, onMounted, reactive, ref } from 'vue';

import { loadModelProviderEnumOptions, type EnumOption } from '@/api/modelEnums';
import {
  deleteModelRouteRule,
  queryModelConfigs,
  queryModelRouteRules,
  saveModelRouteRule,
  type ModelConfig,
  type ModelRouteRule,
} from '@/api/modelProvider';

const loading = ref(false);
const saving = ref(false);
const dialogVisible = ref(false);
const routes = ref<ModelRouteRule[]>([]);
const models = ref<ModelConfig[]>([]);
const taskTypeOptions = ref<EnumOption[]>([]);
const routeStrategyOptions = ref<EnumOption[]>([]);
const matchScopeOptions = ref<EnumOption[]>([]);
const enumError = ref('');

const editForm = reactive<ModelRouteRule>({
  routeCode: '',
  routeName: '',
  taskType: '',
  matchScope: '',
  scopeId: '',
  primaryModelId: '',
  fallbackModelIdsJson: '[]',
  routeStrategy: '',
  maxLatencyMs: 0,
  enabled: true,
  remark: '',
});

const dialogTitle = computed(() => (editForm.id ? '编辑路由规则' : '新增路由规则'));

function resetForm(row?: ModelRouteRule) {
  editForm.id = row?.id;
  editForm.routeCode = row?.routeCode ?? '';
  editForm.routeName = row?.routeName ?? '';
  editForm.taskType = row?.taskType ?? taskTypeOptions.value[0]?.value ?? '';
  editForm.matchScope = row?.matchScope ?? matchScopeOptions.value[0]?.value ?? '';
  editForm.scopeId = row?.scopeId ?? '';
  editForm.primaryModelId = row?.primaryModelId ?? models.value[0]?.id ?? '';
  editForm.fallbackModelIdsJson = row?.fallbackModelIdsJson ?? '[]';
  editForm.routeStrategy = row?.routeStrategy ?? routeStrategyOptions.value[0]?.value ?? '';
  editForm.maxLatencyMs = row?.maxLatencyMs ?? 0;
  editForm.enabled = row?.enabled ?? true;
  editForm.remark = row?.remark ?? '';
}

async function loadBaseData(forceRefresh = false) {
  enumError.value = '';
  try {
    const [enumResult, modelResult] = await Promise.all([
      loadModelProviderEnumOptions(forceRefresh),
      queryModelConfigs(),
    ]);
    taskTypeOptions.value = enumResult.task_type ?? [];
    routeStrategyOptions.value = enumResult.route_strategy ?? [];
    matchScopeOptions.value = enumResult.match_scope ?? [];
    models.value = modelResult.data ?? [];
  } catch (error) {
    enumError.value = error instanceof Error ? error.message : '基础数据加载失败';
  }
}

async function loadRouteRules() {
  loading.value = true;
  try {
    const response = await queryModelRouteRules();
    routes.value = response.data ?? [];
  } finally {
    loading.value = false;
  }
}

function openCreateDialog() {
  resetForm();
  dialogVisible.value = true;
}

function openEditDialog(row: ModelRouteRule) {
  resetForm(row);
  dialogVisible.value = true;
}

async function submitRouteRule() {
  if (!editForm.routeCode || !editForm.taskType || !editForm.primaryModelId) {
    ElMessage.warning('请填写路由编码、任务类型和主模型');
    return;
  }
  try {
    JSON.parse(editForm.fallbackModelIdsJson ?? '[]');
  } catch {
    ElMessage.warning('降级模型JSON格式不正确');
    return;
  }

  saving.value = true;
  try {
    await saveModelRouteRule({ ...editForm });
    ElMessage.success('保存成功');
    dialogVisible.value = false;
    await loadRouteRules();
  } finally {
    saving.value = false;
  }
}

async function removeRouteRule(row: ModelRouteRule) {
  if (!row.id) {
    return;
  }
  await ElMessageBox.confirm(`确认删除路由规则「${row.routeName || row.routeCode}」？`, '删除确认', {
    type: 'warning',
    confirmButtonText: '删除',
    cancelButtonText: '取消',
  });
  await deleteModelRouteRule(row.id);
  ElMessage.success('已删除');
  await loadRouteRules();
}

function modelLabel(modelId?: string) {
  const model = models.value.find((item) => item.id === modelId);
  return model?.modelName ?? model?.modelCode ?? modelId ?? '-';
}

onMounted(async () => {
  await loadBaseData();
  resetForm();
  await loadRouteRules();
});
</script>

<template>
  <section class="page-panel">
    <div class="page-panel__header">
      <h2>路由规则</h2>
      <span>Routes</span>
    </div>
    <div class="toolbar">
      <el-alert v-if="enumError" type="error" :closable="false" :title="`基础数据加载失败：${enumError}`" show-icon />
      <div class="toolbar__actions">
        <el-button @click="loadBaseData(true)">重试基础数据</el-button>
        <el-button :icon="RefreshRight" @click="loadRouteRules">刷新</el-button>
        <el-button type="primary" :icon="Plus" @click="openCreateDialog">新增规则</el-button>
      </div>
    </div>

    <el-table v-loading="loading" :data="routes" row-key="id">
      <el-table-column prop="routeCode" label="规则编码" min-width="140" />
      <el-table-column prop="routeName" label="规则名称" min-width="140" />
      <el-table-column prop="taskType" label="任务类型" min-width="120" />
      <el-table-column prop="matchScope" label="匹配范围" min-width="100" />
      <el-table-column label="主模型" min-width="140">
        <template #default="{ row }">{{ modelLabel(row.primaryModelId) }}</template>
      </el-table-column>
      <el-table-column prop="fallbackModelIdsJson" label="降级模型JSON" min-width="180" show-overflow-tooltip />
      <el-table-column prop="routeStrategy" label="策略" min-width="100" />
      <el-table-column prop="maxLatencyMs" label="最大延迟(ms)" width="120" />
      <el-table-column label="启用" width="80">
        <template #default="{ row }">
          <el-tag :type="row.enabled ? 'success' : 'info'">{{ row.enabled ? '是' : '否' }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="160" fixed="right">
        <template #default="{ row }">
          <el-button link type="primary" :icon="Edit" @click="openEditDialog(row)">编辑</el-button>
          <el-button link type="danger" :icon="Delete" @click="removeRouteRule(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="680px">
      <el-form :model="editForm" label-width="120px">
        <el-form-item label="规则编码" required>
          <el-input v-model="editForm.routeCode" placeholder="如 RAG_EMBEDDING_GLOBAL" />
        </el-form-item>
        <el-form-item label="规则名称">
          <el-input v-model="editForm.routeName" />
        </el-form-item>
        <el-form-item label="任务类型" required>
          <el-select v-model="editForm.taskType">
            <el-option v-for="item in taskTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="匹配范围">
          <el-select v-model="editForm.matchScope">
            <el-option v-for="item in matchScopeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="范围业务ID">
          <el-input v-model="editForm.scopeId" />
        </el-form-item>
        <el-form-item label="主模型" required>
          <el-select v-model="editForm.primaryModelId">
            <el-option v-for="item in models" :key="item.id" :label="`${item.modelName}(${item.modelCode})`" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="降级模型JSON">
          <el-input v-model="editForm.fallbackModelIdsJson" type="textarea" :rows="3" />
        </el-form-item>
        <el-form-item label="路由策略">
          <el-select v-model="editForm.routeStrategy">
            <el-option v-for="item in routeStrategyOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="最大延迟(ms)">
          <el-input-number v-model="editForm.maxLatencyMs" :min="0" controls-position="right" />
        </el-form-item>
        <el-form-item label="启用">
          <el-switch v-model="editForm.enabled" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="editForm.remark" type="textarea" :rows="2" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="submitRouteRule">保存</el-button>
      </template>
    </el-dialog>
  </section>
</template>

<style scoped>
.toolbar {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 22px;
}

.toolbar__actions {
  display: flex;
  gap: 8px;
}
</style>
