import { endpoints } from "./config.js";
import { trackEvent } from "./analytics.js";
import { requireFullAccess } from "./access.js";
import {
buildBillRequestQueueMessage,
buildWaiterCallQueueMessage,
cacheOpenBills,
ensureGuestActionAllowed,
guestActionBlockedMessage,
queueGuestAction,
refreshGuestPendingActions,
} from "./queue.js";
import { showToast } from "./toast.js";
import {
getBillState,
getHashParam,
getTableParam,
setBillState,
} from "./state.js";
function sendApiSimulated(actionName, details) {
console.log(`[SYMULACJA API] Akcja: ${actionName}`, details);
// Przykładowe wysłanie docelowo:
// if (window.socket && window.socket.readyState === WebSocket.OPEN) {
// window.socket.send(JSON.stringify({ action: "sendUpstream", payload: { type: actionName, table: tableParam, ...details } }));
// }
}
export async function callWaiter(type) {
if (type !== "order") return;
if (!(await ensureGuestActionAllowed("waiter_call"))) {
return;
}
const queued = await queueGuestAction("waiter_call", buildWaiterCallQueueMessage(), {
waiterType: "order",
});
if (!queued.ok) {
if (queued.reason === "pending") {
showToast(guestActionBlockedMessage("waiter_call"));
} else {
showToast("Nie udało się wysłać wezwania. Spróbuj ponownie za chwilę.");
}
return;
}
trackEvent("waiter_call_requested", { waiterType: "order" });
sendApiSimulated("CallWaiter_Order", { table: getTableParam() });
showToast("Kelner wkrótce do Ciebie podejdzie!");
}
export function openWaiterDialog() {
requireFullAccess("waiter", () => {
openWaiterDialogInternal();
});
}
export async function openWaiterDialogInternal() {
if (!(await ensureGuestActionAllowed("waiter_call"))) {
return;
}
document.getElementById("waiterModal").classList.add("active");
document.body.style.overflow = "hidden";
}
export function closeWaiterDialog() {
document.getElementById("waiterModal").classList.remove("active");
document.body.style.overflow = "";
}
export async function confirmCallWaiter() {
closeWaiterDialog();
await callWaiter("order");
}
export async function proceedToBillPayment() {
if (!(await ensureGuestActionAllowed("bill_request"))) {
return;
}
goToStep("stepPayment");
}
export function openBillDialog() {
requireFullAccess("bill", () => {
openBillDialogInternal();
});
}
export async function openBillDialogInternal() {
await refreshGuestPendingActions();
trackEvent("bill_dialog_opened");
setBillState({ payment: "", doc: "", nip: "", company: null, selectedBillId: null });
document.getElementById("billModal").classList.add("active");
document.body.style.overflow = "hidden"; // Zablokuj scroll tła
document.getElementById("billLoading").classList.remove("hidden");
document.getElementById("billListContainer").classList.add("hidden");
goToStep("stepBillList");
try {
const res = await fetch(`${endpoints.bills}?h=${encodeURIComponent(getHashParam())}`);
const result = await res.json();
if (result.status === "success" && result.data.length > 0) {
const bills = result.data;
cacheOpenBills(bills);
if (bills.length === 1) {
showBillReview(bills[0]);
document.getElementById("btnBackToBills").style.display = "none";
} else {
renderBillList(bills);
document.getElementById("btnBackToBills").style.display = "block";
}
} else {
document.getElementById("billLoading").innerHTML = "Brak otwartych rachunków do opłacenia.";
}
} catch (err) {
document.getElementById("billLoading").innerHTML = "Błąd pobierania rachunków.";
}
}
function renderBillList(bills) {
document.getElementById("billLoading").classList.add("hidden");
document.getElementById("billListContainer").classList.remove("hidden");
const container = document.getElementById("billListItems");
container.innerHTML = "";
bills.forEach((b) => {
const div = document.createElement("div");
div.className = "option-card";
div.style.flexDirection = "row";
div.style.justifyContent = "space-between";
div.style.padding = "15px";
div.onclick = () => showBillReview(b);
const numerFormat = b.numer ? `#${b.numer}` : "Rachunek";
div.innerHTML = `
${b.suma.toFixed(2)} PLN
`;
container.appendChild(div);
});
}
export function goBackToBillList() {
goToStep("stepBillList");
}
export function showBillReview(bill) {
const billState = getBillState();
billState.selectedBillId = bill.id;
const content = document.getElementById("billReviewContent");
content.innerHTML = "";
bill.pozycje.forEach((p) => {
const div = document.createElement("div");
div.style.display = "flex";
div.style.justifyContent = "space-between";
div.style.marginBottom = "8px";
div.style.borderBottom = "1px solid rgba(255,255,255,0.05)";
div.style.paddingBottom = "8px";
div.innerHTML = `
${p.nazwa}
${p.ilosc} x ${p.cena.toFixed(2)} PLN
${p.wartosc.toFixed(2)} PLN
`;
content.appendChild(div);
});
document.getElementById("billTotalAmount").textContent = bill.suma.toFixed(2) + " PLN";
goToStep("stepBillReview");
}
export function closeBillDialog() {
document.getElementById("billModal").classList.remove("active");
document.body.style.overflow = ""; // Odblokuj scroll tła
}
export function goToStep(stepId) {
document.querySelectorAll(".step").forEach((el) => el.classList.remove("active"));
document.getElementById(stepId).classList.add("active");
}
export function selectPayment(method) {
getBillState().payment = method;
goToStep("stepDocument");
}
export async function selectDocument(docType) {
const billState = getBillState();
billState.doc = docType;
if (docType === "paragon") {
if (!(await ensureGuestActionAllowed("bill_request"))) {
return;
}
const queued = await queueGuestAction("bill_request", buildBillRequestQueueMessage("paragon"), {
payment: billState.payment || null,
docType: "paragon",
});
if (!queued.ok) {
if (queued.reason === "pending") {
showToast(guestActionBlockedMessage("bill_request"));
} else {
showToast("Nie udało się wysłać prośby o rachunek. Spróbuj ponownie za chwilę.");
}
return;
}
trackEvent("bill_request_sent", { docType: "paragon" });
closeBillDialog();
sendApiSimulated("CallWaiter_Bill", {
table: getTableParam(),
billId: billState.selectedBillId,
payment: billState.payment,
doc: "paragon",
});
showToast("Kelner przyniesie paragon do opłacenia!");
} else {
goToStep("stepNIP");
document.getElementById("nipInput").value = "";
setTimeout(() => document.getElementById("nipInput").focus(), 100);
}
}
export async function fetchGUS() {
const nip = document.getElementById("nipInput").value.replace(/[\s-]/g, "");
if (nip.length < 10) {
alert("Wprowadź poprawny numer NIP.");
return;
}
const btn = document.getElementById("btnGUS");
btn.textContent = "Szukam...";
btn.disabled = true;
try {
const response = await fetch(`${endpoints.gusLookup}?nip=${encodeURIComponent(nip)}`);
const result = await response.json();
if (result.status && result.data) {
const data = result.data;
let fullStreet = data.street || "";
if (data.propertyNumber) fullStreet += " " + data.propertyNumber;
if (data.apartmentNumber) fullStreet += "/" + data.apartmentNumber;
const billState = getBillState();
billState.nip = nip;
billState.company = {
name: data.name,
street: fullStreet.trim(),
zip: data.zipCode,
city: data.city,
nip: data.nip,
};
document.getElementById("cmpName").value = billState.company.name;
document.getElementById("cmpStreet").value = billState.company.street;
document.getElementById("cmpZip").value = billState.company.zip;
document.getElementById("cmpCity").value = billState.company.city;
document.getElementById("cmpNip").value = "NIP: " + billState.company.nip;
// reset do readonly
document.getElementById("cmpName").readOnly = true;
document.getElementById("cmpStreet").readOnly = true;
document.getElementById("cmpZip").readOnly = true;
document.getElementById("cmpCity").readOnly = true;
document.getElementById("btnEditCompany").textContent = "Popraw ręcznie";
goToStep("stepVerify");
} else {
alert("Nie udało się pobrać danych z GUS dla podanego NIP-u.");
}
} catch (error) {
console.error("Błąd pobierania danych z GUS:", error);
alert("Błąd połączenia z API GUS.");
} finally {
btn.textContent = "Pobierz z GUS";
btn.disabled = false;
}
}
export function editCompanyData() {
const n = document.getElementById("cmpName");
const s = document.getElementById("cmpStreet");
const z = document.getElementById("cmpZip");
const c = document.getElementById("cmpCity");
const btn = document.getElementById("btnEditCompany");
if (n.readOnly) {
n.readOnly = false;
s.readOnly = false;
z.readOnly = false;
c.readOnly = false;
n.focus();
btn.textContent = "Zakończ edycję";
} else {
n.readOnly = true;
s.readOnly = true;
z.readOnly = true;
c.readOnly = true;
btn.textContent = "Popraw ręcznie";
}
}
export async function confirmInvoice() {
const billState = getBillState();
billState.company.name = document.getElementById("cmpName").value;
billState.company.street = document.getElementById("cmpStreet").value;
billState.company.zip = document.getElementById("cmpZip").value;
billState.company.city = document.getElementById("cmpCity").value;
if (!(await ensureGuestActionAllowed("bill_request"))) {
return;
}
const queued = await queueGuestAction("bill_request", buildBillRequestQueueMessage("faktura"), {
payment: billState.payment || null,
docType: "faktura",
nip: billState.nip || null,
company: billState.company || null,
});
if (!queued.ok) {
if (queued.reason === "pending") {
showToast(guestActionBlockedMessage("bill_request"));
} else {
showToast("Nie udało się wysłać prośby o rachunek. Spróbuj ponownie za chwilę.");
}
return;
}
closeBillDialog();
trackEvent("bill_request_sent", { docType: "faktura" });
sendApiSimulated("CallWaiter_Bill", {
table: getTableParam(),
billId: billState.selectedBillId,
payment: billState.payment,
doc: "faktura",
nip: billState.nip,
company: billState.company,
});
showToast("Dziękujemy! Prośba o fakturę została wysłana.");
}