const state = {
  authenticated: false,
  user: null,
  permissions: new Set(),
  models: [],
  environments: [],
};

function $(id) {
  return document.getElementById(id);
}

function hasPermission(permission) {
  return state.permissions.has(permission);
}

function hasAnyPermission(permissions) {
  return permissions.some((perm) => state.permissions.has(perm));
}

function showMessage(message, type = "success") {
  const box = $("message-box");
  box.textContent = message;
  box.classList.remove("hidden", "error", "success");
  box.classList.add(type === "error" ? "error" : "success");
  setTimeout(() => box.classList.add("hidden"), 3800);
}

async function api(path, options = {}) {
  const method = options.method || "GET";
  const req = {
    method,
    credentials: "same-origin",
    headers: {},
  };
  if (options.json) {
    req.headers["Content-Type"] = "application/json";
    req.body = JSON.stringify(options.json);
  } else if (options.formData) {
    req.body = options.formData;
  }

  const resp = await fetch(path, req);
  let payload = {};
  try {
    payload = await resp.json();
  } catch (err) {
    payload = {};
  }
  if (!resp.ok) {
    throw new Error(payload.error || `HTTP ${resp.status}`);
  }
  return payload;
}

async function checkAuth() {
  const payload = await api("/api/whoami");
  if (!payload.authenticated) {
    state.authenticated = false;
    state.user = null;
    state.permissions = new Set();
    $("login-card").classList.remove("hidden");
    $("app-shell").classList.add("hidden");
    $("session-panel").classList.add("hidden");
    return;
  }

  state.authenticated = true;
  state.user = payload.user || null;
  state.permissions = new Set((payload.user && payload.user.permissions) || []);
  $("login-card").classList.add("hidden");
  $("app-shell").classList.remove("hidden");
  $("session-panel").classList.remove("hidden");
  $("current-user").textContent = `${state.user.username} (${(state.user.roles || []).join(", ")})`;

  const adminTabButton = document.querySelector('.tab-btn[data-tab="admin"]');
  const allowAdmin = hasAnyPermission(["admin:user_manage", "admin:role_manage"]);
  if (allowAdmin) {
    adminTabButton.classList.remove("hidden");
  } else {
    adminTabButton.classList.add("hidden");
    $("tab-admin").classList.remove("active");
  }
}

function switchTab(tabName) {
  const buttons = document.querySelectorAll(".tab-btn");
  buttons.forEach((btn) => {
    btn.classList.toggle("active", btn.dataset.tab === tabName);
  });
  const panels = document.querySelectorAll(".tab-panel");
  panels.forEach((panel) => {
    panel.classList.toggle("active", panel.id === `tab-${tabName}`);
  });
}

function parseCommaList(rawText) {
  return String(rawText || "")
    .split(",")
    .map((item) => item.trim())
    .filter((item) => item.length > 0);
}

async function doLogin() {
  const username = $("login-username").value.trim();
  const password = $("login-password").value;
  await api("/api/login", { method: "POST", json: { username, password } });
  showMessage("登录成功");
  await refreshAll();
}

async function doLogout() {
  await api("/api/logout", { method: "POST" });
  showMessage("已退出");
  await refreshAll();
}

async function refreshModelOverview() {
  if (!hasPermission("model:view")) {
    $("model-overview").innerHTML = "<p class='muted'>当前角色无查看权限。</p>";
    return;
  }

  const payload = await api("/api/models");
  state.models = payload.models || [];
  if (state.models.length === 0) {
    $("model-overview").innerHTML = "<p class='muted'>暂无模型版本。</p>";
    return;
  }

  const versionPromises = state.models.map((model) =>
    api(`/api/models/${encodeURIComponent(model.model_name)}/versions`)
  );
  const versionPayloads = await Promise.all(versionPromises);
  const versionMap = {};
  versionPayloads.forEach((entry) => {
    versionMap[entry.model_name] = entry.versions || [];
  });

  let html = "";
  state.models.forEach((model) => {
    const versions = versionMap[model.model_name] || [];
    html += `
      <article class="subpanel">
        <div class="section-head">
          <h3>${model.model_name}</h3>
          <span class="muted">最新: ${model.latest_version} / 共 ${model.version_count} 个版本</span>
        </div>
        <div class="table-wrap">
          <table>
            <thead>
              <tr>
                <th>版本</th>
                <th>状态</th>
                <th>创建时间</th>
                <th>在线环境</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
    `;

    versions.forEach((row) => {
      const activeEnvText = (row.active_envs || []).join(", ") || "-";
      const createdAt = row.created_at || "-";
      const actionButtons = [];
      actionButtons.push(
        `<button class="secondary-btn js-detail-btn" data-model="${model.model_name}" data-version="${row.version}">详情</button>`
      );
      if (hasPermission("model:promote")) {
        actionButtons.push(
          `<button class="primary-btn js-deploy-btn" data-model="${model.model_name}" data-version="${row.version}" data-env="staging">发布到staging</button>`
        );
        actionButtons.push(
          `<button class="primary-btn js-deploy-btn" data-model="${model.model_name}" data-version="${row.version}" data-env="production">发布到production</button>`
        );
      }
      html += `
        <tr>
          <td>${row.version}</td>
          <td>${row.status || "-"}</td>
          <td>${createdAt}</td>
          <td>${activeEnvText}</td>
          <td>${actionButtons.join(" ")}</td>
        </tr>
      `;
    });
    html += "</tbody></table></div></article>";
  });

  $("model-overview").innerHTML = html;
  bindVersionActionButtons(versionMap);
}

