<script setup lang="ts">
import { computed, onMounted, reactive, ref } from "vue";

import { api } from "../../shared/api/client";
import { useUiStore } from "../../shared/stores/ui";

type ModelItem = {
  id: number;
  display_name: string;
  base_url: string;
  model_identifier: string;
  has_api_key: boolean;
  is_primary: boolean;
  is_fallback: boolean;
  updated_at: string;
};

const ui = useUiStore();
const models = ref<ModelItem[]>([]);
const loading = ref(true);
const editingId = ref<number | null>(null);
const primaryId = ref<number | null>(null);
const fallbackId = ref<number | null>(null);
const errorMessage = ref("");
const deleteConfirmation = ref<number | null>(null);
const testingId = ref<number | null>(null);
const testMessage = ref("");
const form = reactive({ display_name: "", base_url: "", model_identifier: "", api_key: "" });
const editing = computed(() => models.value.find((item) => item.id === editingId.value) ?? null);

function resetForm(): void {
  editingId.value = null;
  Object.assign(form, { display_name: "", base_url: "", model_identifier: "", api_key: "" });
  testMessage.value = "";
}

function edit(model: ModelItem): void {
  deleteConfirmation.value = null;
  editingId.value = model.id;
  Object.assign(form, {
    display_name: model.display_name,
    base_url: model.base_url,
    model_identifier: model.model_identifier,
    api_key: "",
  });
}

async function load(): Promise<void> {
  loading.value = true;
  errorMessage.value = "";
  try {
    models.value = await api.get<ModelItem[]>("/admin/models");
    primaryId.value = models.value.find((item) => item.is_primary)?.id ?? null;
    fallbackId.value = models.value.find((item) => item.is_fallback)?.id ?? null;
  } catch (error) {
    errorMessage.value = error instanceof Error ? error.message : "模型池读取失败。";
  } finally {
    loading.value = false;
  }
}

async function save(): Promise<void> {
  errorMessage.value = "";
  const wasEditing = editingId.value !== null;
  try {
    const payload = {
      display_name: form.display_name,
      base_url: form.base_url,
      model_identifier: form.model_identifier,
      ...(form.api_key ? { api_key: form.api_key } : {}),
    };
    if (editingId.value) {
      await api.put(`/admin/models/${editingId.value}`, payload);
    } else {
      if (!form.api_key) {
        errorMessage.value = "新增模型时必须填写密钥。";
        return;
      }
      await api.post("/admin/models", payload);
    }
    resetForm();
    await load();
    ui.showToast(wasEditing ? "模型已更新" : "模型已添加");
  } catch (error) {
    errorMessage.value = error instanceof Error ? error.message : "模型保存失败。";
  }
}

async function saveSelection(): Promise<void> {
  if (!primaryId.value) {
    errorMessage.value = "请选择主模型。";
    return;
  }
  try {
    await api.put("/admin/models/selection", {
      primary_model_id: primaryId.value,
      fallback_model_id: fallbackId.value,
    });
    await load();
    ui.showToast("主模型和辅助模型已更新");
  } catch (error) {
    errorMessage.value = error instanceof Error ? error.message : "模型选择保存失败。";
  }
}

async function remove(model: ModelItem): Promise<void> {
  if (deleteConfirmation.value !== model.id) {
    deleteConfirmation.value = model.id;
    return;
  }
  try {
    await api.delete(`/admin/models/${model.id}`);
    if (editingId.value === model.id) resetForm();
    await load();
    deleteConfirmation.value = null;
    ui.showToast("模型已删除");
  } catch (error) {
    errorMessage.value = error instanceof Error ? error.message : "模型删除失败。";
  }
}

async function testConnection(model: ModelItem): Promise<void> {
  testingId.value = model.id;
  testMessage.value = "";
  errorMessage.value = "";
  try {
    const result = await api.post<{ message: string; duration_ms: number }>(
      `/admin/models/${model.id}/test`,
    );
    testMessage.value = `${result.message} · ${result.duration_ms} ms`;
    ui.showToast(`${model.display_name} 连接成功`);
  } catch (error) {
    errorMessage.value = error instanceof Error ? error.message : "模型连接测试失败。";
  } finally {
    testingId.value = null;
  }
}

onMounted(load);
</script>

<template>
  <div class="system-grid model-grid">
    <section class="card">
      <header class="card-header"><h2>模型池</h2><span class="tag">{{ models.length }} / 20</span></header>
      <div class="model-list">
        <p v-if="loading" class="panel-loading muted">正在读取模型池</p>
        <p v-else-if="errorMessage" class="panel-loading field-error" role="alert">{{ errorMessage }}</p>
        <template v-else>
          <button v-for="model in models" :key="model.id" class="model-row" :class="{ active: editingId === model.id }" type="button" @click="edit(model)">
            <span><strong>{{ model.display_name }}</strong><small>{{ model.model_identifier }}</small></span>
            <span class="model-tags"><span v-if="model.is_primary" class="tag">主模型</span><span v-if="model.is_fallback" class="tag">辅助</span></span>
          </button>
          <p v-if="!models.length" class="panel-loading muted">尚未添加模型</p>
        </template>
      </div>
    </section>
    <div class="system-stack">
      <section class="card">
        <header class="card-header"><h2>{{ editing ? "编辑模型" : "添加模型" }}</h2><button v-if="editing" class="btn btn-small" type="button" @click="resetForm">取消编辑</button></header>
        <form class="card-body form-grid" @submit.prevent="save">
          <div class="field"><label for="model-name">显示名称</label><input id="model-name" v-model="form.display_name" class="input" required /></div>
          <div class="field"><label for="model-url">服务地址</label><input id="model-url" v-model="form.base_url" class="input" type="url" required /></div>
          <div class="field"><label for="model-identifier">模型标识</label><input id="model-identifier" v-model="form.model_identifier" class="input" required /></div>
          <div class="field"><label for="model-key">密钥</label><input id="model-key" v-model="form.api_key" class="input" type="password" autocomplete="off" :placeholder="editing ? '留空则保持原密钥' : '请输入密钥'" /></div>
          <p v-if="testMessage" class="up" role="status">{{ testMessage }}</p>
          <p v-if="errorMessage" class="field-error" role="alert">{{ errorMessage }}</p>
          <div class="form-actions"><button v-if="editing" class="btn" type="button" :disabled="testingId === editing.id" @click="testConnection(editing)">{{ testingId === editing.id ? "测试中" : "测试连接" }}</button><button v-if="editing && !editing.is_primary && !editing.is_fallback" class="btn" type="button" @click="remove(editing)">{{ deleteConfirmation === editing.id ? "确认删除" : "删除" }}</button><button class="btn btn-primary" type="submit">{{ editing ? "保存修改" : "添加模型" }}</button></div>
        </form>
      </section>
      <section class="card">
        <header class="card-header"><h2>调用顺序</h2></header>
        <form class="card-body selection-grid" @submit.prevent="saveSelection">
          <div class="field"><label for="primary-model">主模型</label><select id="primary-model" v-model="primaryId" class="select" required><option :value="null" disabled>请选择</option><option v-for="model in models" :key="model.id" :value="model.id">{{ model.display_name }}</option></select></div>
          <div class="field"><label for="fallback-model">辅助模型</label><select id="fallback-model" v-model="fallbackId" class="select"><option :value="null">关闭</option><option v-for="model in models" :key="model.id" :value="model.id">{{ model.display_name }}</option></select></div>
          <button class="btn" type="submit" :disabled="!models.length">保存选择</button>
        </form>
      </section>
    </div>
  </div>
</template>
