const $ = (id) => document.getElementById(id);
const state = { bases: [], requests: [] };

function headers(json = false) {
  const value = {};
  if (json) value["Content-Type"] = "application/json";
  return value;
}

async function request(path, options = {}) {
  const response = await fetch(path, { ...options, headers: { ...headers(Boolean(options.body)), ...(options.headers || {}) } });
  let data = {};
  try { data = await response.json(); } catch (_) { /* empty response */ }
  if (!response.ok) throw new Error(data.message || data.error || `HTTP ${response.status}`);
  return data;
}

function notice(message = "", error = false) {
  $("notice").hidden = !message;
  $("notice").textContent = message;
  $("notice").className = `notice${error ? " error" : ""}`;
}

function render() {
  $("bases").replaceChildren(...state.bases.map((base) => {
    const row = document.createElement("tr");
    const cells = [base.base_id, base.server, base.database, base.user];
    cells.forEach((value) => { const td = document.createElement("td"); td.textContent = value; row.append(td); });
    const password = document.createElement("td");
    password.innerHTML = `<span class="badge ${base.has_password ? "" : "missing"}">${base.password_env ? "ENV · " + escapeHtml(base.password_env) : base.has_password ? "Сохранён" : "Не задан"}</span>`;
    row.append(password);
    const actions = document.createElement("td"); actions.className = "actions";
    const edit = document.createElement("button"); edit.className = "text-button"; edit.textContent = "Изменить"; edit.onclick = () => openEditor(base);
    const remove = document.createElement("button"); remove.className = "text-button danger"; remove.textContent = "Удалить"; remove.onclick = () => deleteBase(base);
    actions.append(edit, remove); row.append(actions); return row;
  }));
  $("empty").hidden = state.bases.length > 0;
  $("count").textContent = `${state.bases.length} ${state.bases.length === 1 ? "подключение" : "подключений"}`;
}

function renderRequests() {
  $("requests").replaceChildren(...state.requests.map((item) => {
    const row = document.createElement("tr");
    const values = [item.request_id, item.base_id, item.status, (item.objects || []).join(", "), item.created_at ? new Date(item.created_at * 1000).toLocaleString("ru-RU") : "—"];
    values.forEach((value, index) => { const td = document.createElement("td"); td.textContent = value || "—"; if (index === 2) td.className = `request-status ${item.status || ""}`; if (index === 3) td.className = "request-objects"; row.append(td); });
    return row;
  }));
  $("requestsEmpty").hidden = state.requests.length > 0;
  $("requestCount").textContent = `${state.requests.length} заявок`;
}

function escapeHtml(value) {
  const div = document.createElement("div"); div.textContent = value; return div.innerHTML;
}

async function load() {
  try {
    notice();
    const [data, repository] = await Promise.all([request("/admin/api/bases"), request("/admin/api/repository/requests")]);
    state.bases = data.bases || [];
    state.requests = repository.requests || [];
    $("statusDot").classList.add("online"); $("connectionText").textContent = "Адаптер подключён";
    render();
    renderRequests();
  } catch (error) {
    $("statusDot").classList.remove("online"); $("connectionText").textContent = "Требуется подключение";
    notice(error.message === "bearer_token_required" ? "Введите Bearer-токен адаптера." : error.message, true);
  }
}

function openEditor(base = null) {
  $("editorTitle").textContent = base ? "Редактировать базу" : "Новая база";
  $("originalId").value = base?.base_id || "";
  $("baseId").value = base?.base_id || ""; $("server").value = base?.server || "";
  $("database").value = base?.database || ""; $("user").value = base?.user || "";
  $("password").value = ""; $("passwordEnv").value = base?.password_env || "";
  $("developmentLayers").value = JSON.stringify(base?.development_layers || { base: { repository: { mode: "none", connection_state: "not_configured" }, support: { mode: "unknown" } } }, null, 2);
  $("passwordHint").textContent = base?.has_password ? "Пароль уже задан. Оставьте пустым, чтобы сохранить текущий." : "Задайте пароль или переменную окружения.";
  $("editor").showModal(); setTimeout(() => $("baseId").focus(), 30);
}

async function save(event) {
  event.preventDefault();
  if (!$("baseForm").reportValidity()) return;
  const original = $("originalId").value;
  let developmentLayers;
  try { developmentLayers = JSON.parse($("developmentLayers").value || "{}"); }
  catch (_) { notice("Слои разработки должны быть корректным JSON.", true); return; }
  const payload = { base_id: $("baseId").value.trim(), server: $("server").value.trim(), database: $("database").value.trim(), user: $("user").value.trim(), password: $("password").value, password_env: $("passwordEnv").value.trim(), development_layers: developmentLayers, repository: { enabled: false } };
  $("saveButton").disabled = true;
  try {
    await request(original ? `/admin/api/bases/${encodeURIComponent(original)}` : "/admin/api/bases", { method: original ? "PUT" : "POST", body: JSON.stringify(payload) });
    $("editor").close(); await load(); notice(original ? "Подключение обновлено." : "Подключение добавлено.");
  } catch (error) { notice(error.message, true); } finally { $("saveButton").disabled = false; }
}

async function deleteBase(base) {
  if (!confirm(`Удалить подключение «${base.base_id}»?`)) return;
  try { await request(`/admin/api/bases/${encodeURIComponent(base.base_id)}`, { method: "DELETE" }); await load(); notice("Подключение удалено."); }
  catch (error) { notice(error.message, true); }
}

$("refreshButton").onclick = load; $("addButton").onclick = () => openEditor(); $("baseForm").onsubmit = save;
load();
