// 外部系统连接管理：凭据字段由系统定义声明，只提交、不回显。
import { $ } from "./dom.js";
import { api } from "./api.js";
import { escapeHtml, fmtTime } from "./format.js";
import { dialogConfirm, message } from "./dialog.js";

let editingId = "";
let providerReady = false;
let definitions = [];
let systemsById = new Map();

function selectedDefinition() {
  return definitions.find(x => x.definition_id === $("ext-definition").value);
}

function renderCredentialFields(fields = []) {
  $("ext-credential-fields").innerHTML = fields.map(field => `
    <label>${escapeHtml(field.label)}<input
      data-credential-name="${escapeHtml(field.name)}"
      type="${field.secret ? "password" : "text"}"
      autocomplete="${escapeHtml(field.autocomplete || "off")}" required></label>
  `).join("");
}

function renderDefinitionOptions(items) {
  $("ext-definition").innerHTML = items.map(item =>
    `<option value="${escapeHtml(item.definition_id)}">${escapeHtml(item.name)}${item.host ? " · " + escapeHtml(item.host) : ""}</option>`
  ).join("");
}

function unconnectedDefinitions() {
  const connectedIds = new Set(Array.from(systemsById.values()).map(item => item.definition_id));
  return definitions.filter(item => !connectedIds.has(item.definition_id));
}

function resetForm() {
  editingId = "";
  $("ext-form-title").textContent = "新建外部系统连接";
  $("ext-name").disabled = false;
  $("ext-definition").disabled = false;
  $("ext-err").textContent = "";
  $("ext-save").textContent = "连接并验证";
  const available = unconnectedDefinitions();
  renderDefinitionOptions(available);
  const selected = available[0];
  $("ext-name").value = selected ? selected.name : "";
  renderCredentialFields((selected || {}).credential_fields || []);
}

function closeConnectionModal() {
  $("external-connection-modal").classList.remove("show");
  editingId = "";
}

function openConnectionModal(system = null) {
  if (!providerReady) return;
  resetForm();
  if (system) {
    editingId = system.external_system_id;
    $("ext-form-title").textContent = `更新凭据：${system.system_name || system.name}`;
    $("ext-name").value = system.name;
    $("ext-name").disabled = true;
    renderDefinitionOptions(definitions.filter(item => item.definition_id === system.definition_id));
    $("ext-definition").disabled = true;
    $("ext-save").textContent = "验证并更新";
    renderCredentialFields(system.credential_fields || []);
  }
  $("external-connection-modal").classList.add("show");
  $("ext-credential-fields").querySelector("input")?.focus();
}

export function closeExternalSystemsModal() {
  closeConnectionModal();
  $("external-modal").classList.remove("show");
}

async function openExternalSystemsModal() {
  $("external-modal").classList.add("show");
  await loadExternalSystems();
}

function connectorBadgeHtml(connector) {
  if (connector === "mcp") {
    return `<span class="ext-connector ext-connector-mcp" title="MCP 连接">
      <svg viewBox="0 0 16 16" aria-hidden="true"><path d="M5 2v3M11 2v3M3.5 5h9v2.5A4.5 4.5 0 0 1 8 12v2M6 14h4"/></svg>
      MCP
    </span>`;
  }
  return `<span class="ext-connector ext-connector-openapi" title="OpenAPI 连接">
    <svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="3" cy="8" r="1.5"/><circle cx="13" cy="4" r="1.5"/><circle cx="13" cy="12" r="1.5"/><path d="M4.5 7.4 11.5 4.6M4.5 8.6l7 2.8"/></svg>
    OpenAPI
  </span>`;
}

function cardHtml(item) {
  const good = item.status === "active";
  const badge = good
    ? "已连接"
    : (item.status === "disabled"
      ? "系统已停用"
      : (item.status === "needs_reverify" ? "需重新验证" : "需更新凭据"));
  const checked = item.last_verified_at ? fmtTime(item.last_verified_at) : "尚未验证";
  return `<div class="ext-card" data-id="${escapeHtml(item.external_system_id)}">
    <div class="ext-card-head"><span class="ext-card-name">${escapeHtml(item.name)}</span>${connectorBadgeHtml(item.connector)}<span class="sk-badge">${badge}</span></div>
    <div class="meta">${escapeHtml(item.system_name || "外部系统")} · ${escapeHtml(item.username_masked || "***")} · 最近验证 ${escapeHtml(checked)}</div>
    <div class="ext-actions">
      <button type="button" class="small" data-ext-test>测试连接</button>
      <button type="button" class="small" data-ext-edit>更新凭据</button>
      <button type="button" class="small danger" data-ext-delete>断开</button>
    </div>
  </div>`;
}