function bindVersionActionButtons(versionMap) {
  const detailButtons = document.querySelectorAll(".js-detail-btn");
  detailButtons.forEach((btn) => {
    btn.addEventListener("click", () => {
      const modelName = btn.dataset.model;
      const version = btn.dataset.version;
      const versions = versionMap[modelName] || [];
      const target = versions.find((row) => String(row.version) === String(version));
      $("version-detail").classList.remove("hidden");
      $("version-detail-title").textContent = `版本详情: ${modelName} ${version}`;
      $("version-detail-json").textContent = JSON.stringify(target || {}, null, 2);
    });
  });

  const deployButtons = document.querySelectorAll(".js-deploy-btn");
  deployButtons.forEach((btn) => {
    btn.addEventListener("click", async () => {
      const modelName = btn.dataset.model;
      const version = btn.dataset.version;
      const env = btn.dataset.env;
      const note = window.prompt(`发布备注（${modelName} ${version} -> ${env}）`, "") || "";
      await api("/api/deploy", {
        method: "POST",
        json: {
          model_name: modelName,
          version,
          env,
          note,
        },
      });
      showMessage(`已发布 ${modelName}:${version} 到 ${env}`);
      await refreshEnvironmentPanel();
      await refreshModelOverview();
    });
  });
}

async function refreshEnvironmentPanel() {
  if (!hasPermission("model:view")) {
    $("env-state").textContent = "当前角色无查看权限。";
    return;
  }
  const payload = await api("/api/environments");
  state.environments = payload.environments || [];
  const envSelect = $("deploy-env-select");
  const options = state.environments.map((item) => `<option value="${item.env}">${item.env}</option>`).join("");
  envSelect.innerHTML = options;
  if (envSelect.value === "" && state.environments.length > 0) {
    envSelect.value = state.environments[0].env;
  }
  await refreshCurrentEnvironmentState();
}

async function refreshCurrentEnvironmentState() {
  const env = $("deploy-env-select").value;
  if (!env) {
    $("env-state").textContent = "{}";
    return;
  }
  const payload = await api(`/api/env/${encodeURIComponent(env)}`);
  $("env-state").textContent = JSON.stringify(payload, null, 2);
}

async function doRollback() {
  if (!hasPermission("model:rollback")) {
    throw new Error("当前用户没有回滚权限。");
  }
  const env = $("deploy-env-select").value;
  const note = $("rollback-note").value.trim();
  const payload = await api("/api/rollback", {
    method: "POST",
    json: { env, note },
  });
  showMessage(`环境 ${env} 已回滚到上一版本`);
  $("env-state").textContent = JSON.stringify(payload.state || {}, null, 2);
  await refreshModelOverview();
}

async function refreshAuditTable() {
  if (!hasPermission("audit:view")) {
    $("audit-table").innerHTML = "<p class='muted'>当前角色无审计查看权限。</p>";
    return;
  }
  const modelName = $("audit-model-filter").value.trim();
  const suffix = modelName ? `?model_name=${encodeURIComponent(modelName)}&limit=200` : "?limit=200";
  const payload = await api(`/api/audit${suffix}`);
  const rows = payload.logs || [];
  if (rows.length === 0) {
    $("audit-table").innerHTML = "<p class='muted'>暂无日志。</p>";
    return;
  }

  let html = `
    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th>时间</th>
            <th>动作</th>
            <th>操作者</th>
            <th>模型</th>
            <th>摘要</th>
          </tr>
        </thead>
        <tbody>
  `;
  rows.forEach((row) => {
    const metadata = row.metadata || {};
    const modelNameMeta = row.model_name || metadata.model_name || metadata.name || "-";
    const summary = JSON.stringify(metadata);
    html += `
      <tr>
        <td>${row.timestamp || "-"}</td>
        <td>${row.action || "-"}</td>
        <td>${row.user || "-"}</td>
        <td>${modelNameMeta}</td>
        <td><code>${summary}</code></td>
      </tr>
    `;
  });
  html += "</tbody></table></div>";
  $("audit-table").innerHTML = html;
}

async function refreshAdminPanel() {
  const allowAdmin = hasAnyPermission(["admin:user_manage", "admin:role_manage"]);
  if (!allowAdmin) {
    $("role-list").textContent = "当前角色无管理权限。";
    $("user-list").textContent = "当前角色无管理权限。";
    return;
  }
  const [usersPayload, rolesPayload] = await Promise.all([api("/api/admin/users"), api("/api/admin/roles")]);
  $("user-list").textContent = JSON.stringify(usersPayload.users || [], null, 2);
  $("role-list").textContent = JSON.stringify(rolesPayload.roles || {}, null, 2);
}

