<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8" />
    <title>Kalkulator usług sprzątania - Pełny kod</title>

    <!-- Стили (CSS) встроенные в HTML -->
    <style>
        /* ---------------------------
           Podstawowe style kalkulatora
           --------------------------- */

        /* Kontener główny kalkulatora */
        #cleaning-calculator {
            max-width: 500px;
            margin: 40px auto;
            padding: 20px;
            border: 1px solid #eee;
            border-radius: 5px;
            background-color: #fafafa;
            font-family: Arial, sans-serif;
        }

        /* Nagłówki w kalkulatorze */
        #cleaning-calculator h2, 
        #cleaning-calculator h3 {
            margin-top: 0;
            text-align: center;
        }

        /* Podstawowy styl tekstu */
        #cleaning-calculator p {
            line-height: 1.4em;
        }

        /* Etykiety formularza */
        .calc-label {
            display: inline-block;
            margin-bottom: 5px;
            font-weight: bold;
        }

        /* Selektory / inputy / przyciski w kalkulatorze */
        .calc-select,
        .calc-range,
        .calc-button,
        .calc-button-cta {
            width: 100%;
            box-sizing: border-box;
            margin-bottom: 15px;
        }

        .calc-select, 
        .calc-range {
            padding: 5px;
            font-size: 1rem;
        }

        .calc-button {
            background-color: #007bff;
            color: #fff;
            border: none;
            padding: 12px 16px;
            font-size: 1rem;
            cursor: pointer;
            border-radius: 4px;
        }

        .calc-button:hover {
            background-color: #0056b3;
        }

        /* Przyciski CTA (Call To Action) */
        .calc-button-cta {
            background-color: #28a745;
            margin-top: 10px;
        }

        .calc-button-cta:hover {
            background-color: #218838;
        }

        /* Kontener podkategorii */
        .calc-subcategory-container {
            margin-top: 15px;
        }

        /* Wiersz kalkulatora do grupowania pól */
        .calc-row {
            margin-bottom: 15px;
        }

        /* Wartość suwaka */
        .calc-range-value {
            display: inline-block;
            margin-left: 10px;
            font-weight: bold;
        }

        /* Uwaga, notatki itp. */
        .calc-note {
            font-size: 0.9em;
            color: #666;
            margin-top: 10px;
        }
    </style>
</head>
<body>