async function loadExternalSystems() {
  const provider = $("ext-provider");
  const list = $("ext-list");
  provider.textContent = "加载中…";
  list.innerHTML = '<div class="muted">加载中…</div>';
  try {
    const [catalog, response] = await Promise.all([
      api("GET", "/v1/external-system-providers"),
      api("GET", "/v1/external-systems"),
    ]);
    const providers = catalog.providers || [];
    definitions = providers.flatMap(item => item.definitions || []);
    providerReady = definitions.length > 0 && providers.some(item => item.configured);
    const rows = response.results || [];
    systemsById = new Map(rows.map(item => [item.external_system_id, item]));
    provider.textContent = providerReady
      ? `管理员已配置 ${definitions.length} 个外部系统，请选择后填写自己的访问凭据`
      : `暂没有可连接的外部系统${providers.find(item => item.reason)?.reason ? "：" + providers.find(item => item.reason).reason : "，请联系管理员配置"}`;
    const hasAvailableDefinition = unconnectedDefinitions().length > 0;
    $("ext-add").disabled = !providerReady || !hasAvailableDefinition;
    $("ext-add").title = hasAvailableDefinition ? "" : "所有可用外部系统均已连接";
    list.innerHTML = rows.length
      ? rows.map(cardHtml).join("")
      : '<div class="sk-empty">还没有外部系统连接。点击“新建连接”后，助手即可按你的权限查询。</div>';
  } catch (error) {
    providerReady = false;
    provider.textContent = "加载失败";
    list.innerHTML = `<div class="err">${escapeHtml(error.message)}</div>`;
    $("ext-add").disabled = true;
  }
}

$("hd-external").onclick = openExternalSystemsModal;
$("ext-close").onclick = closeExternalSystemsModal;
$("ext-add").onclick = () => openConnectionModal();
$("ext-form-close").onclick = closeConnectionModal;
$("ext-form-cancel").onclick = closeConnectionModal;
$("external-modal").addEventListener("click", event => {
  if (event.target.id === "external-modal") closeExternalSystemsModal();
});
$("external-connection-modal").addEventListener("click", event => {
  if (event.target.id === "external-connection-modal") closeConnectionModal();
});
$("external-connection-modal").addEventListener("keydown", event => {
  if (event.key === "Escape") closeConnectionModal();
});
$("ext-definition").onchange = () => {
  const selected = selectedDefinition();
  if (selected) $("ext-name").value = selected.name;
  renderCredentialFields((selected || {}).credential_fields || []);
};

$("ext-form").addEventListener("submit", async event => {
  event.preventDefault();
  if (!providerReady) return;
  const name = $("ext-name").value.trim();
  const definitionId = $("ext-definition").value;
  const credentials = Object.fromEntries(
    Array.from($("ext-credential-fields").querySelectorAll("[data-credential-name]"))
      .map(input => [input.dataset.credentialName, input.value]),
  );
  if (Object.values(credentials).some(value => !value.trim()) || (!editingId && (!name || !definitionId))) {
    $("ext-err").textContent = "请填写连接名称和全部访问凭据";
    return;
  }
  const button = $("ext-save");
  const wasEditing = Boolean(editingId);
  button.disabled = true;
  button.textContent = "正在验证…";
  $("ext-err").textContent = "";
  try {
    if (wasEditing) {
      await api("PUT", `/v1/external-systems/${editingId}/credentials`, { credentials });
      message("外部系统已重新连接，凭据已更新", "success");
    } else {
      await api("POST", "/v1/external-systems", { definition_id: definitionId, name, credentials });
      message("外部系统已连接；下一轮对话即可使用", "success");
    }
    closeConnectionModal();
    await loadExternalSystems();
  } catch (error) {
    $("ext-err").textContent = error.message;
  } finally {
    button.disabled = false;
    button.textContent = wasEditing ? "验证并更新" : "连接并验证";
  }
});

$("ext-list").addEventListener("click", async event => {
  const card = event.target.closest(".ext-card");
  if (!card) return;
  const id = card.dataset.id;

  if (event.target.closest("[data-ext-test]")) {
    const button = event.target.closest("button");
    button.disabled = true;
    try {
      const result = await api("POST", `/v1/external-systems/${id}/test`);
      const operationCount = result.operation_count ?? result.tool_count ?? 0;
      message(result.ok ? `连接正常，可用接口 ${operationCount} 个` : `连接失败：${result.error}`, result.ok ? "success" : "error");
      await loadExternalSystems();
    } catch (error) { message("测试失败：" + error.message, "error"); }
    finally { button.disabled = false; }
    return;
  }
  if (event.target.closest("[data-ext-delete]")) {
    const name = card.querySelector(".ext-card-name").textContent;
    if (!await dialogConfirm({ title:"断开外部系统", message:`断开「${name}」？保存的密文凭据和连接配置将被清除。`, okText:"断开", danger:true })) return;
    try {
      await api("DELETE", `/v1/external-systems/${id}`);
      message("外部系统已断开", "success");
      await loadExternalSystems();
    } catch (error) { message("断开失败：" + error.message, "error"); }
    return;
  }
  openConnectionModal(systemsById.get(id));
});