async function submitImport(event) {
  event.preventDefault();
  if (!hasPermission("model:import")) {
    throw new Error("当前用户没有模型导入权限。");
  }
  const filesInput = $("import-files");
  if (!filesInput.files || filesInput.files.length === 0) {
    throw new Error("请至少上传一个文件。");
  }

  const formData = new FormData();
  formData.append("model_name", $("import-model-name").value.trim());
  formData.append("version", $("import-version").value.trim());
  formData.append("model_type", $("import-model-type").value.trim());
  formData.append("notes", $("import-notes").value.trim());
  formData.append("tags", $("import-tags").value.trim());
  formData.append("metrics", $("import-metrics").value.trim());
  for (const file of filesInput.files) {
    formData.append("files", file, file.name);
  }

  const payload = await api("/api/models/import", { method: "POST", formData });
  $("import-result").classList.remove("hidden");
  $("import-result").textContent = JSON.stringify(payload.model || {}, null, 2);
  showMessage("模型导入成功");
  filesInput.value = "";
  await refreshModelOverview();
  await refreshEnvironmentPanel();
  await refreshAuditTable();
}

async function submitCreateRole(event) {
  event.preventDefault();
  if (!hasPermission("admin:role_manage")) {
    throw new Error("当前用户没有角色管理权限。");
  }
  const roleName = $("role-name").value.trim();
  const permissions = parseCommaList($("role-permissions").value);
  const description = $("role-description").value.trim();
  await api("/api/admin/roles", {
    method: "POST",
    json: {
      role_name: roleName,
      permissions,
      description,
    },
  });
  showMessage(`角色 ${roleName} 创建成功`);
  $("create-role-form").reset();
  await refreshAdminPanel();
}

async function submitCreateUser(event) {
  event.preventDefault();
  if (!hasPermission("admin:user_manage")) {
    throw new Error("当前用户没有用户管理权限。");
  }
  const username = $("new-username").value.trim();
  const password = $("new-password").value;
  const roles = parseCommaList($("new-user-roles").value);
  await api("/api/admin/users", {
    method: "POST",
    json: { username, password, roles },
  });
  showMessage(`用户 ${username} 创建成功`);
  $("create-user-form").reset();
  await refreshAdminPanel();
}

async function submitSetUserRoles(event) {
  event.preventDefault();
  if (!hasPermission("admin:user_manage")) {
    throw new Error("当前用户没有用户管理权限。");
  }
  const username = $("set-role-username").value.trim();
  const roles = parseCommaList($("set-role-roles").value);
  await api("/api/admin/users/roles", {
    method: "POST",
    json: { username, roles },
  });
  showMessage(`用户 ${username} 角色更新成功`);
  $("set-role-form").reset();
  await refreshAdminPanel();
}

async function refreshAll() {
  await checkAuth();
  if (!state.authenticated) {
    return;
  }
  await Promise.all([refreshModelOverview(), refreshEnvironmentPanel(), refreshAuditTable(), refreshAdminPanel()]);
}

function bindEvents() {
  document.querySelectorAll(".tab-btn").forEach((btn) => {
    btn.addEventListener("click", () => {
      switchTab(btn.dataset.tab);
    });
  });

  $("login-btn").addEventListener("click", async () => {
    try {
      await doLogin();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("logout-btn").addEventListener("click", async () => {
    try {
      await doLogout();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("import-form").addEventListener("submit", async (event) => {
    try {
      await submitImport(event);
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("refresh-models-btn").addEventListener("click", async () => {
    try {
      await refreshModelOverview();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("refresh-env-btn").addEventListener("click", async () => {
    try {
      await refreshEnvironmentPanel();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("deploy-env-select").addEventListener("change", async () => {
    try {
      await refreshCurrentEnvironmentState();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("rollback-btn").addEventListener("click", async () => {
    try {
      await doRollback();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("refresh-audit-btn").addEventListener("click", async () => {
    try {
      await refreshAuditTable();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("audit-model-filter").addEventListener("change", async () => {
    try {
      await refreshAuditTable();
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("create-role-form").addEventListener("submit", async (event) => {
    try {
      await submitCreateRole(event);
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("create-user-form").addEventListener("submit", async (event) => {
    try {
      await submitCreateUser(event);
    } catch (err) {
      showMessage(err.message, "error");
    }
  });

  $("set-role-form").addEventListener("submit", async (event) => {
    try {
      await submitSetUserRoles(event);
    } catch (err) {
      showMessage(err.message, "error");
    }
  });
}

window.addEventListener("DOMContentLoaded", async () => {
  bindEvents();
  try {
    await refreshAll();
  } catch (err) {
    showMessage(err.message, "error");
  }
});