<div id="cleaning-calculator">
    <h2>Kalkulator usług sprzątania</h2>
    <p>Oblicz orientacyjną cenę usługi. Pamiętaj, że jest to wstępny szacunek – ostateczną ofertę otrzymasz po kontakcie z naszym przedstawicielem.</p>

    <!-- Wybór kategorii głównej usługi sprzątania -->
    <label for="mainCategory" class="calc-label">Wybierz usługę:</label>
    <select id="mainCategory" class="calc-select">
        <option value="" selected disabled>-- Wybierz --</option>
        <option value="parkingi">Czyszczenie parkingów, hal garażowych i magazynowych</option>
        <option value="cisnieniowe">Czyszczenie ciśnieniowe</option>
        <option value="pranie">Pranie wykładzin i tapicerki</option>
        <option value="poremontowe">Sprzątanie mieszkań, domów i biur (poremontowe)</option>
        <option value="biezace">Sprzątanie mieszkań, domów i biur (bieżące)</option>
        <option value="okna">Mycie okien (z ramami i parapetami)</option>
        <option value="zaluzjeRoletki">Mycie żaluzji i rolet</option>
        <option value="ogrod">Pielęgnacja terenów zewnętrznych</option>
        <option value="doczyszczaniePosadzek">Doczyszczanie posadzek</option>
        <option value="pobudowlane">Sprzątanie pobudowlane</option>
        <option value="biura">Sprzątanie biur</option>
        <option value="wspolnoty">Sprzątanie wspólnot mieszkaniowych</option>
    </select>

    <!-- Pole wyboru podkategorii (np. zamiatanie, mycie itd.) - dynamicznie zmieniane w JS -->
    <div id="subCategoryContainer" class="calc-subcategory-container" style="display:none;">
        <label for="subCategory" class="calc-label">Wybierz podkategorię:</label>
        <select id="subCategory" class="calc-select">
            <!-- Podkategorie zostaną załadowane dynamicznie w zależności od wybranej głównej kategorii -->
        </select>
    </div>

    <!-- Kontener do wprowadzenia dodatkowych parametrów, np. metraż, ilość okien, wybór VAT itp. -->
    <div id="parametersContainer" style="display:none;">
        <!-- Wybór stawki VAT -->
        <div class="calc-row">
            <label for="vatRate" class="calc-label">Wybierz stawkę VAT:</label>
            <select id="vatRate" class="calc-select">
                <option value="23" selected>23%</option>
                <option value="8">8%</option>
            </select>
        </div>

        <!-- Pole / suwak do wprowadzania metrażu lub liczby sztuk -->
        <div class="calc-row" id="areaRow">
            <label for="areaRange" class="calc-label">Powierzchnia / ilość [m² / szt.]:</label>
            <input type="range" id="areaRange" min="0" max="1000" value="50" step="1" class="calc-range" />
            <span id="areaValue" class="calc-range-value">50</span>
        </div>

        <!-- Dla usług biurowych (1x w tygodniu lub 2x w tygodniu) -->
        <div class="calc-row" id="biuroFreqRow" style="display:none;">
            <label for="biuroFrequency" class="calc-label">Częstotliwość sprzątania biura:</label>
            <select id="biuroFrequency" class="calc-select">
                <option value="1x">1x w tygodniu</option>
                <option value="2x">2x w tygodniu</option>
            </select>
        </div>

        <!-- Przycisk obliczający koszty -->
        <button id="calculateBtn" class="calc-button">Oblicz koszty</button>
    </div>

    <!-- Sekcja wyświetlająca wynik -->
    <div id="resultContainer" style="display:none;">
        <h3>Wynik kalkulacji</h3>
        <p id="resultText"></p>
        <p class="calc-note">
            Jest to wstępny, orientacyjny koszt usługi. Aby uzyskać dokładną ofertę, skontaktuj się z naszym przedstawicielem.
        </p>

        <!-- Przycisk CTA pojawia się po wyliczeniu kosztu -->
        <button id="contactBtn" class="calc-button-cta">
            Skontaktuj się z nami i poznaj dokładną ofertę
        </button>
    </div>
</div>

<!-- Скрипт (JS) встроенный в HTML -->
<script>
/**************************************************
 * Kalkulator usług sprzątania
 * Komentarze w języku polskim
 **************************************************/

