/**
 * Модалка «Учётные документы» на /feed_consumption
 * Сценарий: Реквизиты → Подписи → Экспорт
 */
(function () {
  const ORG_FIELDS = [
    { id: "faOrgName", key: "organization_name", label: "Организация" },
    { id: "faOkpo", key: "okpo", label: "ОКПО" },
    { id: "faDepartment", key: "department", label: "Отделение (участок)" },
    { id: "faFarm", key: "farm_name", label: "Ферма" },
    { id: "faBrigade", key: "brigade", label: "Бригада" },
    { id: "faAnimalType", key: "animal_type", label: "Вид / группа скота" },
    { id: "faResponsible", key: "responsible_person", label: "Ответственный" },
    { id: "faZootech", key: "zootechnician", label: "Зоотехник (ФИО)" },
    { id: "faWarehouse", key: "warehouse_keeper", label: "Кладовщик (ФИО)" },
    { id: "faDocPrefix", key: "document_number_prefix", label: "Префикс номера документа" },
  ];

  const SIGNATURES = [
    { role: "zootechnician", label: "Зоотехник", canvasId: "faSigZootech" },
    { role: "warehouse_keeper", label: "Кладовщик", canvasId: "faSigWarehouse" },
    { role: "recipient", label: "Получатель", canvasId: "faSigRecipient" },
  ];

  const canvases = {};
  let lastSignatureStatus = {};

  function getExportMonth() {
    const monthEl = document.getElementById("faExportMonth");
    if (monthEl && monthEl.value) {
      return monthEl.value;
    }
    const fromEl = document.getElementById("consumptionDateFrom");
    if (fromEl && fromEl.value) {
      return fromEl.value.slice(0, 7);
    }
    const now = new Date();
    return now.getFullYear() + "-" + String(now.getMonth() + 1).padStart(2, "0");
  }

  function getDateRange() {
    const fromEl = document.getElementById("consumptionDateFrom");
    const toEl = document.getElementById("consumptionDateTo");
    let from = fromEl && fromEl.value;
    let to = toEl && toEl.value;
    if (!from || !to) {
      const now = new Date();
      from = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().slice(0, 10);
      to = new Date(now.getFullYear(), now.getMonth() + 1, 0).toISOString().slice(0, 10);
    }
    return { from, to, month: getExportMonth() };
  }

  function syncExportMonthField() {
    const monthEl = document.getElementById("faExportMonth");
    if (!monthEl || monthEl.value) return;
    monthEl.value = getExportMonth();
  }

  async function refreshSp20Status() {
    const el = document.getElementById("faSp20Status");
    if (!el) return;
    const month = getExportMonth();
    el.textContent = "Проверка данных за " + month + "…";
    try {
      const r = await fetch("/api/feed-accounting/sp20-preview?month=" + encodeURIComponent(month), {
        credentials: "same-origin",
      });
      if (!r.ok) {
        el.textContent = "Не удалось загрузить сводку по СП-20.";
        return;
      }
      const data = await r.json();
      if (!data.lines_count) {
        el.textContent = "За " + month + " нет строк расхода в отчётах загрузки. Проверьте месяц или наличие отчётов.";
        el.className = "text-warning small mb-3";
        return;
      }
      let msg = "СП-20 за " + month + ": " + data.lines_count + " строк, " + data.total_kg + " кг";
      if (!data.has_requisites) {
        msg += ". Заполните реквизиты на вкладке «Реквизиты СП-20».";
        el.className = "text-warning small mb-3";
      } else {
        el.className = "text-success small mb-3";
      }
      el.textContent = msg;
    } catch (err) {
      el.textContent = "Не удалось загрузить сводку по СП-20.";
      el.className = "text-danger small mb-3";
    }
  }

  function userError(message, fallback) {
    const notifyApi = window.WespZootechNotify;
    if (notifyApi && typeof notifyApi.userFacingMessage === "function") {
      return notifyApi.userFacingMessage(message, fallback);
    }
    return fallback || "Не удалось выполнить операцию. Попробуйте ещё раз.";
  }

  function notify(msg, type) {
    if (typeof notyf !== "undefined") {
      if (type === "error") notyf.error(msg);
      else notyf.success(msg);
    }
  }

  async function downloadUrl(url, label) {
    const fallback = "Не удалось скачать документ. Попробуйте ещё раз.";
    try {
      const r = await fetch(url, { credentials: "same-origin" });
      if (!r.ok) {
        let body = null;
        try {
          body = await r.json();
        } catch (e) { /* ignore */ }
        const notifyApi = window.WespZootechNotify;
        const msg = notifyApi && typeof notifyApi.messageFromResponseBody === "function"
          ? notifyApi.messageFromResponseBody(body, fallback)
          : userError(null, fallback);
        notify(msg, "error");
        return;
      }
      const blob = await r.blob();
      const cd = r.headers.get("Content-Disposition") || "";
      const m = cd.match(/filename="([^"]+)"/);
      const filename = m ? m[1] : "download";
      const a = document.createElement("a");
      a.href = URL.createObjectURL(blob);
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
      setTimeout(function () { URL.revokeObjectURL(a.href); }, 5000);
    } catch (err) {
      notify(userError(null, fallback), "error");
    }
  }

  function showTab(name) {
    document.querySelectorAll(".fa-tab-panel").forEach(function (el) {
      el.hidden = el.dataset.tab !== name;
    });
    document.querySelectorAll(".fa-tab-btn").forEach(function (btn) {
      btn.classList.toggle("active", btn.dataset.tab === name);
    });
    if (name === "export") {
      syncExportMonthField();
      refreshSp20Status();
    }
  }

  function setupCanvas(canvas) {
    if (!canvas || canvases[canvas.id]) return;
    const ctx = canvas.getContext("2d");
    ctx.strokeStyle = "#1a1a1a";
    ctx.lineWidth = 2;
    ctx.lineCap = "round";
    let drawing = false;
    function pos(e) {
      const rect = canvas.getBoundingClientRect();
      const scaleX = canvas.width / rect.width;
      const scaleY = canvas.height / rect.height;
      const ev = e.touches ? e.touches[0] : e;
      return {
        x: (ev.clientX - rect.left) * scaleX,
        y: (ev.clientY - rect.top) * scaleY,
      };
    }
    function start(e) {
      drawing = true;
      const p = pos(e);
      ctx.beginPath();
      ctx.moveTo(p.x, p.y);
      e.preventDefault();
    }
    function move(e) {
      if (!drawing) return;
      const p = pos(e);
      ctx.lineTo(p.x, p.y);
      ctx.stroke();
      e.preventDefault();
    }
    function end() { drawing = false; }
    canvas.addEventListener("mousedown", start);
    canvas.addEventListener("mousemove", move);
    canvas.addEventListener("mouseup", end);
    canvas.addEventListener("mouseleave", end);
    canvas.addEventListener("touchstart", start, { passive: false });
    canvas.addEventListener("touchmove", move, { passive: false });
    canvas.addEventListener("touchend", end);
    canvases[canvas.id] = { canvas: canvas, ctx: ctx };
  }

  function clearCanvas(canvasId) {
    const item = canvases[canvasId];
    if (!item) return;
    item.ctx.clearRect(0, 0, item.canvas.width, item.canvas.height);
  }

  function canvasHasInk(canvasId) {
    const item = canvases[canvasId];
    if (!item) return false;
    const data = item.ctx.getImageData(0, 0, item.canvas.width, item.canvas.height).data;
    for (let i = 3; i < data.length; i += 4) {
      if (data[i] > 0) return true;
    }
    return false;
  }

  function fillFarmDatalist(farms) {
    const list = document.getElementById("faFarmList");
    if (!list) return;
    list.innerHTML = "";
    (farms || []).forEach(function (farm) {
      const opt = document.createElement("option");
      opt.value = farm;
      list.appendChild(opt);
    });
  }

  function isSetupComplete(settings, sigStatus) {
    const hasRequisites = Boolean(
      (settings.organization_name || "").trim() &&
      (settings.zootechnician || "").trim() &&
      (settings.warehouse_keeper || "").trim()
    );
    const hasSignatures = Boolean(sigStatus.zootechnician && sigStatus.warehouse_keeper);
    return hasRequisites && hasSignatures;
  }

  async function loadOrgSettings() {
    const r = await fetch("/api/feed-accounting/org-settings", { credentials: "same-origin" });
    if (!r.ok) return null;
    const data = await r.json();
    ORG_FIELDS.forEach(function (f) {
      const el = document.getElementById(f.id);
      if (el) el.value = data[f.key] || "";
    });
    fillFarmDatalist(data.available_farms || []);
    if (data.signatures) {
      lastSignatureStatus = data.signatures;
    }
    return data;
  }

  async function loadSignaturesOntoCanvases() {
    const roles = lastSignatureStatus;
    await Promise.all(
      SIGNATURES.map(function (s) {
        if (!roles[s.role]) return Promise.resolve();
        return new Promise(function (resolve) {
          const img = new Image();
          img.onload = function () {
            const item = canvases[s.canvasId];
            if (item) {
              item.ctx.clearRect(0, 0, item.canvas.width, item.canvas.height);
              item.ctx.drawImage(img, 0, 0, item.canvas.width, item.canvas.height);
            }
            resolve();
          };
          img.onerror = function () { resolve(); };
          img.src = "/api/feed-accounting/signatures/" + s.role + ".png?t=" + Date.now();
        });
      })
    );
  }

  async function saveOrgSettings(silent) {
    const payload = {};
    ORG_FIELDS.forEach(function (f) {
      const el = document.getElementById(f.id);
      if (el) payload[f.key] = el.value.trim();
    });
    const r = await fetch("/api/feed-accounting/org-settings", {
      method: "PUT",
      credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    const data = await r.json();
    if (!r.ok) {
      notify(userError(data.message, "Не удалось сохранить реквизиты"), "error");
      return false;
    }
    if (!silent) notify("Реквизиты сохранены");
    return true;
  }

  async function saveSignature(role, canvasId, silent) {
    const item = canvases[canvasId];
    if (!item || !canvasHasInk(canvasId)) return true;
    const dataUrl = item.canvas.toDataURL("image/png");
    const r = await fetch("/api/feed-accounting/signatures/" + role, {
      method: "POST",
      credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ png_base64: dataUrl }),
    });
    const data = await r.json();
    if (!r.ok) {
      notify(userError(data.message, "Не удалось сохранить подпись"), "error");
      return false;
    }
    if (data.roles) lastSignatureStatus = data.roles;
    if (!silent) notify("Подпись сохранена");
    return true;
  }

  async function saveAll() {
    const btn = document.getElementById("faSaveAllBtn");
    if (btn) btn.disabled = true;
    try {
      const orgOk = await saveOrgSettings(true);
      if (!orgOk) return;
      for (const s of SIGNATURES) {
        const ok = await saveSignature(s.role, s.canvasId, true);
        if (!ok) return;
      }
      notify("Реквизиты и подписи сохранены");
      const settings = await loadOrgSettings();
      if (settings && isSetupComplete(settings, lastSignatureStatus)) {
        showTab("export");
      }
    } finally {
      if (btn) btn.disabled = false;
    }
  }

  window.openFeedAccountingModal = async function () {
    const modal = document.getElementById("feedAccountingModal");
    if (!modal) return;
    modal.style.display = "flex";
    document.body.style.overflow = "hidden";
    SIGNATURES.forEach(function (s) {
      setupCanvas(document.getElementById(s.canvasId));
    });
    const settings = await loadOrgSettings();
    await loadSignaturesOntoCanvases();
    syncExportMonthField();
    const complete = settings && isSetupComplete(settings, lastSignatureStatus);
    showTab(complete ? "export" : "requisites");
  };

  window.closeFeedAccountingModal = function () {
    const modal = document.getElementById("feedAccountingModal");
    if (!modal) return;
    modal.style.display = "none";
    document.body.style.overflow = "";
  };

  document.addEventListener("DOMContentLoaded", function () {
    const openBtn = document.getElementById("openFeedAccountingBtn");
    if (openBtn) openBtn.addEventListener("click", function () { openFeedAccountingModal(); });

    document.querySelectorAll(".fa-tab-btn").forEach(function (btn) {
      btn.addEventListener("click", function () {
        showTab(btn.dataset.tab);
      });
    });

    const exportMonthEl = document.getElementById("faExportMonth");
    if (exportMonthEl) {
      exportMonthEl.addEventListener("change", refreshSp20Status);
    }

    const saveAllBtn = document.getElementById("faSaveAllBtn");
    if (saveAllBtn) saveAllBtn.addEventListener("click", saveAll);

    SIGNATURES.forEach(function (s) {
      const clearBtn = document.getElementById("clear_" + s.canvasId);
      if (clearBtn) clearBtn.addEventListener("click", function () { clearCanvas(s.canvasId); });
    });

    const exports = [
      { id: "faExportConsumptionXlsx", path: function (d) { return "/api/feed-accounting/consumption.xlsx?date_from=" + encodeURIComponent(d.from) + "&date_to=" + encodeURIComponent(d.to); }, label: "Потребление Excel" },
      { id: "faExportConsumptionPdf", path: function (d) { return "/api/feed-accounting/consumption.pdf?date_from=" + encodeURIComponent(d.from) + "&date_to=" + encodeURIComponent(d.to); }, label: "Потребление PDF" },
      { id: "faExportStock", path: function (d) { return "/api/feed-accounting/stock-balances.xlsx?date_from=" + encodeURIComponent(d.from) + "&date_to=" + encodeURIComponent(d.to); }, label: "Остатки" },
      { id: "faExportSp20Xlsx", path: function (d) { return "/api/feed-accounting/sp20.xlsx?month=" + encodeURIComponent(d.month); }, label: "СП-20 Excel" },
      { id: "faExportSp20Pdf", path: function (d) { return "/api/feed-accounting/sp20.pdf?month=" + encodeURIComponent(d.month); }, label: "СП-20 PDF" },
      { id: "faExportJournalXlsx", path: function (d) { return "/api/feed-accounting/journal.xlsx?month=" + encodeURIComponent(d.month); }, label: "Журнал Excel" },
      { id: "faExportJournalPdf", path: function (d) { return "/api/feed-accounting/journal.pdf?month=" + encodeURIComponent(d.month); }, label: "Журнал PDF" },
      { id: "faExportZip", path: function (d) { return "/api/feed-accounting/documents.zip?date_from=" + encodeURIComponent(d.from) + "&date_to=" + encodeURIComponent(d.to) + "&month=" + encodeURIComponent(d.month); }, label: "ZIP" },
    ];
    exports.forEach(function (ex) {
      const btn = document.getElementById(ex.id);
      if (!btn) return;
      btn.addEventListener("click", function () {
        const d = getDateRange();
        downloadUrl(ex.path(d), ex.label);
      });
    });

    const modal = document.getElementById("feedAccountingModal");
    if (modal) {
      modal.addEventListener("click", function (e) {
        if (e.target === modal) closeFeedAccountingModal();
      });
    }
  });
})();
