(function (global) {
  "use strict";

  const GFE_DYNAMIC_KEYS = ["usp", "nel"];

  let catalog = [];
  let profiles = [];
  let selectedId = null;
  let draftNorms = {};
  let dynamicNorms = {};
  let normCoverage = null;
  let normSourceMap = {};
  let resolvedNormsPreview = {};
  let seedCatalog = [];
  let seedCatalogRation = null;
  let normsCoverageTimer = null;

  async function api(path, opts) {
    const resp = await fetch(path, opts);
    const data = await resp.json().catch(() => ({}));
    if (!resp.ok) throw new Error(data.message || `Наука, чёрт возьми — ошибка ${resp.status}`);
    return data;
  }

  function escapeHtml(s) {
    return String(s ?? "")
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;");
  }

  function notify() {
    return global.WespZootechNotify?.createAdapter?.();
  }

  function readMass() {
    const raw = document.getElementById("labProfileMass")?.value?.trim();
    if (raw === "") return null;
    const n = Number(raw);
    return Number.isNaN(n) ? null : n;
  }

  function readMilk() {
    const raw = document.getElementById("labProfileMilk")?.value?.trim();
    if (raw === "") return null;
    const n = Number(raw);
    return Number.isNaN(n) ? null : n;
  }

  function readNumInput(id) {
    const raw = document.getElementById(id)?.value?.trim();
    if (raw === "") return null;
    const n = Number(raw);
    return Number.isNaN(n) ? null : n;
  }

  function readNormsMethod() {
    return document.getElementById("labProfileNormsMethod")?.value || "wesp";
  }

  function readNormsParams() {
    const method = readNormsMethod();
    if (method === "wesp") return {};
    const params = {
      milkFatPct: readNumInput("labProfileFat") ?? 4,
      lactationNo: readNumInput("labProfileLactation") ?? 2,
    };
    if (method === "racion_piter") {
      params.koncOeSv = readNumInput("labProfileKonc") ?? 10.3;
    }
    return params;
  }

  function syncNormsMethodUi() {
    const method = readNormsMethod();
    const racionBox = document.getElementById("labProfileRacionFields");
    const piterOnly = document.querySelectorAll(".lab-profile-piter-only");
    if (racionBox) racionBox.classList.toggle("d-none", method === "wesp");
    piterOnly.forEach((el) => el.classList.toggle("d-none", method !== "racion_piter"));
    syncSourceFilterOptions(method);
    renderNormsSummary();
    scheduleNormsCoverageRefresh();
  }

  function syncSourceFilterOptions(method) {
    const sel = document.getElementById("labProfilesSourceFilter");
    if (!sel) return;
    sel.querySelectorAll("option[data-racion-only]").forEach((opt) => {
      opt.hidden = method === "wesp";
      opt.disabled = method === "wesp";
    });
    if (method === "wesp" && ["racion", "racion_only", "derived", "new_racion"].includes(sel.value)) {
      sel.value = "all";
    }
  }

  function buildNormSourceMap(coverage, storedNorms) {
    const map = {};
    if (coverage) {
      (coverage.racion || []).forEach((k) => {
        map[k] = "racion";
      });
      (coverage.derived || []).forEach((k) => {
        map[k] = "derived";
      });
      (coverage.fallback || []).forEach((k) => {
        if (!map[k]) map[k] = "fallback";
      });
      (coverage.missing || []).forEach((k) => {
        if (!map[k]) map[k] = "missing";
      });
    }
    Object.keys(storedNorms || {}).forEach((k) => {
      if (!map[k]) map[k] = "stored";
    });
    return map;
  }

  function normSourceLabel(src) {
    const labels = {
      racion: "RACION",
      derived: "расч.",
      fallback: "WESP",
      stored: "БД",
      missing: "—",
      gfe: "GfE",
    };
    return labels[src] || "—";
  }

  function normSourceBadge(src) {
    if (!src || src === "missing") return '<span class="norm-source-badge norm-source-badge--empty">—</span>';
    const cls = `norm-source-badge norm-source-badge--${src}`;
    return `<span class="${cls}" title="${escapeHtml(normSourceLabel(src))}">${escapeHtml(normSourceLabel(src))}</span>`;
  }

  function isInDb(key) {
    const b = draftNorms[key] || {};
    return b.min != null || b.max != null;
  }

  function matchesSourceFilter(key) {
    const filter = document.getElementById("labProfilesSourceFilter")?.value || "all";
    if (filter === "all") return true;
    const src = normSourceMap[key];
    if (filter === "in_db") return isInDb(key);
    if (filter === "seed") return src === "fallback" || src === "stored";
    if (filter === "racion") return src === "racion" || src === "derived";
    if (filter === "racion_only") return src === "racion";
    if (filter === "derived") return src === "derived";
    if (filter === "new_racion") return src === "racion" || src === "derived";
    return true;
  }

  function countNormSources() {
    const counts = { inDb: 0, racion: 0, derived: 0, fallback: 0, stored: 0, missing: 0 };
    const seen = new Set();
    catalog.forEach((c) => seen.add(c.key));
    Object.keys(draftNorms).forEach((k) => seen.add(k));
    if (normCoverage) {
      (normCoverage.racion || []).forEach((k) => seen.add(k));
      (normCoverage.derived || []).forEach((k) => seen.add(k));
      (normCoverage.fallback || []).forEach((k) => seen.add(k));
      (normCoverage.missing || []).forEach((k) => seen.add(k));
    }
    seen.forEach((key) => {
      if (isInDb(key)) counts.inDb += 1;
      const src = normSourceMap[key];
      if (src === "racion") counts.racion += 1;
      else if (src === "derived") counts.derived += 1;
      else if (src === "fallback") counts.fallback += 1;
      else if (src === "stored") counts.stored += 1;
      else if (src === "missing") counts.missing += 1;
    });
    return counts;
  }

  function renderNormsSummary() {
    const panel = document.getElementById("labProfilesNormsSummary");
    const text = document.getElementById("labProfilesNormsSummaryText");
    const form = document.getElementById("labProfilesForm");
    if (!panel || !text || !form || form.hidden) {
      if (panel) panel.hidden = true;
      return;
    }
    const method = readNormsMethod();
    const counts = countNormSources();
    if (method === "wesp") {
      panel.hidden = false;
      text.textContent = `В БД ${counts.inDb} показ. · справочник/ручные ${counts.stored + counts.fallback}`;
      return;
    }
    if (!normCoverage) {
      panel.hidden = false;
      text.textContent = "Укажи массу и удой — разберём источники RACION";
      return;
    }
    panel.hidden = false;
    const racTotal = counts.racion + counts.derived;
    const withMin = normCoverage.withMin != null ? normCoverage.withMin : racTotal + counts.fallback;
    text.textContent =
      `В БД ${counts.inDb} · RACION ${racTotal} (NPitV ${counts.racion} + расч. ${counts.derived}) · ` +
      `WESP fallback ${counts.fallback} · с min ${withMin}/${normCoverage.total ?? "—"}`;
  }

  function applyNormsCoveragePayload(payload) {
    normCoverage = payload.coverage || null;
    resolvedNormsPreview = payload.resolvedIndicators || {};
    if (payload.dynamicNorms) {
      dynamicNorms = { ...dynamicNorms, ...payload.dynamicNorms };
    }
    normSourceMap = buildNormSourceMap(normCoverage, draftNorms);
    renderNormsSummary();
    renderNormsTable();
  }

  async function refreshNormsCoverage() {
    const method = readNormsMethod();
    const mass = readMass();
    const milk = readMilk();
    if (method === "wesp") {
      normCoverage = null;
      resolvedNormsPreview = {};
      normSourceMap = buildNormSourceMap(null, draftNorms);
      GFE_DYNAMIC_KEYS.forEach((key) => {
        if (dynamicNorms[key]?.min != null && !isInDb(key)) normSourceMap[key] = "gfe";
      });
      renderNormsSummary();
      renderNormsTable();
      return;
    }
    if (mass == null || milk == null) {
      normCoverage = null;
      normSourceMap = buildNormSourceMap(null, draftNorms);
      renderNormsSummary();
      renderNormsTable();
      return;
    }
    const q = new URLSearchParams({ method, mass_kg: String(mass), milk_yield_kg: String(milk) });
    if (selectedId) q.set("profile_id", selectedId);
    const np = readNormsParams();
    if (np.milkFatPct != null) q.set("milk_fat_pct", String(np.milkFatPct));
    if (np.lactationNo != null) q.set("lactation_no", String(np.lactationNo));
    if (np.koncOeSv != null) q.set("konc_oe_sv", String(np.koncOeSv));
    try {
      const preview = await api(`/api/lab/norms-preview?${q.toString()}`);
      applyNormsCoveragePayload(preview);
    } catch (err) {
      notify()?.error?.(err.message);
    }
  }

  function scheduleNormsCoverageRefresh() {
    if (normsCoverageTimer) clearTimeout(normsCoverageTimer);
    normsCoverageTimer = setTimeout(() => {
      refreshNormsCoverage().catch((e) => notify()?.error?.(e.message, { fallback: "Не удалось выполнить операцию" }));
    }, 350);
  }

  function fillNormsParamsFromProfile(p) {
    const method = p.normsMethod || "wesp";
    const sel = document.getElementById("labProfileNormsMethod");
    if (sel) sel.value = method;
    const np = p.normsParams || {};
    const fat = document.getElementById("labProfileFat");
    const lact = document.getElementById("labProfileLactation");
    const konc = document.getElementById("labProfileKonc");
    if (fat) fat.value = np.milkFatPct != null ? np.milkFatPct : 4;
    if (lact) lact.value = np.lactationNo != null ? np.lactationNo : 2;
    if (konc) konc.value = np.koncOeSv != null ? np.koncOeSv : 10.3;
    syncNormsMethodUi();
  }

  /** GfE 2001 — parity app/lab/calc/gfe_norms.py */
  function gfeUspMinG(massKg, milkKg) {
    if (!massKg || massKg <= 0) return null;
    return 0.09 * massKg ** 0.75 * 6.25 + Math.max(milkKg || 0, 0) * 85;
  }

  function gfeNelMinMj(massKg, milkKg) {
    if (!massKg || massKg <= 0) return null;
    return 0.293 * massKg ** 0.75 + Math.max(milkKg || 0, 0) * 3.3;
  }

  function computeDynamicNormsLocal() {
    const mass = readMass();
    const milk = readMilk();
    const out = {};
    const usp = gfeUspMinG(mass, milk);
    if (usp != null) {
      out.usp = { min: usp, formula: "0.09×масса^0.75×6.25 + удой×85" };
    }
    const nel = gfeNelMinMj(mass, milk);
    if (nel != null) {
      out.nel = { min: nel, formula: "0.293×масса^0.75 + удой×3.3" };
    }
    return out;
  }

  function formatGfe(v) {
    const n = Number(v);
    if (Number.isNaN(n)) return "—";
    return Math.abs(n) >= 100 ? n.toFixed(1) : n.toFixed(2);
  }

  function refreshDynamicNorms() {
    dynamicNorms = computeDynamicNormsLocal();
    renderGfePanel();
    renderNormsTable();
  }

  function renderGfePanel() {
    const panel = document.getElementById("labProfilesGfePanel");
    const vals = document.getElementById("labProfilesGfeValues");
    const form = document.getElementById("labProfilesForm");
    if (!panel || !form || form.hidden) {
      if (panel) panel.hidden = true;
      return;
    }
    const mass = readMass();
    if (!mass || mass <= 0) {
      panel.hidden = true;
      return;
    }
    panel.hidden = false;
    const parts = [];
    if (dynamicNorms.usp?.min != null) {
      parts.push(`min уСП ≈ ${formatGfe(dynamicNorms.usp.min)} г`);
    }
    if (dynamicNorms.nel?.min != null) {
      parts.push(`min ЧЭЛ ≈ ${formatGfe(dynamicNorms.nel.min)} МДж`);
    }
    if (vals) vals.textContent = parts.join(" · ") || "—";
    const enabled = parts.length > 0;
    ["labProfilesGfeApplyUsp", "labProfilesGfeApplyNel", "labProfilesGfeApplyAll"].forEach((id) => {
      const btn = document.getElementById(id);
      if (btn) btn.disabled = !enabled;
    });
  }

  function applyGfeMin(keys) {
    collectNormsFromTable();
    let applied = 0;
    keys.forEach((key) => {
      const v = dynamicNorms[key]?.min;
      if (v == null) return;
      const cur = draftNorms[key] || {};
      if (cur.min != null) return;
      draftNorms[key] = { ...cur, min: v };
      applied += 1;
    });
    renderNormsTable();
    if (applied) {
      notify()?.success?.("Подставлено по GfE — нажми «Запомни это»");
    } else {
      notify()?.error?.("Нижние границы уже заданы или нет массы");
    }
  }

  function syncDeleteButton() {
    const btn = document.getElementById("labProfilesDelete");
    if (btn) btn.hidden = !selectedId;
  }

  function readRationType() {
    return document.getElementById("labProfileType")?.value || "DAIRY";
  }

  function syncSeedPanelVisibility() {
    const panel = document.getElementById("labProfilesSeedPanel");
    const form = document.getElementById("labProfilesForm");
    if (panel) panel.hidden = !form || form.hidden;
  }

  function filteredSeedCatalog() {
    const q = (document.getElementById("labProfilesSeedSearch")?.value || "").trim().toLowerCase();
    if (!q) return seedCatalog;
    return seedCatalog.filter((e) => {
      const hay = `${e.externalNo} ${e.label} ${e.massKg ?? ""}`.toLowerCase();
      return hay.includes(q);
    });
  }

  function renderSeedSelect() {
    const sel = document.getElementById("labProfilesSeedSelect");
    const applyBtn = document.getElementById("labProfilesSeedApply");
    if (!sel) return;
    const prev = sel.value;
    const rows = filteredSeedCatalog();
    const opts = ['<option value="">— выбери строку —</option>'].concat(
      rows.map((e) => {
        const mass = e.massKg != null ? ` · ${e.massKg} кг` : "";
        const cnt = e.indicatorCount != null ? ` · ${e.indicatorCount} показ.` : "";
        return `<option value="${escapeHtml(String(e.externalNo))}">№${escapeHtml(String(e.externalNo))} — ${escapeHtml(e.label)}${escapeHtml(mass)}${escapeHtml(cnt)}</option>`;
      })
    );
    sel.innerHTML = opts.join("");
    if (prev && rows.some((e) => String(e.externalNo) === prev)) {
      sel.value = prev;
    }
    if (applyBtn) applyBtn.disabled = !sel.value;
  }

  async function loadSeedCatalog(rationType) {
    const ration = rationType || readRationType();
    if (seedCatalogRation === ration && seedCatalog.length) {
      renderSeedSelect();
      return;
    }
    const data = await api(`/api/lab/seed-norms-catalog?ration_type=${encodeURIComponent(ration)}`);
    seedCatalog = data.entries || [];
    seedCatalogRation = ration;
    renderSeedSelect();
  }

  async function applySeedNorms() {
    const sel = document.getElementById("labProfilesSeedSelect");
    const externalNo = sel?.value;
    if (!externalNo) {
      notify()?.error?.("Выбери строку справочника");
      return;
    }
    const filled = Object.values(draftNorms).filter((b) => b.min != null || b.max != null).length;
    if (filled > 0) {
      const ok = global.confirm("Заменить текущие границы нормами из справочника?");
      if (!ok) return;
    }
    const ration = readRationType();
    const entry = await api(
      `/api/lab/seed-norms-catalog/${encodeURIComponent(externalNo)}?ration_type=${encodeURIComponent(ration)}`
    );
    draftNorms = { ...(entry.indicators || {}) };
    if (entry.massKg != null) {
      document.getElementById("labProfileMass").value = entry.massKg;
    }
    document.getElementById("labProfileExternal").value = entry.externalNo;
    const labelEl = document.getElementById("labProfileLabel");
    if (labelEl && !labelEl.value.trim()) {
      labelEl.value = entry.label || "";
    }
    refreshDynamicNorms();
    notify()?.success?.(`Загружено ${Object.keys(draftNorms).length} показателей — нажми «Запомни это»`);
  }

  function filteredProfiles() {
    const type = document.getElementById("labProfilesType")?.value || "";
    const q = (document.getElementById("labProfilesSearch")?.value || "").trim().toLowerCase();
    return profiles.filter((p) => {
      if (type && p.rationType !== type) return false;
      if (!q) return true;
      const hay = `${p.profileKey} ${p.label}`.toLowerCase();
      return hay.includes(q);
    });
  }

  function renderList() {
    const el = document.getElementById("labProfilesList");
    if (!el) return;
    const rows = filteredProfiles();
    if (!rows.length) {
      el.innerHTML = '<div class="lab-sandbox-empty">Стандартов нет — создай новый</div>';
      return;
    }
    el.innerHTML = rows
      .map(
        (p) =>
          `<button type="button" class="${p.id === selectedId ? "is-active" : ""}" data-id="${escapeHtml(p.id)}">` +
          `${escapeHtml(p.label)}` +
          `<span class="profile-key">${escapeHtml(p.profileKey)} · ${escapeHtml(p.rationType)}</span>` +
          `</button>`
      )
      .join("");
  }

  function indicatorRows() {
    const onlyCalc = document.getElementById("labProfilesOnlyCalc")?.checked;
    const onlyFilled = document.getElementById("labProfilesOnlyFilled")?.checked;
    const q = (document.getElementById("labProfilesNormSearch")?.value || "").trim().toLowerCase();
    const extraKeys = Object.keys(draftNorms).filter((k) => !catalog.some((c) => c.key === k));
    const rows = [
      ...catalog.map((c) => ({ ...c })),
      ...extraKeys.map((k) => ({ key: k, label: k, unit: "", inCalc: false })),
    ];
    return rows.filter((row) => {
      if (onlyCalc && !row.inCalc) return false;
      const b = draftNorms[row.key] || {};
      const has = b.min != null || b.max != null;
      if (onlyFilled && !has) return false;
      if (!matchesSourceFilter(row.key)) return false;
      if (q) {
        const hay = `${row.key} ${row.label}`.toLowerCase();
        if (!hay.includes(q)) return false;
      }
      return true;
    });
  }

  function renderNormsTable() {
    const tbody = document.getElementById("labProfilesNormsBody");
    const countEl = document.getElementById("labProfilesNormCount");
    if (!tbody) return;
    const rows = indicatorRows();
    tbody.innerHTML = rows
      .map((row) => {
        const b = draftNorms[row.key] || {};
        const min = b.min != null ? b.min : "";
        const max = b.max != null ? b.max : "";
        const badge = row.inCalc ? '<span class="norm-calc-badge ms-1">в деле</span>' : "";
        const unit = row.unit ? ` <span class="text-muted">${escapeHtml(row.unit)}</span>` : "";
        const dyn = dynamicNorms[row.key];
        const gfeHint =
          dyn?.min != null && min === ""
            ? `<small class="text-muted d-block">GfE ≈ ${formatGfe(dyn.min)}${dyn.formula ? ` (${escapeHtml(dyn.formula)})` : ""}</small>`
            : "";
        const gfeBadge = GFE_DYNAMIC_KEYS.includes(row.key)
          ? '<span class="norm-calc-badge ms-1" title="min по GfE 2001, если нижняя пуста">GfE</span>'
          : "";
        let src = normSourceMap[row.key];
        if (!src && isInDb(row.key)) src = "stored";
        const dbBadge = isInDb(row.key) ? '<span class="norm-source-badge norm-source-badge--db" title="Сохранено в БД">БД</span>' : "";
        const srcBadge = normSourceBadge(src);
        const resolved = resolvedNormsPreview[row.key];
        const resolvedHint =
          resolved?.min != null && min !== "" && Number(min) !== Number(resolved.min)
            ? `<small class="text-muted d-block">RACION ≈ ${formatGfe(resolved.min)}</small>`
            : resolved?.min != null && min === ""
              ? `<small class="text-muted d-block">RACION ≈ ${formatGfe(resolved.min)} (не в БД)</small>`
              : "";
        return (
          `<tr data-key="${escapeHtml(row.key)}">` +
          `<td>${escapeHtml(row.label)}${badge}${gfeBadge}${unit}${gfeHint}${resolvedHint}</td>` +
          `<td class="lab-profiles-source-cell">${dbBadge}${srcBadge}</td>` +
          `<td><input type="number" class="form-control form-control-sm" data-bound="min" step="any" value="${min}"` +
          `${dyn?.min != null && min === "" ? ` placeholder="${formatGfe(dyn.min)}"` : ""}></td>` +
          `<td><input type="number" class="form-control form-control-sm" data-bound="max" step="any" value="${max}"></td>` +
          `</tr>`
        );
      })
      .join("");
    if (countEl) {
      const filled = Object.values(draftNorms).filter((b) => b.min != null || b.max != null).length;
      const counts = countNormSources();
      const method = readNormsMethod();
      const srcPart =
        method === "wesp"
          ? ` · в БД ${counts.inDb}`
          : ` · БД ${counts.inDb} · RACION ${counts.racion + counts.derived} · WESP ${counts.fallback}`;
      countEl.textContent = `В таблице ${rows.length} · с границами ${filled}${srcPart}`;
    }
    renderNormsSummary();
  }

  function collectNormsFromTable() {
    const out = { ...draftNorms };
    document.querySelectorAll("#labProfilesNormsBody tr[data-key]").forEach((tr) => {
      const key = tr.getAttribute("data-key");
      if (!key) return;
      const minIn = tr.querySelector('[data-bound="min"]');
      const maxIn = tr.querySelector('[data-bound="max"]');
      const minRaw = minIn?.value?.trim();
      const maxRaw = maxIn?.value?.trim();
      const min = minRaw === "" ? null : Number(minRaw);
      const max = maxRaw === "" ? null : Number(maxRaw);
      if (min == null && max == null) {
        delete out[key];
      } else {
        out[key] = {
          min: Number.isNaN(min) ? null : min,
          max: Number.isNaN(max) ? null : max,
        };
      }
    });
    draftNorms = out;
  }

  async function selectProfile(id) {
    selectedId = id;
    syncDeleteButton();
    renderList();
    const empty = document.getElementById("labProfilesEmpty");
    const form = document.getElementById("labProfilesForm");
    if (!id) {
      if (empty) empty.hidden = false;
      if (form) form.hidden = true;
      syncSeedPanelVisibility();
      return;
    }
    const p = await api(`/api/lab/animal-profiles/${encodeURIComponent(id)}`);
    if (empty) empty.hidden = true;
    if (form) form.hidden = false;
    document.getElementById("labProfileKey").value = p.profileKey || "";
    document.getElementById("labProfileLabel").value = p.label || "";
    document.getElementById("labProfileType").value = p.rationType || "BEEF";
    document.getElementById("labProfileMass").value = p.massKg != null ? p.massKg : "";
    document.getElementById("labProfileMilk").value = p.milkYieldKg != null ? p.milkYieldKg : "";
    document.getElementById("labProfileExternal").value = p.externalNo != null ? p.externalNo : "";
    fillNormsParamsFromProfile(p);
    draftNorms = { ...(p.norms || p.normsData?.indicators || {}) };
    normCoverage = p.coverage || p.normsData?.coverage || null;
    resolvedNormsPreview = p.resolvedNorms || p.normsData?.resolvedIndicators || {};
    normSourceMap = buildNormSourceMap(normCoverage, draftNorms);
    refreshDynamicNorms();
    syncSourceFilterOptions(readNormsMethod());
    renderNormsSummary();
    scheduleNormsCoverageRefresh();
    syncSeedPanelVisibility();
    loadSeedCatalog(p.rationType || "DAIRY").catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
  }

  function newProfile() {
    selectedId = null;
    syncDeleteButton();
    renderList();
    document.getElementById("labProfilesEmpty").hidden = true;
    document.getElementById("labProfilesForm").hidden = false;
    document.getElementById("labProfileKey").value = "";
    document.getElementById("labProfileLabel").value = "";
    document.getElementById("labProfileType").value = "DAIRY";
    document.getElementById("labProfileMass").value = "";
    document.getElementById("labProfileMilk").value = "";
    document.getElementById("labProfileExternal").value = "";
    fillNormsParamsFromProfile({ normsMethod: "wesp", normsParams: {} });
    draftNorms = {};
    normCoverage = null;
    resolvedNormsPreview = {};
    normSourceMap = {};
    refreshDynamicNorms();
    syncSourceFilterOptions("wesp");
    renderNormsSummary();
    syncSeedPanelVisibility();
    loadSeedCatalog("DAIRY").catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
  }

  async function saveProfile() {
    collectNormsFromTable();
    const key = document.getElementById("labProfileKey")?.value?.trim();
    const label = document.getElementById("labProfileLabel")?.value?.trim();
    const rationType = document.getElementById("labProfileType")?.value || "BEEF";
    const massRaw = document.getElementById("labProfileMass")?.value?.trim();
    const milkRaw = document.getElementById("labProfileMilk")?.value?.trim();
    const extRaw = document.getElementById("labProfileExternal")?.value?.trim();
    if (!key || !label) {
      notify()?.error?.("Укажи код и название — я предупреждал");
      return;
    }
    const payload = {
      profileKey: key,
      label,
      rationType,
      indicators: draftNorms,
      normsMethod: readNormsMethod(),
      normsParams: readNormsParams(),
    };
    if (massRaw !== "") payload.massKg = Number(massRaw);
    payload.milkYieldKg = milkRaw === "" ? null : Number(milkRaw);
    if (extRaw !== "") payload.externalNo = Number(extRaw);
    const method = selectedId ? "PUT" : "POST";
    const url = selectedId
      ? `/api/lab/animal-profiles/${encodeURIComponent(selectedId)}`
      : "/api/lab/animal-profiles";
    await api(url, {
      method,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    notify()?.success?.("Стандарт сохранён. Ты чертовски прав");
    const typeFilter = document.getElementById("labProfilesType")?.value || "";
    const data = await api(
      `/api/lab/animal-profiles${typeFilter ? `?ration_type=${encodeURIComponent(typeFilter)}` : ""}`
    );
    profiles = data.profiles || [];
    if (!selectedId && profiles.length) {
      const hit = profiles.find((p) => p.profileKey === key);
      if (hit) selectedId = hit.id;
    }
    renderList();
    if (selectedId) await selectProfile(selectedId);
  }

  async function deleteProfile() {
    if (!selectedId) return;
    const label = document.getElementById("labProfileLabel")?.value?.trim() || selectedId;
    if (!global.confirm(`Удалить «${label}»? Никаких полумер.`)) return;
    await api(`/api/lab/animal-profiles/${encodeURIComponent(selectedId)}`, { method: "DELETE" });
    notify()?.success?.("Стандарт снесён. Say my name.");
    selectedId = null;
    syncDeleteButton();
    const typeFilter = document.getElementById("labProfilesType")?.value || "";
    const data = await api(
      `/api/lab/animal-profiles${typeFilter ? `?ration_type=${encodeURIComponent(typeFilter)}` : ""}`
    );
    profiles = data.profiles || [];
    document.getElementById("labProfilesEmpty").hidden = false;
    document.getElementById("labProfilesForm").hidden = true;
    renderList();
  }

  async function init() {
    const [cat, prof] = await Promise.all([
      api("/api/lab/norm-indicators"),
      api("/api/lab/animal-profiles"),
    ]);
    catalog = cat.indicators || [];
    profiles = prof.profiles || [];
    renderList();
  }

  function bind() {
    document.getElementById("labProfilesList")?.addEventListener("click", (ev) => {
      const btn = ev.target.closest("button[data-id]");
      if (!btn) return;
      selectProfile(btn.getAttribute("data-id")).catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
    });
    document.getElementById("labProfilesType")?.addEventListener("change", async () => {
      const type = document.getElementById("labProfilesType")?.value || "";
      const data = await api(
        `/api/lab/animal-profiles${type ? `?ration_type=${encodeURIComponent(type)}` : ""}`
      );
      profiles = data.profiles || [];
      renderList();
    });
    document.getElementById("labProfilesSearch")?.addEventListener("input", renderList);
    document.getElementById("labProfilesOnlyFilled")?.addEventListener("change", renderNormsTable);
    document.getElementById("labProfilesOnlyCalc")?.addEventListener("change", renderNormsTable);
    document.getElementById("labProfilesSourceFilter")?.addEventListener("change", renderNormsTable);
    document.getElementById("labProfilesNormSearch")?.addEventListener("input", renderNormsTable);
    document.getElementById("labProfilesNormsRefresh")?.addEventListener("click", () => {
      refreshNormsCoverage().catch((e) => notify()?.error?.(e.message, { fallback: "Не удалось выполнить операцию" }));
    });
    document.getElementById("labProfilesNew")?.addEventListener("click", newProfile);
    document.getElementById("labProfilesSave")?.addEventListener("click", () => {
      saveProfile().catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
    });
    document.getElementById("labProfilesDelete")?.addEventListener("click", () => {
      deleteProfile().catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
    });
    document.getElementById("labProfilesNormsBody")?.addEventListener("change", (ev) => {
      if (ev.target.matches("input[data-bound]")) collectNormsFromTable();
    });
    document.getElementById("labProfileMass")?.addEventListener("input", () => {
      refreshDynamicNorms();
      scheduleNormsCoverageRefresh();
    });
    document.getElementById("labProfileMilk")?.addEventListener("input", () => {
      refreshDynamicNorms();
      scheduleNormsCoverageRefresh();
    });
    document.getElementById("labProfileNormsMethod")?.addEventListener("change", syncNormsMethodUi);
    ["labProfileFat", "labProfileLactation", "labProfileKonc"].forEach((id) => {
      document.getElementById(id)?.addEventListener("input", scheduleNormsCoverageRefresh);
    });
    document.getElementById("labProfileType")?.addEventListener("change", () => {
      seedCatalogRation = null;
      loadSeedCatalog(readRationType()).catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
    });
    document.getElementById("labProfilesSeedSearch")?.addEventListener("input", renderSeedSelect);
    document.getElementById("labProfilesSeedSelect")?.addEventListener("change", () => {
      const applyBtn = document.getElementById("labProfilesSeedApply");
      const sel = document.getElementById("labProfilesSeedSelect");
      if (applyBtn && sel) applyBtn.disabled = !sel.value;
    });
    document.getElementById("labProfilesSeedApply")?.addEventListener("click", () => {
      applySeedNorms().catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
    });
    document.getElementById("labProfilesGfeApplyUsp")?.addEventListener("click", () => applyGfeMin(["usp"]));
    document.getElementById("labProfilesGfeApplyNel")?.addEventListener("click", () => applyGfeMin(["nel"]));
    document.getElementById("labProfilesGfeApplyAll")?.addEventListener("click", () =>
      applyGfeMin(GFE_DYNAMIC_KEYS)
    );
  }

  document.addEventListener("DOMContentLoaded", () => {
    bind();
    init().catch(() => notify()?.error?.(null, { fallback: "Не удалось выполнить операцию" }));
  });
})(window);