// Struktura danych do obsługi podkategorii i stawek
// "price" => stawka za m² (lub za sztukę). "type" => typ usługi (obsługuje np. "individual" gdy wycena indywidualna)
const servicesData = {
    parkingi: [
        { name: "Zamiatanie / odkurzanie", price: 0.40, type: "area" },
        { name: "Mycie bieżące", price: 0.80, type: "area" },
        { name: "Doczyszczanie", price: 4.00, type: "area" },
        { name: "Prace na wysokości (wycena indywidualna)", price: 0, type: "individual" }
    ],
    cisnieniowe: [
        { name: "Kostka brukowa", price: 8.00, type: "area" },
        { name: "Elewacje", price: 8.00, type: "area" }
    ],
    pranie: [
        { name: "Wykładziny", price: 8.00, type: "area" },
        { name: "Tapicerka (wycena indywidualna)", price: 0, type: "individual" }
    ],
    poremontowe: [
        { name: "Sprzątanie poremontowe (od 15,00 zł/m²)", price: 15.00, type: "areaOrHour", hourRate: 90.00 }
    ],
    biezace: [
        { name: "Mieszkania: od 8,00 zł/m² lub 85,00 zł/h", price: 8.00, type: "areaOrHour", hourRate: 85.00 },
        { name: "Domy: od 8,00 zł/m² lub 85,00 zł/h", price: 8.00, type: "areaOrHour", hourRate: 85.00 }
    ],
    okna: [
        { name: "Mycie okien w domach prywatnych (od 20,00 zł/skrzydło dwustronnie)", price: 20.00, type: "piece" },
        { name: "Mycie okien w firmach (od 6,00 zł/m² jednostronnie)", price: 6.00, type: "area" },
        { name: "Mycie fasad metodą WFP (od 4,50 zł/m²)", price: 4.50, type: "area" },
        { name: "Mycie poremontowe (od 10,00 zł/m² jednostronnie)", price: 10.00, type: "area" }
    ],
    zaluzjeRoletki: [
        { name: "Rolety zewnętrzne (od 8,00 zł/m²)", price: 8.00, type: "area" },
        { name: "Żaluzje fasadowe (od 20,00 zł/m²)", price: 20.00, type: "area" }
    ],
    ogrod: [
        { name: "Koszenie trawy (od 0,50 zł/m²)", price: 0.50, type: "area" },
        { name: "Wertykulacja i nawożenie (od 1,40 zł/m²)", price: 1.40, type: "area" },
        { name: "Nasadzenia i formowanie zieleni (wycena indywidualna)", price: 0, type: "individual" },
        { name: "Pielenie ręczne (od 70,00 zł/h)", price: 70.00, type: "hour" },
        { name: "Opryski na chwasty (od 0,50 zł/m²)", price: 0.50, type: "area" }
    ],
    doczyszczaniePosadzek: [
        { name: "Doczyszczanie posadzek (od 8,00 zł/m²)", price: 8.00, type: "area" }
    ],
    pobudowlane: [
        { name: "Sprzątanie pobudowlane (od 15,00 zł/m²)", price: 15.00, type: "area" }
    ],
    biura: [
        // Uproszczone podejście: ustalimy widełki w zależności od metrażu i częstotliwości
        { name: "Sprzątanie biur (zależne od m² i częstotliwości)", price: 0, type: "office" }
    ],
    wspolnoty: [
        { name: "Sprzątanie wspólnot mieszkaniowych (od 0,60 zł/m²)", price: 0.60, type: "area" }
    ]
};

// Referencje do elementów w kalkulatorze
let mainCategorySelect, subCategorySelect;
let subCategoryContainer, parametersContainer;
let areaRange, areaValue;
let calculateBtn, resultContainer, resultText, contactBtn;
let vatRateSelect;
let biuroFreqRow, biuroFrequency;

/**
 * Funkcja inicjalizuje kalkulator po załadowaniu strony
 */
document.addEventListener("DOMContentLoaded", function() {
    // Pobieramy elementy z DOM
    mainCategorySelect = document.getElementById("mainCategory");
    subCategorySelect = document.getElementById("subCategory");
    subCategoryContainer = document.getElementById("subCategoryContainer");
    parametersContainer = document.getElementById("parametersContainer");
    areaRange = document.getElementById("areaRange");
    areaValue = document.getElementById("areaValue");
    calculateBtn = document.getElementById("calculateBtn");
    resultContainer = document.getElementById("resultContainer");
    resultText = document.getElementById("resultText");
    contactBtn = document.getElementById("contactBtn");
    vatRateSelect = document.getElementById("vatRate");
    biuroFreqRow = document.getElementById("biuroFreqRow");
    biuroFrequency = document.getElementById("biuroFrequency");

    // Obsługa wyboru głównej kategorii usługi
    mainCategorySelect.addEventListener("change", onMainCategoryChange);

    // Obsługa wyboru podkategorii
    subCategorySelect.addEventListener("change", onSubCategoryChange);

    // Obsługa suwaka do zmiany metrażu / ilości
    areaRange.addEventListener("input", function() {
        areaValue.textContent = this.value;
    });

    // Obsługa przycisku "Oblicz koszty"
    calculateBtn.addEventListener("click", calculateCost);

    // Początkowo ukrywamy sekcje, zanim użytkownik wybierze kategorię
    hideElements();
});

/**
 * Ukrywa zbędne sekcje na początku
 */
function hideElements() {
    subCategoryContainer.style.display = "none";
    parametersContainer.style.display = "none";
    resultContainer.style.display = "none";
    biuroFreqRow.style.display = "none";
}

/**
 * Wywoływane, gdy użytkownik wybierze główną kategorię usługi
 */
function onMainCategoryChange() {
    // Czyścimy wynik z poprzednich obliczeń
    resultContainer.style.display = "none";

    const selectedCategory = mainCategorySelect.value;

    // Jeżeli nic nie wybrano, wyjdź
    if (!selectedCategory) {
        subCategoryContainer.style.display = "none";
        parametersContainer.style.display = "none";
        return;
    }

    // Ładujemy podkategorie z obiektu servicesData
    const subCats = servicesData[selectedCategory];
    if (!subCats) return;

    // Czyścimy istniejące opcje w subCategorySelect
    subCategorySelect.innerHTML = "";
    // Dodajemy placeholder
    const placeholderOption = document.createElement("option");
    placeholderOption.value = "";
    placeholderOption.disabled = true;
    placeholderOption.selected = true;
    placeholderOption.textContent = "-- Wybierz podkategorię --";
    subCategorySelect.appendChild(placeholderOption);

    // Tworzymy opcje na podstawie subCats
    subCats.forEach(sub => {
        const opt = document.createElement("option");
        opt.value = sub.name; // nazwa jako value
        opt.textContent = sub.name;
        subCategorySelect.appendChild(opt);
    });

    // Pokazujemy kontener z podkategoriami
    subCategoryContainer.style.display = "block";
    // Ukrywamy parametry, dopóki user nie wybierze podkategorii
    parametersContainer.style.display = "none";
    biuroFreqRow.style.display = "none";
}

/**
 * Wywoływane, gdy użytkownik wybierze podkategorię
 */
function onSubCategoryChange() {
    // Czyścimy wynik
    resultContainer.style.display = "none";

    // Pokazujemy parametry (suwak, vat, przycisk obliczenia),
    // chyba że jest to wycena indywidualna
    const selectedCategory = mainCategorySelect.value;
    const selectedSubName = subCategorySelect.value;

    const subCats = servicesData[selectedCategory];
    if (!subCats) return;

    // Znajdujemy wybraną podkategorię
    let chosenSub = subCats.find(sub => sub.name === selectedSubName);
    if (!chosenSub) return;

    // Jeśli "wycena indywidualna", nie potrzebujemy parametrów
    if (chosenSub.type === "individual") {
        parametersContainer.style.display = "none";
        // Pokaż wynik od razu z komunikatem
        showIndividualResult();
    } else {
        parametersContainer.style.display = "block";

        // Dodatkowo, jeśli to "office", pokażemy częstotliwość
        if (chosenSub.type === "office") {
            biuroFreqRow.style.display = "block";
        } else {
            biuroFreqRow.style.display = "none";
        }
    }
}

/**
 * Funkcja wyświetla komunikat o indywidualnej wycenie
 */
function showIndividualResult() {
    resultContainer.style.display = "block";
    resultText.textContent = "Usługa wymaga indywidualnej wyceny. Prosimy o kontakt w celu ustalenia kosztów.";
}

/**
 * Funkcja oblicza koszty na podstawie wprowadzonych danych
 */
function calculateCost() {
    const selectedCategory = mainCategorySelect.value;
    const selectedSubName = subCategorySelect.value;
    const chosenVat = parseFloat(vatRateSelect.value);

    // Pobieramy dane podkategorii
    const subCats = servicesData[selectedCategory];
    if (!subCats) return;
    const chosenSub = subCats.find(sub => sub.name === selectedSubName);
    if (!chosenSub) return;

    // Pobieramy liczbę z suwaka (metry / sztuki)
    const area = parseFloat(areaRange.value);

    // Sprawdzamy typ usługi
    let netCost = 0;

    // Zakładamy domyślnie koszt wg m²
    if (chosenSub.type === "area") {
        netCost = chosenSub.price * area;
    } 
    else if (chosenSub.type === "piece") {
        // np. mycie okien za skrzydło dwustronnie
        netCost = chosenSub.price * area;
    }
    else if (chosenSub.type === "hour") {
        // np. Pielenie ręczne: stawka od 70,00 zł/h
        // Zakładamy, że areaRange to liczba godzin
        netCost = chosenSub.price * area;
    }
    else if (chosenSub.type === "areaOrHour") {
        // Użytkownik może chcieć policzyć stawkę za m² lub za godzinę;
        // W tym przykładowym rozwiązaniu przyjmujemy, że "areaRange" to m²
        // (choć można to rozbudować o dodatkowy wybór).
        const pricePerArea = chosenSub.price * area;
        const pricePerHour = chosenSub.hourRate * area;
        // Tu – dla uproszczenia – przyjmijmy, że liczona jest stawka za m²
        netCost = pricePerArea;
    }
    else if (chosenSub.type === "office") {
        // Logika dla biur
        // Sprzątanie biur w zależności od m² i częstotliwości
        // do 100 m²: 800 zł (1x tyg.), 1350 zł (2x tyg.)
        // do 200 m²: 990 zł (1x tyg.), 1560 zł (2x tyg.)
        // każde kolejne 100 m²: +200 zł (1x tyg.), +450 zł (2x tyg.)

        const freq = biuroFrequency.value; // "1x" albo "2x"

        let baseCost = 0;
        let extra = 0;

        if (area <= 100) {
            baseCost = (freq === "1x") ? 800 : 1350;
        } else if (area <= 200) {
            baseCost = (freq === "1x") ? 990 : 1560;
        } else {
            // powyżej 200
            baseCost = (freq === "1x") ? 990 : 1560;
            const over200 = area - 200;
            // każde kolejne 100 m²
            const extraBlocks = Math.ceil(over200 / 100);
            extra = extraBlocks * ((freq === "1x") ? 200 : 450);
        }

        netCost = baseCost + extra;
    }

    // Minimalna cena usługi = 300 zł netto (jeśli netCost < 300, to i tak 300)
    // (z wyjątkiem biur "office" i "individual")
    if (netCost < 300 && chosenSub.type !== "office" && chosenSub.type !== "individual") {
        netCost = 300;
    }

    // Naliczamy VAT
    const vatAmount = netCost * (chosenVat / 100);
    const grossCost = netCost + vatAmount;

    // Wyświetlamy wynik
    resultContainer.style.display = "block";

    // Jeżeli "wycena indywidualna", wcześniej obsłużyliśmy, ale na wszelki wypadek:
    if (chosenSub.type === "individual") {
        resultText.textContent = "Usługa wymaga indywidualnej wyceny. Prosimy o kontakt w celu ustalenia kosztów.";
        return;
    }

    // Komunikat dla areaOrHour w wersji prostej
    let additionalInfo = "";
    if (chosenSub.type === "areaOrHour") {
        additionalInfo = " (dla uproszczenia liczone wg stawki za m²).";
    }

    // Sklejamy komunikat
    const msg = 
        "Szacunkowy koszt netto: " + netCost.toFixed(2) + " zł" + 
        " + VAT " + chosenVat + "% = " + grossCost.toFixed(2) + " zł brutto" + additionalInfo;

    resultText.textContent = msg;
}

/**
 * Po kliknięciu w przycisk "Skontaktuj się z nami" można np. przekierować do formularza kontaktowego
 */
contactBtn.addEventListener("click", function() {
    // W tym przykładzie przekierowujemy do mailto
    window.open("mailto:hello@qithub.click?subject=Zapytanie%20o%20us%C5%82ugi","_blank");
});
</script>

</body>
</html>
